كيفية كتابة مكون OSGi المخصص WSO2؟

هل تريد معرفة كيفية تطوير خدمة OSGi؟ سنقوم هنا بتطوير تطبيق بسيط باستخدام OSGi واختباره في نظام WSO2 Carbon الأساسي وهو إطار تطوير خادم قائم على وحدات OSGi. مرتبك بالفعل حول ما هو OSGi؟ لا تقلق ، سأشرح ذلك قريبًا. من المتوقع أن يتمتع القراء بخبرة سابقة في تطوير Java و Apache Maven. يتيح الغوص في :)

أولاً وقبل كل شيء ، قبل وضع أصابعنا على لوحة المفاتيح والبدء في الترميز ، اسمحوا لي أن أشرح الفكرة الحقيقية وراء استخدام OSGi في التطبيقات. OSGi (مبادرة بوابة الخدمات المفتوحة) هي إطار عمل مكون لجافا والذي يحدد بنية لتطوير التطبيقات المعيارية. هذا يعطينا المرونة في تثبيت التطبيقات وبدءها وإيقافها وتحديثها وإلغاء تثبيتها عن بعد الواردة في شكل حزم للنشر دون الحاجة إلى إعادة تشغيل. رائع حق؟ هناك تطبيقات حاوية OSGi مختلفة مثل الإعتدال ، Knopflerfish و Felix. في هذا البرنامج التعليمي مثل حاوية OSGi ، سنستخدم تطبيق حاوية Eclipse OSGi ، يستخدم Equinox (يستخدم Eclipse Equinox كوقت تشغيل OSGi في WSO2 Carbon Platform). لا يزال غير واضح؟ لا تقلق مواصلة القراءة سوف تفهم ذلك قريبا. دعنا ننتقل إلى الترميز.

في هذه المقالة سأقوم أولاً بإنشاء مشروعين مخضرمين ؛ osgiproduc و osgiconsumer. في مشروع osgiproducer ، تتم كتابة خدمة OSGi وفي مشروع osgiconsumer ، سيتم استهلاك خدمة OSGi المكتوبة مسبقًا.

دعونا نضع أيدينا على إنشاء مشروع osgiproducer كمرحلة أولى باتباع الخطوات البسيطة الموضحة أدناه.

1. pom.xml

<؟ xml version = "1.0" encoding = "UTF-8"؟>

     4.0.0 

    <الأم>
         org.wso2 
         WSO2 
        <إصدار> 1 
    

     com.example.osgiproducer 
     osgiproducer 
    <الإصدار> 1.0.0 لقطة 

    <التعبئة والتغليف> حزمة 

    <بناء>
        <الإضافات>
            <المساعد>
                 org.apache.felix 
                 مخضرم-SCR-المساعد 
                <الإصدار> 1.9.0 
            
            <المساعد>
                 org.apache.felix 
                 مخضرم-حزمة من المساعد 
                <ملحقات> صحيح 
                <التكوين>
                    <تعليمات>
                        <حزمة-SymbolicName> $ {project.artifactId} 
                        <حزمة-اسم> $ {project.artifactId} 
                        <الخاص حزمة> com.example.osgiproducer.package01.internal، 
                        <استيراد وحزمة>
                            org.osgi.framework،
                            org.osgi.service.component،
                        
                        <التصدير وحزمة>
                            ! com.example.osgiproducer.package01.internal.ProducerComponent،
                            com.example.osgiproducer.package01. *؛ نسخة = "1.0.0 لقطة"
                        
                    
                
            
        
    

    <تبعيات>
        <الاعتماد>
             org.eclipse.osgi 
             org.eclipse.osgi 
            <إصدار> 3.9.1.v20130814-1242 
        
        <الاعتماد>
             org.eclipse.osgi 
             org.eclipse.osgi.services 
            <إصدار> 3.3.100.v20130513-1956 
        
    
    

دعونا ننظر عن كثب إلى تكوينات POM المذكورة أعلاه.

<التعبئة والتغليف> حزمة 

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

<التصدير وحزمة>
    ! com.example.osgiproducer.package01.internal.ProducerComponent،
    com.example.osgiproducer.package01. *؛ نسخة = "1.0.0 لقطة"

يمثل <تصدير الحزمة> قائمة الحزم لحزمة للتصدير. سيتم نسخ هذه الحزم إلى الحزمة الناتجة JAR. يمكننا استبعاد الحزم التي لا نريد استيرادها باستخدام negation (!). لاحظ أنه من الضروري استخدام الأسماء المؤهلة بالكامل عند استدعاء الفئات والحزم ذات الصلة. سيتم توضيح الغرض من تصدير الحزم لاحقًا عند إضافة تكوينات POM إلى مشروع osgiconsumer.

