Статьи

СКА, Ньютон и Спринг Д.М.

На прошлой неделе я посетил  тренинг Ньютона, представленный Дэвидом Сэвиджем и Майком Фрэнсисом из Паремуса . Newton — это проект с открытым исходным кодом, нацеленный на реализацию спецификации SCA с использованием возможностей OSGi внутри одной JVM и JINI за ее пределами.

 

Цель

Создайте 2 составных приложения:

  • Композитный 1: Публикация сервиса вне текущей JVM с использованием SCA с Spring DM и Newton
  • Композит 2: Потребление услуг.

инструменты

 Для этого я использовал:

Создание проекта

  1. Создайте новый групповой проект в Netbeans с именем sca .
  2. Новые проекты Maven:

    1. родительский проект, который будет содержать 3 подпроекта:
    2. API : интерфейс службы.
    3. импл : реализация сервиса.
    4. клиент : потребляющий услугу.
  3. Добавьте api-зависимость для impl и client .
  4. Добавьте каталоги ресурсов для проектов impl и client с пустыми XML-файлами Spring DM и Newton. 
  5. Каталог проекта будет:

,
| — API
| | — pom.xml
| `- src
| `- главная
| `- Ява
| `- ком
| `- Jtunisie
| `- osgi
| `- sca
| `- IService.java
| — клиент
| | — pom.xml
| `- src
| `- главная
| | — Ява
| | `- ком
| | `- Jtunisie
| | `- osgi
| | `- sca
| | `- клиент
| | `- Activator.java
| `- ресурсы
| `- МЕТА-ИНФ
| | — ньютон
| | `- client.composite
| `- весна
| | — bundle-context-osgi.xml
| `- bundle-context.xml
| — impl
| | — pom.xml
| `- src
| `- главная
| | — Ява
| | `- ком
| | `- Jtunisie
| | `- osgi
| | `- sca
| | `- impl
| | `- Service.java
| `- ресурсы
| `- МЕТА-ИНФ
| | — ньютон
| | `- service.composite
| `- весна
| | — bundle-context-osgi.xml
| `- bundle-context.xml`
— pom.xml

IService содержит одну сигнатуру метода:

public interface IService extends Serializable  {

String getMessage(String name);
}

Реализация Сервиса — это:

public class Service implements IService  {

@Override
public String getMessage(String name) {
return "Hello " + name;
}
}


Активатор клиента (не Активатор OSGi):

public class Activator {

IService service;

public void setService(IService service) {
this.service = service;
}

public void init() {
String message = service.getMessage("world!!!!");
System.out.println(message);
}
}

 



Файлы Пом

  • Измените три проекта для упаковки пакетов: добавьте <package> bundle </ packaging> в заголовки pom.
  • Api будет экспортировать пакет com.jtunisie.osgi.sca

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.jtunisie.osgi.sca</Export-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
  • impl также экспортирует пакет com.jtunisie.osgi.sca и сделает реализацию частной

<build>
<plugins>
<plugin>
<groupid>org.apache.felix</groupid>
<artifactid>maven-bundle-plugin</artifactid>
<extensions>true</extensions>
<configuration>
<instructions>
<export-package>com.jtunisie.osgi.sca</export-package>
<private-package>com.jtunisie.osgi.sca.impl</private-package>
<bundle-symbolicname>${pom.name}-${pom.version}</bundle-symbolicname>
</instructions>
</configuration>
</plugin>
</plugins>
</build>


Примечание. Пакет
impl содержит интерфейс API, поэтому не развертывайте
пакет
API . Да, нам не нужно включать
API в
пакет
Impl . Просто импортируйте
 пакет
com.jtunisie.osgi.sca и разверните два пакета.

  • Клиент пакет не экспортирует любой пакет:

  <build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Private-Package>com.jtunisie.osgi.sca.client</Private-Package>
<Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins>
</build>


  • Добавьте заголовки Newton: Installable-Component-Templates — это имя составного файла в ресурсах | — META-INF | — каталог newton.
    • Импл пом:

        <build>
    <plugins>
    <plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
    <instructions>
    <Export-Package>com.jtunisie.osgi.sca</Export-Package>
    <Private-Package>com.jtunisie.osgi.sca.impl</Private-Package>
    <Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
    <Installable-Component>true</Installable-Component>
    <Installable-Component-Templates>META-INF/newton/service.composite</Installable-Component-Templates>
    </instructions>
    </configuration>
    </plugin>
    </plugins>
    </build>


    • клиент пом:
      <build>
      <plugins>
      <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
      <instructions>
      <Private-Package>com.jtunisie.osgi.sca.client</Private-Package>
      <Bundle-SymbolicName>${pom.name}-${pom.version}</Bundle-SymbolicName>
      <Installable-Component>true</Installable-Component>
      <Installable-Component-Templates>META-INF/newton/client.composite</Installable-Component-Templates>
      </instructions>
      </configuration>
      </plugin>
      </plugins>
      </build>

 

Издательский сервис

  • Вернемся к пакету impl и его файлам Spring XML. Объявите простой bean-компонент Spring в bundle-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>

<bean id="service" class="com.jtunisie.osgi.sca.impl.Service"/>
</beans>


  • Опубликуйте его в bundle-context-osgi.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">




<osgi:service id="_service" interface="com.jtunisie.osgi.sca.IService" ref="service"/>

</beans>


Сервис теперь публикуется внутри локального контейнера OSGi с использованием Spring DM.

  • Теперь мы выставим его за пределы локального контейнера. Чтобы сделать это, мы сначала добавляем свойство в наш открытый сервис, чтобы Newton мог его обнаружить. будет содержать bundle-context-osgi.xml .

 <osgi:service id="_service" interface="com.jtunisie.osgi.sca.IService" ref="service">
<osgi:service-properties>
<entry key="newton.sca.service" value="sca_service"/>
</osgi:service-properties>
</osgi:service>


  • Служба экспорта:

Ньютон в основном предоставляет сервисы, использующие RMI за пределами локальной JVM, и мы можем использовать OSGi внутри него. Составной файл представляет собой документ XML. Для редактирования давайте добавим этот тип в IDE Netbeans.

  •  Перейти к инструментам -> Параметры -> Разное
  • В расширении файла нажмите «Создать» и добавьте в него композитный код «APPLICATION / xhtml + xml».
  •  Откройте service.composite.
  •   Редактировать service.composite, добавить две услуги для  RMI и OSGi :
      <service name="sca_service_rmi" >
    <interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
    <binding.rmi/>
    </service>
    <service name="sca_service_osgi" >
    <interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
    <binding.osgi/>
    </service>


  •  Мы можем использовать короткое объявление (но я его не проверял):

    <service name="sca_service_rmi" >
    <interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
    <binding.rmi/>
    <binding.osgi/>
    </service>


  • Добавьте наш пакет как компонент, который реализован с помощью Spring:

<component name="srv">
<description>spring configuration</description>
<service name="sca_service" />
<sdm:implementation.spring />
</component>


Имя службы — это файл источника значения свойства newton.sca.service.

  • У нас есть две службы привязки и один компонент. Теперь добавьте электромонтажные услуги:

 <wire>
<source.uri>sca_service_rmi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
<wire>
<source.uri>sca_service_osgi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>


  • Добавить Impl композитный:

<?xml version="1.0" encoding="UTF-8"?>
<composite name="configuration"
xmlns:sdm="http://newton.cauldron.org/springdm">.
<service name="sca_service_rmi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.rmi/>
</service>
<service name="sca_service_osgi" >
<interface.java interface="com.jtunisie.osgi.sca.IService"></interface.java>
<binding.osgi/>
</service>
<component name="srv">
<description>spring configuration</description>
<service name="sca_service" />
<sdm:implementation.spring />
</component>
<wire>
<source.uri>sca_service_rmi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
<wire>
<source.uri>sca_service_osgi</source.uri>
<target.uri>srv/sca_service</target.uri>
</wire>
</composite>


  • Мы закончили наш первый композит. Он публикует сервис внутри и вне JVM, настраивая только три XML-файла.

Использование сервиса:

Давайте использовать аннотации Spring, чтобы использовать этот сервис в
клиентском проекте.

  • Добавьте spring-osgi-annotation к зависимости pom XML:

<dependency>
<groupId>org.springframework.osgi</groupId>
<artifactId>spring-osgi-annotation</artifactId>
<version>1.1.1</version>
</dependency>

Зарегистрируйте bean-компонент Activator в bundle-context.xml и включите процессор аннотаций
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-init-method="init">


<bean id="activator" class="com.jtunisie.osgi.sca.client.Activator"/>


<!-- annotation processor -->
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor"/>
</beans>


Метод init () будет вызываться как метод init-default.

  • Нет необходимости в bundle-context-osgi.xml, мы можем его удалить.
  • В классе Activator мы добавляем аннотацию Spring следующим образом:

@ServiceReference(filter="(newton.sca.reference=service_cons)")
public void setService(IService service) {
this.service = service;
}


Примечание. Фильтр используется для включения Ньютона.

  • В составном файле мы добавляем сервисную ссылку с именем service_ref_rmi

 <reference name="service_ref_rmi" multiplicity="0..1">
<interface.java interface="com.jtunisie.osgi.sca.IService" />
<binding.rmi/>
</reference>


  • Объявите компонент с именем serv-test с именем ссылки в качестве значения фильтра newton.sca.reference

  <component name="serv-test">
<description>spring configuration</description>
<reference name="service_cons" />
<sdm:implementation.spring />
</component>


  • Ссылка на провод к компоненту:

 <wire>
<source.uri>serv-test/service_cons</source.uri>
<target.uri>service_ref_rmi</target.uri>
</wire>


  • Мы закончили наш второй композит:

<?xml version="1.0" encoding="UTF-8"?>
<composite name="service_test"
xmlns:sdm="http://newton.cauldron.org/springdm">

<reference name="service_ref_rmi" multiplicity="0..1">
<interface.java interface="com.jtunisie.osgi.sca.IService" />
<binding.rmi/>
</reference>
<component name="serv_test">
<description>spring configuration</description>
<reference name="service_cons" />
<sdm:implementation.spring />
</component>

<wire>
<source.uri>serv_test/service_cons</source.uri>
<target.uri>service_ref_rmi</target.uri>
</wire>

</composite>

Запуск компоновки SCA:

Прежде чем начать этот последний шаг, нам нужно добавить в папки и два файла.

  • Ls


bin и т. д. привет LICENSE.txt publish-springdm-1.2.0.xml примеры

документов dk springdm
hello-config.script lib NOTICE.txt README.html var

  • Каталог Springdm содержит пакеты Spring 1.2 и пакеты hello  :

springdm

| — aopalliance.osgi-1.0-SNAPSHOT.jar

| — jcl104-over-slf4j-1.4.3.jar

| — log4j.osgi-1.2.15-SNAPSHOT.jar

| — slf4j-api-1.4. 3.jar

| — slf4j-api-1.5.2.jar

| — slf4j-log4j12-1.4.3.jar

| — slf4j-log4j12-1.5.2.jar

| — spring-2.5.5.jar

| — spring-aop-2.5.5.jar

| — spring-beans-2.5.5.jar

| — spring-context-2.5.5.jar

| — spring-context-support-2.5.5.jar

| — spring-core-2.5.5.jar

| — spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar

| — spring-osgi-core-1.2.0-m1.jar

| — spring- osgi-extender-1.2.0-m1.jar

`- spring-osgi-io-1.2.0-m1.jar

