02/2/13

من مشروعي التخرج – 2 – إدارة تزامن المعطيات في مشاريع الويب

سأقوم في هذه السلسلة من المقالات بوضع بعض الفقرات العامة التي وردت في أطروحة مشروع التخرج الذي تقدمنا به في كلية الهندسة المعلوماتية، وقد حاز هذا المشروع على العلامة الاعلى على مستوى الكلية في تلك السنة، قدم هذا المشروع كل من:

م.محمود البيك
م.طلال عبد الواحد
م. غيث عقاد
م. محمد صخر صوان

أشرف على المشروع:

الدكتور      : أحمد بدرالدين خضر

الدكتور      : حيــــــان حــــــصرم (رحمه الله و اسكنه جنانه)

المهندس   : بشــــر مسلاتـــــي

موجز عن المشروع

إدارة تزامن المعطيات Concurrency:

إن التطبيقات الموزعة تحتاج لإدارة عمليات التعديل المتزامنة. حيث يمكن أن يحدث السيناريو التالي:

- قام المستخدم A بفتح صفحة التعديل لأحد عناصر النظام وليكن منتج ما وفي هذه الأثناء قام المستخدم B بفتح صفحة التعديل وقام بتعديل بعض البيانات وحفظ هذه التعديلات (خلال هذه الفترة يقوم المستخدم A ببعض التعديلات ولكن لم يحفظها) وبعد أن أجرى المستخدم A تعديلاته ضغط على زر الحفظ. في هذه الحالة تعديلات المستخدم A جرت على بيانات خاطئة لأنه أثناء التعديل للبيانات لم يعلم بالتعديلات التي حفظها المستخدم B.

مخطط ال Sequence Diagram التالي يوضح السيناريو:

11

هذه المشكلة شائعة في التطبيقات الموزعة ولها عدة حلول

الحل الافتراضي “Last One Wins

وهو يمثل تجاهل هذه المشكلة وبكل بساطة حفظ تعديلات آخر مستخدم قام بالتعديل دون فحص فيما إذا كان أحدهم قام بالتعديل أي حفظ تعديلات المستخدم A لأنه آخر من قام بالتعديل وهو حل ممكن في التطبيقات ذات الأهمية المنخفضة حيث أنه الابسط والحلول الأخرى مكلفة برمجيا.

ولكنه غير مناسب أبدا للمشاريع المؤسساتية الكبيرة ولذلك لم نختره في مشروعنا.

-  الحل التزامني المتشائم (بالقفل) Pessimistic Concurrency:

حيث يتم ” قفل “السجل الذي يجري تعديله حاليا ومنع أي مستخدم من تعديله 

ففي السيناريو السابق لن يسمح للمستخدم B بالدخول إلى صفحة تعديل هذا العنصر لأن A لا سيزال في صفحة التعديل ويتم فك القفل في الحالتين التاليتين:

- عند الخروج من صفحة التعديل دون الحفظ.

-  عند حفظ التعديلات.

وهذا الحل جيد فقط في التطبيقات المكتبية وذلك لإمكانية معرفة وقت الخروج من صفحة التعديل وتطبيقه غير ممكن في الويب، ونحن في مشروعنا نريد حلا يشمل جميع أنواع التطبيقات وليس المكتبي منها فقط ولذلك لم نطبق هذا الحل أيضا.

-  الحل التزامني المتفائل Optimistic Concurrency وهو المعتمد في المشروع:

عند فتح صفحة التعديل من قبل المستخدم A لن يتم قفل السجل ويمكن لأي مستخدم فتح صفحة التعديل ولكن عند حدوث السيناريو السابق يتم إعطاء رسالة خطأ للمستخدم A ويتم تجاهل تعديلاته لأنه قام بالتعديل انطلاقا من بيانات أصبحت خاطئة بعد التعديل الذي قام به B أثناء هذه العملية.

وهو الحل المعتمد في مشروعنا لأنه مناسب لكافة أنواع التطبيقات المكتبية منها وتطبيقات الويب وأي نوع آخر مع العلم أنه الحل الأصعب تنفيذا من الناحية البرمجية.

- طريقة بسيطة لتنفيذ هذا الحل في مشروع ويب:

- يتم إضافة حقل إلى جميع الجداول في النظام وهذا الحقل عبارة عن (Time Stamp) تتغير عند أي تعديل على السجل.

 وعند طلب عملية التعديل يتم فحص القيمة الموجودة في الجدول مع القيمة المرسلة من أجل التعديل فإن كانتا متساويتين يتم التعديل بنجاح لأن هذا يدل على أن السجل لم يتم تعديله منذ أن أُحضر السجل من قاعدة البيانات في المرة السابقة.

وأما إذا كانت قيم الـ Time Stamp   غير متساوية فيتم توليد خطأ يفيد بأن عملية التعديل فشلت بسبب فحص التزامن المتفائل، و سيتم اعلام المستخدم بان العملية فشلت بهذا السبب.

02/2/13

موجز عن مشروعي التخرج – Enterprise Project Generator

المشاريع المؤسساتية هي مشاريع ضخمة وذات تعقيد كبيرنسبياً وتحتاج لفلسفة بناء خاصة لها عادة وجهين ايجابي وسلبي :

  • ·        الوجه الإيجابي:

أنها تقدم مفاهيم العزل و زيادة قابلية الصيانة وقابلية الاختبار وقابلية التوسع والتخصيص  وإعادة الاستعمال وميزات كبيرة أخرى.

  • ·        الوجه السلبي:

وضع بنية تحتية تقدم الميزات السابقة يؤدي إلى زيادة كبيرة بالجهد اللازم في التطوير وعلى مسارين:

تحديد البنية المستخدمة وتصميم المكونات اللازمة لها.

كتابة الشيفرة المصدرية للمشروع وهي في هذه الحالة  أكبر من الشيفرة المصدرية في حالة كتابة المشروع بالطريقة ” اللا مؤسساتية”.

من هنا نبعت فكرت مشروعنا.. فالحاجة أم الاختراع…فكرنا في بناء مشروع يهدف إلى تعزيز الجانب الإيجابي وتهميش الجانب السلبي ماأمكن ذلك. وساعدنا على ذلك فكرة إمكانية أتمتة بعض الجوانب في المشاريع المبنية على نظام العمل المؤسساتي.. وتوصلنا لمشروع يقوم بتوليد نظام يعتمد بشكل أساسي على البنية متعددة الطبقات (3 Tier Architecture) ويقدم الخدمات التالية:

  • العمليات الأساسية على المعطيات (إضافة وتعديل وحذف واستعلام..).
  • تعددية اللغات على مستوى الواجهة وقاعدة البيانات بطريقة مبتكرة (جديدة ).
  • التوزيع Distribution من خلال توليد Web Services.

و يقدم أيضا حلولاً لمشاكل عادة ما تؤرق المطورين و يتجنب حلها الكثيرين لصعوبة حلها مثل:

  • مشكلة التزامن Concurrency.
  • مشكلة تصفيح البيانات و ترتيبها (Pagination & Ordering) .
  • مشكلة حفظ معلومات المتابعة التي تساعد على تتبع الأخطاء و كشف الاستعمال المسيئ للنظام مثل حفظ صاحب آخر تعديل على أي سجل في قاعدة البيانات و تاريخ هذا التعديل و معلومات أخرى.
  • مشكلة العزل التام لطبقة الوصول للمعطيات (لكي يتاح تغييرها دون أي تأثير على باقي أجزاء المشروع).

هذا المشروع تم تقديمه لنيل درجة البكالوريوس في الهندسة المعلوماتية من قبل:

م.محمود البيك

م.طلال عبد الواحد

م. غيث عقاد

م. محمد صخر صوان

أشرف على المشروع:

الدكتور      : أحمد بدرالدين خضر

الدكتور      : حيــــــان حــــــصرم (رحمه الله و اسكنه فسيح جنانه)

المهندس   : بشــــر مسلاتـــــي

A4 Interface

02/2/13

من مشروعي التخرج – 1 – تعدد اللغات في قاعدة المعطيات

سأقوم في هذه السلسلة من المقالات بوضع بعض الفقرات العامة التي وردت في أطروحة مشروع التخرج الذي تقدمنا به في كلية الهندسة المعلوماتية، وقد حاز هذا المشروع على العلامة الاعلى على مستوى الكلية في تلك السنة، قدم هذا المشروع كل من:

م.محمود البيك
م.طلال عبد الواحد
م. غيث عقاد
م. محمد صخر صوان

أشرف على المشروع:

الدكتور      : أحمد بدرالدين خضر