حقيقة رئيسية أخرى ينبغي أن أذكر عنها هي .

<الخاص حزمة> com.example.osgiproducer.package01.internal، 

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

<استيراد وحزمة>
    org.osgi.framework،
    org.osgi.service.component،

تشير تعليمات إلى الحزم المطلوبة بواسطة الحزم المتضمنة في الحزمة.

2. واجهة المنتج

package com.example.osgiproducer.package01؛

واجهة عامة منتج {

    إنتاج باطل (اسم السلسلة) ؛
}

3. فئة ProducerImpl

package com.example.osgiproducer.package01؛

استيراد java.util.logging.Logger ؛

ProducerImpl من الطبقة العامة ينفذ المنتج {

    نهائي ثابت خاص Logger LOGGER = Logger.getLogger (ProducerImpl.class.getName ())؛

    @تجاوز
    إنتاج الفراغ العام (اسم السلسلة) {
        
        LOGGER.info ("أنتج بنجاح:" + اسم) ؛
      
    }
}

4. الطبقة منتج

حزمة com.example.osgiproducer.package01.internal ؛

استيراد com.example.osgiproducer.package01.Producer؛
استيراد com.example.osgiproducer.package01.ProducerImpl؛
import org.osgi.framework.BundleContext؛
استيراد org.osgi.service.component.annotations.Activate ؛
import org.osgi.service.component.annotations.Component؛

Component (name = "com.example.osgiproducer.package01.internal.ProducerComponent"،
        فوري = صحيح)
فئة المنتج العام

    @تفعيل
    تنشيط الفراغ المحمي (BundleContext bundleContext) {

        bundleContext.registerService (Producer.class، ProducerImpl ()، new null)؛
    }
}

لاحظ أنه كما ذكرنا سابقًا ، يجب أن تكون فئة ProducerComponent داخل الحزمة المسماة الداخلية.

سيبدو هيكل مجلد المشروع هكذا ،

أخيرًا ، قم بإنشاء المشروع من خلال استدعاء الأمر maven "mvn clean install" وستحصل على osgiproducer-1.0.0.-SNAPSHOT.jar داخل المجلد الهدف.

الآن لنقم بإنشاء مشروع osgiconsumer باتباع الخطوات المذكورة أدناه.

  1. ملف بوم
<؟ xml version = "1.0" encoding = "UTF-8"؟>

     4.0.0 

    <الأم>
         org.wso2 
         WSO2 
        <إصدار> 1 
    

     com.example.osgiconsumer 
     osgiconsumer 
    <الإصدار> 1.0.0 لقطة 

    <التعبئة والتغليف> حزمة 

    <بناء>
        <الإضافات>
            <المساعد>
                 org.apache.felix 
                 مخضرم-SCR-المساعد 
                <الإصدار> 1.9.0 
            
            <المساعد>
                 org.apache.felix 
                 مخضرم-حزمة من المساعد 
                <ملحقات> صحيح 
                <التكوين>
                    <تعليمات>
                        <حزمة-SymbolicName> $ {project.artifactId} 
                        <حزمة-اسم> $ {project.artifactId} 
                        <الخاص حزمة> com.example.osgiconsumer.package01.internal، 
                        <استيراد وحزمة>
                            org.osgi.framework،
                            org.osgi.service.component،
                            com.example.osgiproducer.package01. *؛ نسخة = "1.0.0 لقطة"
                        
                        <التصدير وحزمة>
                            ! com.example.osgiconsumer.package01.internal.ConsumerComponent،
                            com.example.osgiconsumer.package01. *؛ نسخة = "1.0.0 لقطة"
                        
                    
                
            
        
    

    <تبعيات>
        <الاعتماد>
             org.eclipse.osgi 
             org.eclipse.osgi 
            <إصدار> 3.9.1.v20130814-1242 
        
        <الاعتماد>
             org.eclipse.osgi 
             org.eclipse.osgi.services 
            <إصدار> 3.3.100.v20130513-1956 
        
        <الاعتماد>
             com.example.osgiproducer 
             osgiproducer 
            <الإصدار> 1.0.0 لقطة 
            <نطاق> المقدمة 
        
    


لن أشرح عن تكوينات POM مرة أخرى ولكن هناك حقيقة واحدة يجب أن أشير إليها.