привет

| — client-1.0-SNAPSHOT.jar

`- impl-1.0-SNAPSHOT.jar

  • publish-springdm-1.2.0.xml будет использоваться для публикации пакетов Spring

<?xml version="1.0" encoding="iso-8859-1"?>
<publish>
<item name="spring-2.5.5.jar" path="springdm/spring-2.5.5.jar" />
<item name="spring-aop-2.5.5.jar" path="springdm/spring-aop-2.5.5.jar" />
<item name="spring-beans-2.5.5.jar" path="springdm/spring-beans-2.5.5.jar" />
<item name="spring-context-2.5.5.jar" path="springdm/spring-context-2.5.5.jar" />
<item name="spring-context-support-2.5.5.jar" path="springdm/spring-context-support-2.5.5.jar" />
<item name="spring-core-2.5.5.jar" path="springdm/spring-core-2.5.5.jar" />
<item name="spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar" path="springdm/spring-osgi-annotation-1.2.0-m1-SNAPSHOT.jar" />
<item name="spring-osgi-core-1.2.0-m1.jar" path="springdm/spring-osgi-core-1.2.0-m1.jar" />
<item name="spring-osgi-extender-1.2.0-m1.jar" path="springdm/spring-osgi-extender-1.2.0-m1.jar" />
<item name="spring-osgi-io-1.2.0-m1.jar" path="springdm/spring-osgi-io-1.2.0-m1.jar" />
<item name="aopalliance.osgi-1.0-SNAPSHOT.jar" path="springdm/aopalliance.osgi-1.0-SNAPSHOT.jar" />
<item name="jcl104-over-slf4j-1.4.3.jar" path="springdm/jcl104-over-slf4j-1.4.3.jar" />
<item name="slf4j-api-1.4.3.jar" path="springdm/slf4j-api-1.4.3.jar" />
<item name="slf4j-log4j12-1.4.3.jar" path="springdm/slf4j-log4j12-1.4.3.jar" />

</publish>


  • hello-config.script содержит подпрограммы сценария:

Exec и т.д. / скрипты / одной JVM-распред-инфра 
# установить JINI браузер  ( опционально )
установщик установки и т.д. / примеры / jinibrowser.composite

установщик установки и т.д. / экземпляры сервера cds.composite /
система управления и т.д. / системы / дистанционного container.system 

# загружать пакеты в
cds, сканировать cds remote / springdm cds
publish remote publish-springdm- 1.2.0. XML 
CD-сканирование удаленного / привет

  • Откройте два терминала и в первом мы выполним:

 bin / container -fabricName = тест

на втором

 bin / контейнер -fabricName = экземпляр теста = 1

Если используются 2 машины

 bin / container -fabricName = test -bindAddress = machineIP (1) -serviceLookupURLs = jini: machineIP (1)

 bin / container -fabricName = test -bindAddress = machineIP (2) -serviceLookupURLs = jini: machineIP (1) -instance = 1

  • Выполните hello-config.script, введите его на двух терминалах.


> exec hello-config.script

  • На первом jvm мы установим реализацию сервиса:

> установщик установить составной: sca_service

Служба теперь установлена, и вы можете проверить это в браузере jini.

  • На другом jvm мы установим клиент. Давайте проверим это наличие:

> cds find ser *

> Content [service_test: {bundle.symbolic.name = client-1.0-SNAPSHOT, type = component.template, версия = 1.0.0.SNAPSHOT, зона = удаленная}]

  • Установить его

> установщик установить композит: service_test

> Hello world !!!!

  • Мы получаем наше первое сервисное сообщение. На самом деле, клиентский пакет загружается в клиент JVM.
  • Проверить связки

На клиентской консоли введите:

>eq ss
.....
109 RESOLVED impl-1.0-SNAPSHOT_1.0.0.SNAPSHOT
110 RESOLVED org.springframework.bundle.osgi.io_1.2.0.m1
111 RESOLVED org.springframework.bundle.osgi.core_1.2.0.m1
112 RESOLVED org.springframework.bundle.osgi.extensions.annotations_1.2.0.m1-SNAPSHOT
113 ACTIVE org.springframework.bundle.osgi.extender_1.2.0.m1
114 ACTIVE client-1.0-SNAPSHOT_1.0.0.SNAPSHOT


Пакет Impl также загружен, но не запущен. Пакет Impl загружается, потому что он экспортирует интерфейсы API .
На консоли сервера введите:

> eq ss 
....
108 ACTIVE impl-1.0-SNAPSHOT_1.0.0.SNAPSHOT
109 RESOLVED org.springframework.bundle.spring_2.5.5
110 RESOLVED org.springframework.bundle.osgi.io_1.2.0.m1
111 RESOLVED org.springframework.bundle.osgi.core_1.2.0.m1
112 RESOLVED org.springframework.bundle.osgi.extensions.annotations_1.2.0.m1-SNAPSHOT
113 ACTIVE org.springframework.bundle.osgi.extender_1.2.0.m1
114 ACTIVE com.sun.jini.browser_2.1.0


Примечание. Реализация развернута на сервере и активирована.

Примечание. Если мы разделили impl на два пакета api и impl , будет загружен только пакет api, и может возникнуть исключение RMI.

Вывод :

  1. В следующем выпуске OSGii 4.2 рекомендуется использовать функции Apache CXF и JEE.
  2. SCA делает общение простым без необходимости знать протоколы связи, издательские услуги и потребление декларативным способом.

исходный код опубликован в разделе svn:

svn checkout
http://hellosca.googlecode.com/svn/trunk/hellosca-read-only