الدكتور      : حيــــــان حــــــصرم (رحمه الله و اسكنه فسيح جنانه)

المهندس   : بشــــر مسلاتـــــي

موجز عن المشروع

مشكلة تعدد اللغات في قواعد المعطيات و الحلول المطروحة:

- بحثنا عن هذا الموضوع فوجدنا عدداً من الحلول لها مالها وعليها ما عليها. سنقدمها باختصار مع ميزاتها وسلبياتها ثم نقدم الحل المبتكر الذي اعتمدناه في مشروعنا.

- الحل الاول وهو الابسط:

إضافة حقل إضافي لكل جدول وهو (Language Id) وجعله كجزء من المفتاح الرئيسي للجدول حيث يعبر هذا الحقل الجديد عن لغة السجل ويتم تخزين نفس السجل عدة مرات مع تغير الـ (Language Id) وترجمة باقي الحقول بنفس المعرف الرئيسي مثلا:

الجدول ذو البنية التالية:

1

والبيانات مثلا السجلات:

Price

Name

ID

2000

Product 1

10

1000

Product2

20

تصبح:

Price

Name

Language  ID

ID

2000

Product1

en-US

10

2000

المنتج الأول

ar-SY

10

1000

Product2

en-US

20

1000

المنتج الثاني

ar-SY

20

 ايجابيات هذه الطريقة:

  • التغيرات في بنية الجداول في حدها الادنى.

السلبيات:

  • أوضح جانب سلبي في هذه الطريقة هو فائضية البيانات (Data Redundancy) حيث يتم تخزين الواصفات غير اللغوية والتي لا تتغير تبعا لتغير اللغة بشكل مكرر من اجل كل لغة مثلا (الواصفة Price في مثالنا السابق).

مع أن التغير المطلوب في بنية الجداول قليل لكنه مؤثر فإنه يؤدي إلى تغيير المفتاح الرئيسي للجدول مما يلحق مشاكل كبيرة في ربط الجدول مع غيره ولذلك لم نطبقه في مشروعنا.

الحل الثاني:

إضافة جدول جديد لكل لغة وهذا الجدول يحتوي البيانات اللغوية فقط مثلا:

2

 الجانب السلبي الرئيسي في هذه الطريقة تعقيد بنية الجداول وعدم رشاقتها إذ أن إضافة لغة جديدة للنظام بتطلب إضافة جداول إلى قاعدة البيانات بعدد جداول قاعدة البيانات الرئيسية ولكن إضافة جداول إلى قاعدة البيانات أثناء العمل (Run Time) عملية غير مألوفة وسلبية ولذلك لم يطبق في المشروع.

الحل الثالث:

يتم وضع جدول مركزي يحتوي كل العبارات اللغوية وبنيته من الشكل:

3

وعند إضافة واصفات لغوية للجداول يتم اضافتها كعلاقة مع الجدول السابق مثال 

4

السلبية الرئيسية لهذه البنية هي ضخامة الجدول المركزي وعدم القدرة على تطبيق قيود محددة على واصفة ما أو تطبيق فهرسة عليها إذ أن جميع الواصفات تخزن بنفس الطريقة إضافة إلى أن هذه الطريقة صعبة التنفيذ والبرمجة ولهذه الأسباب لم يتم تطبيقه في مشروعنا.

الطريقة المعتمدة في المشروع:

يتم تقسيم الجدول إلى جدولين:

-    الجدول الاول يحوي المعرف والواصفات الغير لغوية (الثابتة بتغير اللغة مثل السعر في مثالنا السابق) -الجدول (A)

-    الجدول الثاني ويحتوي على المعرف ومعرف اللغة والواصفات اللغوية التي نريد تخزينها بعدة لغات -الجدول (B)

 

-    ويتم ربط هذين الجدولين عن طريق علاقة One To Many حيث كل سجل من الجدول (A) يرتبط بعدة سجلات من الجدول (B) وبهذه الطريقة نكون قد حافظنا من جهة على الشكل الرئيسي للجدول ولم نقم بتغير المفتاح الرئيسي له وأيضا نكون قد قللنا فائضية البيانات إلى الحد الأدنى حيث أن الواصفات الغير لغوية تخزن مرة واحدة أما الواصفات اللغوية فهي تخزن من أجل كل لغة:

5

اسقاط الحل المعتمد على نموذج صفوف المعطيات (Data Class Model):

إن العنصر يمثل بصفين 