<استيراد وحزمة>
    org.osgi.framework،
    org.osgi.service.component،
    com.example.osgiproducer.package01. *؛ نسخة = "1.0.0 لقطة"

لاحظ أنه يتعين علينا استيراد الحزمة التي قمنا بتصديرها في مشروع osgiproducer وأود مرة أخرى التأكيد على حقيقة أنه ينبغي أن يسمى باستخدام الاسم المؤهل بالكامل.

2. فئة المستهلك

حزمة com.example.osgiconsumer.package01.internal ؛

استيراد com.example.osgiproducer.package01.Producer؛
import org.osgi.framework.BundleContext؛
استيراد org.osgi.service.component.annotations.Activate ؛
import org.osgi.service.component.annotations.Component؛
import org.osgi.service.component.annotations.Reference؛
import org.osgi.service.component.annotations.ReferenceCardinality؛
import org.osgi.service.component.annotations.ReferencePolicy؛


Component (name = "com.example.osgiconsumer.package01.ConsumerComponent"،
        فوري = صحيح)
الطبقة العامة
    منتج منتج = لاغ

    @تفعيل
    تنشيط الفراغ المحمي (BundleContext bundleContext) {
        منتج (منتج مكون) ؛
    }

    Reference (name = "producerService"، service = Producer.class،
                Cardinality = ReferenceCardinality.MANDATORY، policy = ReferencePolicy.DYNAMIC، unbind = "unbindService")
    سجل الفراغ المحميخدمة (منتج منتج) {
        هذا المنتج = المنتج ؛
    }

    إلغاء الربط المحمي (منتج منتج) {

    }
}

لاحظ أن فئة ConsumerComponent داخل الحزمة الفرعية الداخلية.

سيبدو هيكل مجلد المشروع هكذا ،

قم ببناء المشروع وستحصل على ملف الجرة التالي.

الآن دعونا نختبر خدمة OSGi التي كتبناها. كما ذكرنا في بداية هذه المقالة ، سنختبر كودنا في منصة WSO2 Carbon.

استنساخ https://github.com/wso2/carbon-kernel. الخروج إلى فرع 4.4.x وبناء المشروع باستخدام الأمر "تثبيت نظيفة mvn".

بعد ذلك انتقل إلى موقع المشروع kernel -> التوزيع -> المنتج -> الوحدات -> التوزيع -> الهدف. سترى حزمة ثنائية (ملف ZIP) داخل الدليل الهدف. استخراج هذا الرمز البريدي إلى الموقع المفضل. بدءًا من وقت كتابة هذا المقال ، سأستخدم إصدار wso2carbon-4.4.18-SNAPSHOT. سأشير إليه باسم (دليل حيث قمت بتثبيت توزيع المنتج).

انتقل إلى -> مستودع -> المكونات -> dropins. انسخ 2 ملفات JAR تم إنشاؤها في مجلد dropins.

نحن الآن على استعداد لاختبار ما إذا كانت خدمة OSGi الخاصة بنا تعمل بشكل صحيح أم لا. أولاً ، يتعين علينا بدء تشغيل الخادم ثم التحقق من تنشيط حزم الخدمة 2 OSGi. لهذا علينا أن نبدأ الخادم في وضع وحدة التحكم OSGi.

انتقل إلى -> دليل bin وافتح موجه الأوامر. قم بتنفيذ أحد الأوامر التالية:

  1. لمستخدمي ويندوز:

wso2server.bat - تشغيل -DosgiConsole

2. بالنسبة لمستخدم Linux:

sh wso2server.sh -DosgiConsole

الآن ، ستتم طباعة سجلات بدء تشغيل الخادم. عند اكتمال بدء تشغيل الخادم ، ابحث عن رسالة السجل التالية التي تم تمييزها في الصورة.

اضغط على زر الإدخال عندما يكمل الخادم بدء التشغيل. ثم سوف تحصل على وحدة التحكم osgi. قم بتنفيذ الأمر "ss". ستحصل بعد ذلك على نظرة عامة على جميع حزم OSGi المتاحة مع حالاتها الحالية ومعرفاتها المشابهة للصورة أدناه.

انتقل إلى القائمة وسترى ملفي JAR اللذين قمنا بنسخهما إلى مجلد dropins بالحالة نشط.

قم بتنفيذ الأمر "b " للحصول على معلومات حول الحزمة بما في ذلك الخدمات المسجلة والمستعملة.

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

الرجوع إلى الروابط التالية للحصول على شفرة المصدر.

لذا حان الوقت للخروج إلى هناك وكتابة بعض خدمات OSGi!