-    الصف (Class) الأول: هو الرئيسي ويحتوي الحقول غير اللغوية إضافة إلى مصفوفة أو لائحة من الصف الثاني.

-     الصف (Class) الثاني: يحتوي على الحقول اللغوية.

بشكل مشابه لنموذج الجدول:

6

12/26/12

Developing a simple encrypted files container using C# – تشفير مجلد عن طريق لغة C#

The goal is to make a simple encrypted files container to encrypt a folder in a single file using c#:

الهدف من المقالة كتابة كود لتشفير مجموعة من الملفات في ملف واحد باستخدام لغة سي شارب

You can put your files in a list of custom class:

يمكن وضع معلومات الملفات و محتوياتها ضمن بنية كما يلي:

[Serializable]
public class FileEntry
{
 public string FileName {get;set;}
 public string FileRelativePath {get;set;}
 public byte[] FileContents {get;set;}
}

 

Add the files to a list:

عملية إضافة الملفات إلى القائمة:

List<FileEntry> files = new  List<FileEntry> ();

for .......
{
    files.Add(new FileEntry()
    {
        FileName  = .....,
        FileRelativePath = .....,
        FileContents = File.ReadAllBytes(......),
    };
}

And then, use BinarryFormatter to convert this structure to byte-array:

تحويل هذه البنية إلى مصفوفة من البايتات باستخدام الصنف
BinarryFormatter

byte[] filesBytes;
BinarryFormatter ser = new     BinarryFormatter();
using(MemoryStram ms = new MemoryStram())
{
    ser.Serialize(ms, files);
    filesBytes = ms.ToArray();
}

Now, you have your structure as byte[], you can easily encrypt them with some easy way as this:

عملية التشفير باستخدام اي خوارزمية تشفير مشهورة و قد وضعت رابطا لطريقة تشفير مصفوفة بايتات بطريقة سهلة في الاسفل

filesBytes = Encrypt(filesBytes , ......);

Then save the encrypted bytes to some location with some custom extension:

يمكن الان حفظ المصفوفة المشفرة إلى مكان ما:

File.WriteAllBytes(".........\.....encr",filesBytes);

 

Then, when you want to re-open the file and read the clear data:

ولاستعراض الملفات المشفرة و حفظها إلى مكان ما، أولا يجب قراءة محتويات الملف المشفر:

byte[] encryptedData = File.ReadAllBytes(".......\.....encr");

Decrypt the contents with the same algorithm:

ومن ثم فك تشفيرها باستخدام نفس الخوارزمية السابقة:

byte[] clearContent = Decrypt(encryptedData, ......);

And deserialize the contents into the primary structure:

و الآن يمكن استرجاع البنية السابقة للملفات باستخدام نفس الصف:
BinarryFormatter

BinarryFormatter ser = new BinarryFormatter();
using(MemoryStram ms = new MemoryStram(clearContent))
{
    List<FileEntry>  files = ser.DeSerialize(ms) as List<FileEntry>;
}

And then, write the content of the files to some location if you want:

يمكنك الآن كتابة محتويات الملفات بعد فك تشفيرها إلى مكان ما:

foreach(var file in files)
{
     File.WriteAllBytes(string.Format("........{0}...{1}",file.FileRelativePath , file.FileName), file.FileContents)
}

You can use this question about encryption:

يمكنكم الرجوع إلى الرابط التالي لتجدو معلومات عن التشفير و فك التشفير

Easy way to encrypt/obfuscate a byte array using a secret in .NET?

و هذا مثال عن عملية التحويل من اي بنية إلى مصفوفة بايتات

And this is an example about binary formatter:

 

06/21/12

Installing Visual Studio 2012 RC on a production machine is a nightmare!

I have installed Visual Stdio 2012 Release Candidate on my production machine, then, i couldn’t add a service reference, some times i have problems with TFS, (sometimes i couldn’t check-in), some of .csproj files and .sln files are not open-able now via 2010, publishing web-services and websites is not working now!!!

This is not the main problem, the main one is that some of the previous problems affected vs 2010; If you repented and returned to VS 2010, you would see the that the problems are chasing you there!!!

الخلاصة:
لا تقم بتجربة نسخة
Visual Studio 2012 RC (Release Candidate)

على الجهاز الرئيسي الذي تعمل عليه، لأن ذلك سيؤدي إلى مصائب كبيرة!!