Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Using Spring with ECF Remote Services"

(ConnectContextFactoryBean)
(Product/Dependencies)
 
(38 intermediate revisions by 2 users not shown)
Line 1: Line 1:
UNDER CONSTRUCTION by Angelo Zerr and Scott Lewis
+
==Introduction==
  
== Target ==
+
Work is underway to integrate ECF's OSGi 4.2 Remote Services with [http://www.springsource.org/osgi Spring Dynamic Module] so that it's easy to '''declare your OSGi Remote Services''' rather than exporting and consuming them programmatically.  This work represents an integration and collaboration between the [http://wiki.eclipse.org/ECF ECF project] and the (proposed) [http://www.eclipse.org/proposals/virgo/ Virgo project].
  
Work is underway to support ECF with [http://www.springsource.org/osgi Spring Dynamic Module] to '''declare your OSGi Services''' that you want publish (Host aka server side) and retrieve (Consumer aka client side ). See (for the moment) [https://bugs.eclipse.org/bugs/show_bug.cgi?id=302113 Bug 302113]-
+
See (for the moment) [https://bugs.eclipse.org/bugs/show_bug.cgi?id=302113 Bug 302113].  This bug is being used to track the contribution to ECF for this work. Attached to this bug are zips containing bundles
you can find several bundles that provide :
+
  
 
<ul>
 
<ul>
    <li>...</li>
+
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.config.log4j''': fragment to configure log4j required by Spring Extender bundle..</li>
    <li>...</li>
+
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.consumer''': bundle of Consumer Hello sample managed with Spring DM.</li>
 +
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.host''': bundle of Host Hello sample managed with Spring DM.</li>
 +
  <li>'''org.eclipse.ecf.springframework''' : bundle of [[#ECF Spring support|ECF Spring support]].</li>
 
</ul>
 
</ul>
  
== How it works? ==
+
These samples work with ECF 3.2, which is scheduled for release on Feb 19, 2010. If you want test with older version of ECF, use the examples stored into ecf_3.0.0 of the zip that you can find on [https://bugs.eclipse.org/bugs/show_bug.cgi?id=302113 Bug 302113].
  
When you want use Remote Services with ECF on Consumer bundle (aka client side) and Host buundle (aka server side) you must :
+
==Using ECF's OSGi Remote Services Implementation==
  
<ol>
+
There are two roles in OSGi Remote Services:  the '''host''' (aka the service exporter/publisher), and the '''consumer''' (aka the client/service consumer).
  <li>'''Create an ECF IContainer''' with a type (eg : "ecf.generic.client" for Consumer and "ecf.generic.server" for Host).</li>
+
  <li>'''Publish (for Host)/Retrieve (for Consumer) services''' by using OSGi services registry.</li>
+
</ol>
+
  
You can manage that with several means :
+
The '''host''' is responsible for '''exporting/publishing''' the remote service, and the '''consumer''' is responsible for using or '''consuming''' the service.
  
<ul>
+
With ECF's OSGi Remote Services standard implementation, you can manage the ''''host''' and '''consumer''' via several means:  
  <li>use standard [[#ECF with Java code|OSGi Java code]]</li>
+
  <li>use OSGi Declarative Services (DS)</li>
+
  <li>use [[#ECF with Spring DM|Spring Dynamic Module]].</li>
+
</ul>
+
 
+
With Spring Dynamic Module mean :  
+
  
 
<ul>
 
<ul>
   <li>the Publish/Retrieve services from OSGi service registry is managed by Spring DM by using '''<osgi:service''' and '''<osgi:reference'''.</li>
+
   <li>Standard [[#ECF with Java code|OSGi Standard Java code]]</li>
   <li>the creation of ECF IContainer can be managed too with Spring by using [[#ECF Spring support|ECF Spring support]].</li>
+
  <li>OSGi Declarative Services (DS)</li>
 +
   <li>[[#Remote Services with Spring DM|Spring DM]].</li>
 
</ul>
 
</ul>
  
To explain ECF with Spring Dynamic Module we will use the Hello example which publish/retrieve a basic service IHello. The sample code is bases on last version of ECF 3.2.
+
[[Getting_Started_with_ECF's_OSGi_Remote_Services_Implementation | Here is a page]] that describes how to use standard Java code to export (host) and consume (consumer) a simple example service. Another example with Java is given below.
  
=== ECF with Java code ===
+
==Using Remote Services via Java Code==
  
You can found Hello example with OSGi Java code into :
+
To describe what the Spring DM implementation is doing (described [[#Remote Services with Spring DM  | below]], it's instructive to first describe what happens when OSGi Remote Services are exported programatically...i.e. via Java code. This section briefly shows how to export a remote service via OSGi standard Remote Services, and how to consume that same remote service via the OSGi ServiceTracker.
 
+
<ul>
+
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.host''' : host bundle which publish the Hello service implémentation with an ECF IContainer type of "ecf.generic.server".
+
  </li>
+
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.consumer''' : consumer bundle which call one time the service IHello by using an ECF IContainer type of "ecf.generic.client".
+
  </li>
+
</ul>
+
  
 
[[Image:ECFRemotingServicesWithJavaCode.png]]
 
[[Image:ECFRemotingServicesWithJavaCode.png]]
  
This scheme show you that :
+
This scheme shows:
  
 
<ul>
 
<ul>
   <li>the Host bundle create the ECF IContainer and publish the services into the start method of the Bundle.
+
   <li>The '''host''' bundle creates the ECF IContainer instance(s), and exports/publishes the remote service via a single call to the OSGi BundleContext.registerService method with service properties set as specified by OSGi 4.2 Remote Services standard.  According to the Remote Services standard specification, the service properties indicate that the service being registered should be exported.
   <li>the Consumer bundle create the ECF IContainer and create an OSGi ServiceTracker to track the IHello service into the start method of the Bundle.
+
   <li>The '''consumer''' bundle creates the ECF IContainer instance, and create an OSGi ServiceTracker to track the IHello service.  With network-based discovery (i.e. ECF discovery), the ServiceTracker is asynchronously notified when the remote service is discovered.
 
</ul>
 
</ul>
  
==== Host ====
+
===Exporting a Remote Service===
 
+
Host bundle :
+
  
 
<ul>
 
<ul>
   <li>create an IContainer with Java code. Into ECF 3.2 the Icontainer is created lazily (Scott could you confirm that?).
+
   <li>Create an IContainer instance. NOTE:  In ECF 3.2's OSGi Remote Service implementation, it is '''OPTIONAL''' to do this step...as the IContainer instance will be created lazily by ECF's implementation.
 
</li>
 
</li>
   <li>publish the service into OSGi services registry :  
+
   <li>Export the service via the OSGi service registry:  
 
<source lang="java" >// Setup properties for remote service distribution, as per OSGi 4.2 remote services
 
<source lang="java" >// Setup properties for remote service distribution, as per OSGi 4.2 remote services
 
   // specification (chap 13 in compendium spec)
 
   // specification (chap 13 in compendium spec)
Line 74: Line 58:
 
   // add ECF service property specifying container factory args
 
   // add ECF service property specifying container factory args
 
   props.put(IDistributionConstants.SERVICE_EXPORTED_CONTAINER_FACTORY_ARGUMENTS, containerId);
 
   props.put(IDistributionConstants.SERVICE_EXPORTED_CONTAINER_FACTORY_ARGUMENTS, containerId);
   // register remote service
+
   // register/publish remote service
 
   helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);</source>
 
   helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);</source>
  
Here the same code whith value of constantes :  
+
Here the same code with the value of the constants replaced:  
  
 
<source lang="java" >// Setup properties for remote service distribution, as per OSGi 4.2 remote services
 
<source lang="java" >// Setup properties for remote service distribution, as per OSGi 4.2 remote services
Line 88: Line 72:
 
   // add ECF service property specifying container factory args
 
   // add ECF service property specifying container factory args
 
   props.put("org.eclipse.ecf.containerFactoryArgs", "ecftcp://localhost:3787/server");
 
   props.put("org.eclipse.ecf.containerFactoryArgs", "ecftcp://localhost:3787/server");
   // register remote service
+
   // register/publish remote service
 
   helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);</source>
 
   helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);</source>
 
   </li>
 
   </li>
 
</ul>
 
</ul>
  
==== Consumer ====
+
===Consuming a Remote Service===
 
+
Consumer bundle :
+
  
 
<ul>
 
<ul>
   <li>create an ECF IContainer with Java code :  
+
   <li>Create an ECF IContainer instance with Java code such as the following:  
  
 
<source lang="java" >
 
<source lang="java" >
Line 114: Line 96:
  
 
</li>
 
</li>
   <li>Retrieve the services with OSGi ServiceTracker :  
+
   <li>Consume the remote service with OSGi ServiceTracker:  
 
<source lang="java" >// Create service tracker to track IHello instances that have the 'service.imported'
 
<source lang="java" >// Create service tracker to track IHello instances that have the 'service.imported'
 
   // property set (as defined by OSGi 4.2 remote services spec).
 
   // property set (as defined by OSGi 4.2 remote services spec).
Line 141: Line 123:
 
</source>
 
</source>
  
Here the same code of creation of OSGi Filter with constant value :  
+
Here the same code of creation of OSGi Filter with constant value:  
  
 
<source lang="java" >private Filter createRemoteFilter() throws InvalidSyntaxException {
 
<source lang="java" >private Filter createRemoteFilter() throws InvalidSyntaxException {
Line 149: Line 131:
 
</ul>
 
</ul>
  
=== ECF with Spring DM ===
+
==Remote Services with Spring DM==
  
You can found Hello example with Spring DM into :  
+
The Spring DM example code is found in these two projects/bundles:
  
 
<ul>
 
<ul>
   <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.host''' : host bundle which publish the Hello service implémentation with an ECF IContainer type of ecf.generic.server".
+
   <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.host''': host bundle -- which exports the Hello service implementation with ECF IContainer type "ecf.generic.server".
 
   </li>
 
   </li>
   <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.consumer''' : consumer bundle which create a Thread HelloClientThread and call the service IHello every second by using an ECF IContainer type of ecf.generic.client".
+
   <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.consumer''': consumer bundle -- which creates a Thread HelloClientThread, and calls the service IHello every second by using an ECF IContainer type of "ecf.generic.client".
 
   </li>
 
   </li>
 
</ul>
 
</ul>
  
Here a scheme which explains how ECF works with Spring DM :  
+
Here is a diagram showing how ECF's OSGi Remote Services implementation works with Spring DM:  
  
 
[[Image:ECFRemotingServicesWithSpringDM.png]]
 
[[Image:ECFRemotingServicesWithSpringDM.png]]
  
This scheme show you that ECF IContainer creation and Publish/retrieve services can be totally declarative by using Spring DM. Host and Consumer bundle define a XML Spring file (in this sample module-context.xml is used but you can used any name and it's better to split files for simpel bean definition and osgi definition (cf Spring DM Doc).
+
This scheme shows that ECF IContainer creation and exporting and consuming services can be done declaratively with Spring DM. Host and Consumer bundles define a XML Spring file (in this sample module-context.xml is used but you can used any name and it's better to split files for simple bean definition and osgi definition).
  
The Spring bundle Extender load each XML Spring files stored into META-INF/spring.  
+
The Spring bundle Extender load each XML Spring files stored into META-INF/Spring.  
  
 
<ul>
 
<ul>
   <li>Host bundle define module-context.xml which publish the services (with ECF 3.2 no need to create the IContainer) by using <osgi:service with classic Spring DM.
+
   <li>Host bundle define [[#Host Spring file module-context.xml|Spring file module-context.xml]] which exports the services (with ECF 3.2 no need to create the IContainer) by using <osgi:service with classic Spring DM.
   <li>Consumer bundle define module-context.xml which create the ECF Container by using ECF Spring support and retrieve the service by using <osgi:reference with classic Spring DM.
+
   <li>Consumer bundle define [[#Consumer Spring file module-context.xml|Spring file module-context.xml]] which create the ECF Container by using ECF Spring support and consume the service by using <osgi:reference with classic Spring DM.
 
</ul>
 
</ul>
  
The Consumer module-conext.xml define a Spring bean which create and start a Thread which use the service IHello getted. The IHello service is filled to this Thread by using Spring Dependency Injection. Here the cod eof this Thread :  
+
The [[#Consumer Spring file module-context.xml|Consumer Spring file module-context.xml]] define a Spring bean which create and start a Thread which use the service IHello getted. The IHello service is filled to this Thread by using Spring Dependency Injection. Here the code for this Thread to test the actual calling of the remote IHello service:  
  
 
<source lang="java" >package org.eclipse.ecf.examples.internal.remoteservices.hello.dm.consumer;
 
<source lang="java" >package org.eclipse.ecf.examples.internal.remoteservices.hello.dm.consumer;
Line 201: Line 183:
 
}</source>
 
}</source>
  
When you will launch this consumer you will see into the console th eerror :  
+
When run, will see in the console:  
  
 
<source lang="text" >org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(&(objectClass=org.eclipse.ecf.examples.remoteservices.hello.IHello)(service.imported=*))] unavailable
 
<source lang="text" >org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(&(objectClass=org.eclipse.ecf.examples.remoteservices.hello.IHello)(service.imported=*))] unavailable
Line 207: Line 189:
 
</source>
 
</source>
  
which mean Consumer is searching IHello service from the OSGi services registry and once the service can be getted, teh console display each seconde :  
+
which means that the Consumer is searching IHello service from the OSGi services registry.  Once the service is discovered and can be accessed, the console will display each second:  
  
 
<source lang="text" >IHello service called with HelloClientThread (Spring DM).</source>
 
<source lang="text" >IHello service called with HelloClientThread (Spring DM).</source>
  
==== Host ====
+
===Using Spring DM on Host===
  
 
<ul>
 
<ul>
   <li>Create an ECF (server) IContainer with declarative mean by using [[#ECF Spring support |ECF Spring support]] :  
+
   <li>Create an ECF IContainer server instance declaratively by using [[#ECF Spring support |ECF Spring support]]:  
  
 
<source lang="xml"><bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
 
<source lang="xml"><bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
Line 220: Line 202:
 
</bean></source>
 
</bean></source>
  
Into ECF 3.2, this declaration is NOT required.
+
In ECF 3.2's OSGi Remote Service implementation, this declaration is NOT required/optional as described above.  The ECF implementation will lazily create the "ecf.generic.server" instance lazily.
  
 
   </li>
 
   </li>
   <li>Publish you services with declarative mean by using Spring Dynamic Module :  
+
   <li>Export your remote service declaratively with Spring DM:  
  
 
<source lang="xml" ><bean id="helloService" class="org.eclipse.ecf.examples.remoteservices.hello.impl.Hello" />
 
<source lang="xml" ><bean id="helloService" class="org.eclipse.ecf.examples.remoteservices.hello.impl.Hello" />
Line 239: Line 221:
 
</ul>
 
</ul>
  
Here the full XML file spring module-context.xml :  
+
====Host Spring file module-context.xml====
 +
 
 +
Here the full XML file spring module-context.xml:  
  
 
<source lang="xml"><?xml version="1.0" encoding="UTF-8"?>
 
<source lang="xml"><?xml version="1.0" encoding="UTF-8"?>
Line 268: Line 252:
 
</beans></source>
 
</beans></source>
  
==== Consumer ====
+
===Using Spring DM on Consumer===
  
 
<ul>
 
<ul>
   <li>Create an ECF (client) IContainer with declarative mean by using [[#ECF Spring support |ECF Spring support]] :  
+
   <li>Create an ECF IContainer client instance declaratively via Spring [[#ECF Spring support |ECF Spring support]]:  
  
 
<source lang="xml"><bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
 
<source lang="xml"><bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
Line 284: Line 268:
 
</source>
 
</source>
 
   </li>
 
   </li>
   <li>Inject the service to the Thread HelloClientHread and start the Thread :  
+
   <li>Inject the service to the Thread HelloClientHread and start the Thread:  
  
 
<source lang="xml"><bean id="helloClient"
 
<source lang="xml"><bean id="helloClient"
Line 297: Line 281:
 
Note you have '''cardinality="0..1"''' defined into <osgi:reference. this attribute is very important. Indead by default '''cardinality="1..1"''' and it means that the service MUST be retrieved. When you start the consumer bundle the service can be retrieved the first time and if you set not the cardinality to "0..1", the bean HelloClientThread which use this service can be NOT created.   
 
Note you have '''cardinality="0..1"''' defined into <osgi:reference. this attribute is very important. Indead by default '''cardinality="1..1"''' and it means that the service MUST be retrieved. When you start the consumer bundle the service can be retrieved the first time and if you set not the cardinality to "0..1", the bean HelloClientThread which use this service can be NOT created.   
  
Here the full XML file spring module-context.xml :  
+
====Consumer Spring file module-context.xml====
 +
 
 +
Here the full XML file spring module-context.xml:  
  
 
<source lang="xml" ><?xml version="1.0" encoding="UTF-8"?>
 
<source lang="xml" ><?xml version="1.0" encoding="UTF-8"?>
Line 326: Line 312:
 
</beans></source>
 
</beans></source>
  
== ECF Spring support ==  
+
===Getting and Using the ECF/Spring Integration Bundle===  
  
ECF provides a bundle '''org.eclipse.ecf.springframework''' which is a support for Spring to manage :
+
ECF provides a very small and simple bundle '''org.eclipse.ecf.springframework''' which is a support for Spring to manage:
  
 
<ul>
 
<ul>
Line 339: Line 325:
 
</ul>
 
</ul>
  
With ECF 3.2 you can NOT use this support.
+
This bundle is now available in the ECF incubation area.  In anonymous CVS, it can be accessed here
 +
 
 +
protocol:  '''pserver'''<br>
 +
host:  '''dev.eclipse.org'''<br>
 +
path:  '''/cvsroot/rt'''<br>
 +
Eclipse repository:  ''':pserver:anonymous@dev.eclipse.org:/cvsroot/rt'''<br>
 +
module:  '''org.eclipse.ecf/incubation/bundles/org.eclipse.ecf.springframework'''<br>
 +
 
 +
'''NOTE:  This project is currently in incubation, and so is not distributed as part of ECF's upcoming 3.2 release (Feb 19, 2010).  We expect to include this work in our Helios/3.3 release, however.'''
 +
 
 +
'''NOTE:  The ECF project is working with the propose [http://www.eclipse.org/proposals/virgo/ Virgo project], to provide integration between ECF's support for OSGi 4.2 Remote Services and Virgo.  The work described on this page will very likely be done in concert with the Virgo team.'''
 +
 
 +
Early/initial documentation of the contents of this project follows:
  
=== *ContainerFactoryBean ===
+
====ContainerFactoryBean====
  
==== HostContainerFactoryBean ====
+
====HostContainerFactoryBean====
  
 
HostContainerFactoryBean is Spring factory bean to create an ECF IContainer on server side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.server"
 
HostContainerFactoryBean is Spring factory bean to create an ECF IContainer on server side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.server"
Line 351: Line 349:
 
</bean></source>
 
</bean></source>
  
This déclaration is the same thing like :  
+
This déclaration is the same thing like:  
  
 
<source lang="java" >ContainerFactory.getDefault().createContainer("ecf.generic.server");</source>
 
<source lang="java" >ContainerFactory.getDefault().createContainer("ecf.generic.server");</source>
  
The ECF IContainerFactory can be retrieved from OSGi services regisrty. With Java, you write this code :  
+
=====containerFactory parameter=====
 +
 
 +
The ECF IContainerFactory can be retrieved from OSGi services regisrty. With Java, you write this code:  
  
 
<source lang="java" >IContainerFactory containerFactory = getContainerFactoryByUsingServiceTracker();
 
<source lang="java" >IContainerFactory containerFactory = getContainerFactoryByUsingServiceTracker();
 
containerFactory.createContainer("ecf.generic.server");</source>
 
containerFactory.createContainer("ecf.generic.server");</source>
  
You can manage that with XML Spring declaration like this :  
+
You can manage that with XML Spring declaration like this:  
  
 
<source lang="xml" ><osgi:reference id="containerFactory"
 
<source lang="xml" ><osgi:reference id="containerFactory"
Line 370: Line 370:
 
</bean></source>
 
</bean></source>
  
You can use too the IContainerManager to create a factory into Java :  
+
=====containerManager parameter=====
 +
 
 +
You can use too the IContainerManager to create a factory into Java:  
  
 
<source lang="java" >IContainerManager containerManager = getContainerManagerByUsingServiceTracker();
 
<source lang="java" >IContainerManager containerManager = getContainerManagerByUsingServiceTracker();
Line 376: Line 378:
 
containerFactory.createContainer("ecf.generic.server");</source>
 
containerFactory.createContainer("ecf.generic.server");</source>
  
You can manage that with XML Spring declaration like this :  
+
You can manage that with XML Spring declaration like this:  
  
 
<source lang="xml" ><osgi:reference id="containerManager"
 
<source lang="xml" ><osgi:reference id="containerManager"
Line 386: Line 388:
 
</bean></source>
 
</bean></source>
  
==== ConsumerContainerFactoryBean ====
+
=====containerId parameter=====
 +
 
 +
ECF ID can be used to set the URL server where the client must be connected. Here the java code used to set the server URL at "ecftcp://localhost:3787/server":
 +
 
 +
<source lang="java" >ID containerID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
 +
IContainer container = ContainerFactory.getDefault().createContainer("ecf.generic.server", containerID);</source>
 +
 
 +
You can manage that with XML Spring declaration like this:
 +
 
 +
<source lang="xml" ><bean id="containerId"
 +
  class="org.eclipse.ecf.springframework.identity.StringIDFactoryBean">
 +
  <property name="stringID" value="ecftcp://localhost:3787/server" />
 +
</bean>
 +
 
 +
<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
 +
  <property name="containerType" value="ecf.generic.server" />
 +
  <property name="containerId" ref="containerId" />
 +
</bean></source>
 +
 
 +
====ConsumerContainerFactoryBean====
  
 
ConsumerContainerFactoryBean is Spring factory bean to create an ECF IContainer on client side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.client"
 
ConsumerContainerFactoryBean is Spring factory bean to create an ECF IContainer on client side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.client"
Line 396: Line 417:
 
You can too set the IContainerFactory or the IContainerManager retrieved by OSGi services registry like [[#HostContainerFactoryBean |HostContainerFactoryBean ]].
 
You can too set the IContainerFactory or the IContainerManager retrieved by OSGi services registry like [[#HostContainerFactoryBean |HostContainerFactoryBean ]].
  
ECF ID can be used to set the URL server where the client must be connected. Here teh java code used to set the server URL at "ecftcp://localhost:3787/server" :  
+
=====targetId parameter=====
 +
 
 +
ECF ID can be used to set the URL server where the client must be connected. Here teh java code used to set the server URL at "ecftcp://localhost:3787/server":  
  
 
<source lang="java" >ID targetID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
 
<source lang="java" >ID targetID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
Line 414: Line 437:
 
</bean></source>
 
</bean></source>
  
=== *IDFactoryBean ===
+
====IDFactoryBean====
  
==== StringIDFactoryBean ====
+
====StringIDFactoryBean====
  
StringIDFactoryBean is Spring factory bean to create an ECF String ID. Here the XML bean declaration to create an ECF String ID with value ecftcp://localhost:3787/server" :  
+
StringIDFactoryBean is Spring factory bean to create an ECF String ID. Here the XML bean declaration to create an ECF String ID with value ecftcp://localhost:3787/server":  
  
 
<source lang="xml" ><bean id="containerId"
 
<source lang="xml" ><bean id="containerId"
Line 425: Line 448:
 
</bean></source>
 
</bean></source>
  
This déclaration is the same thing like :  
+
This déclaration is the same thing like:  
  
 
<source lang="java" >ID stringID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");</source>
 
<source lang="java" >ID stringID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");</source>
  
The ECF IIDFactory can be retrieved from OSGi services regisrty. With Java, you write this code :  
+
=====idFactory parameter=====
 +
 
 +
The ECF IIDFactory can be retrieved from OSGi services regisrty. With Java, you can code like this:  
  
 
NOT SURE FOR THAT!!!
 
NOT SURE FOR THAT!!!
Line 436: Line 461:
 
idFactory.createStringID("ecftcp://localhost:3787/server");</source>
 
idFactory.createStringID("ecftcp://localhost:3787/server");</source>
  
You can manage that with XML Spring declaration like this :  
+
You can manage that with XML Spring declaration like this:  
  
 
<source lang="xml" ><osgi:reference id="idFactory"
 
<source lang="xml" ><osgi:reference id="idFactory"
Line 447: Line 472:
 
</bean></source>
 
</bean></source>
  
==== LongIDFactoryBean ====
+
====LongIDFactoryBean====
  
Exist but NOT tested. TODO create another *IDFactoryBean.
+
Exist but NOT tested. TODO: create another IDFactoryBean.
  
=== ConnectContextFactoryBean ===
+
Example Usage: TODO
 +
 
 +
====ConnectContextFactoryBean====
  
 
ConnectContextFactoryBean is Spring factory bean to create an ECF IConnectContext.  
 
ConnectContextFactoryBean is Spring factory bean to create an ECF IConnectContext.  
  
DONE but I don't know how it works into ECF. Scott could you set a sample please with Java code (I will done with Spring DM if you want)?
+
Example Usage: TODO
 +
 
 +
===Creation of Launch/Product===
 +
 
 +
Launch (Eclipse Application or OSGi Framework) is used to start your Host and Consumer Bundle. With launch, you can configre the bundles that you want start and configure it (start-level, auto-start...). Into DM example you have products (wgich generate launch) that you can use to start Host/Consumer bundles.
 +
 
 +
If you wish use ECF with Spring into Host/Consumer you must :
 +
<ul>
 +
  <li>add [[#Product/Dependencies|required dependencies]] like Spring DM and ECF dependencies (and other like your API services, log4j configuration....)
 +
  </li>
 +
  <li>[[#Product/Configuration|configure]] several bundles to '''auto-start to true'''.
 +
  </li>
 +
</ul>
 +
 
 +
====Product/Dependencies====
 +
 
 +
SCOT COULD YOU EXPLAIN EACH BUNDLE OF ECF (discovery, ssl....)???
 +
[[Image:ECFRemotingServicesHostDependenciesProduct.png]]
 +
 
 +
====Product/Configuration====
 +
 
 +
Here a screenshot of the Configuration tab of the product "Hello Service DM Host (generic).product" from the bundle Host org.eclipse.ecf.examples.remoteservices.hello.dm.host :
 +
 
 +
[[Image:ECFRemotingServicesHostConfigurationProduct.png‎]]
 +
 
 +
As you can see, you must set the auto-start to true for 3 bundles :
 +
 
 +
<ul>
 +
  <li>'''org.eclipse.ecf.examples.remoteservices.hello.dm.host''' which is the bundle which publish/export the implementation of the services.
 +
  </li>
 +
  <li>'''org.eclipse.ecf.osgi.services.distribution''' : SCOTT COULD YOU EXPLAIN THE GOAL OF THIS BUNDLE PLEASE??? THANK A LOT.</li>
 +
  <li>'''org.springframework.osgi.extender''' which is the Spring Extender Bundle which detect for each bundles if it contains XML Spring files and load it. It's adwice to start this bunlde before others bundles. To manage that you can for instance set the start-level to 3.</li>
 +
</ul>
 +
 
 +
This "recipe" must be followed too for the Consumer bundle :
 +
 
 +
[[Image:ECFRemotingServicesConsumerConfigurationProduct.PNG]]

Latest revision as of 06:59, 13 February 2010

Introduction

Work is underway to integrate ECF's OSGi 4.2 Remote Services with Spring Dynamic Module so that it's easy to declare your OSGi Remote Services rather than exporting and consuming them programmatically. This work represents an integration and collaboration between the ECF project and the (proposed) Virgo project.

See (for the moment) Bug 302113. This bug is being used to track the contribution to ECF for this work. Attached to this bug are zips containing bundles

  • org.eclipse.ecf.examples.remoteservices.hello.dm.config.log4j: fragment to configure log4j required by Spring Extender bundle..
  • org.eclipse.ecf.examples.remoteservices.hello.dm.consumer: bundle of Consumer Hello sample managed with Spring DM.
  • org.eclipse.ecf.examples.remoteservices.hello.dm.host: bundle of Host Hello sample managed with Spring DM.
  • org.eclipse.ecf.springframework : bundle of ECF Spring support.

These samples work with ECF 3.2, which is scheduled for release on Feb 19, 2010. If you want test with older version of ECF, use the examples stored into ecf_3.0.0 of the zip that you can find on Bug 302113.

Using ECF's OSGi Remote Services Implementation

There are two roles in OSGi Remote Services: the host (aka the service exporter/publisher), and the consumer (aka the client/service consumer).

The host is responsible for exporting/publishing the remote service, and the consumer is responsible for using or consuming the service.

With ECF's OSGi Remote Services standard implementation, you can manage the 'host and consumer via several means:

Here is a page that describes how to use standard Java code to export (host) and consume (consumer) a simple example service. Another example with Java is given below.

Using Remote Services via Java Code

To describe what the Spring DM implementation is doing (described below, it's instructive to first describe what happens when OSGi Remote Services are exported programatically...i.e. via Java code. This section briefly shows how to export a remote service via OSGi standard Remote Services, and how to consume that same remote service via the OSGi ServiceTracker.

ECFRemotingServicesWithJavaCode.png

This scheme shows:

  • The host bundle creates the ECF IContainer instance(s), and exports/publishes the remote service via a single call to the OSGi BundleContext.registerService method with service properties set as specified by OSGi 4.2 Remote Services standard. According to the Remote Services standard specification, the service properties indicate that the service being registered should be exported.
  • The consumer bundle creates the ECF IContainer instance, and create an OSGi ServiceTracker to track the IHello service. With network-based discovery (i.e. ECF discovery), the ServiceTracker is asynchronously notified when the remote service is discovered.

Exporting a Remote Service

  • Create an IContainer instance. NOTE: In ECF 3.2's OSGi Remote Service implementation, it is OPTIONAL to do this step...as the IContainer instance will be created lazily by ECF's implementation.
  • Export the service via the OSGi service registry:
    // Setup properties for remote service distribution, as per OSGi 4.2 remote services
      // specification (chap 13 in compendium spec)
      Properties props = new Properties();
      // add OSGi service property indicated export of all interfaces exposed by service (wildcard)
      props.put(IDistributionConstants.SERVICE_EXPORTED_INTERFACES, IDistributionConstants.SERVICE_EXPORTED_INTERFACES_WILDCARD);
      // add OSGi service property specifying config
      props.put(IDistributionConstants.SERVICE_EXPORTED_CONFIGS, containerType);
      // add ECF service property specifying container factory args
      props.put(IDistributionConstants.SERVICE_EXPORTED_CONTAINER_FACTORY_ARGUMENTS, containerId);
      // register/publish remote service
      helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);

    Here the same code with the value of the constants replaced:

    // Setup properties for remote service distribution, as per OSGi 4.2 remote services
      // specification (chap 13 in compendium spec)
      Properties props = new Properties();
      // add OSGi service property indicated export of all interfaces exposed by service (wildcard)
      props.put("service.exported.interfaces", "*");
      // add OSGi service property specifying config
      props.put("service.exported.configs", "ecf.generic.server");
      // add ECF service property specifying container factory args
      props.put("org.eclipse.ecf.containerFactoryArgs", "ecftcp://localhost:3787/server");
      // register/publish remote service
      helloRegistration = bundleContext.registerService(IHello.class.getName(), new Hello(), props);

Consuming a Remote Service

  • Create an ECF IContainer instance with Java code such as the following:
    getContainerFactory().createContainer("ecf.generic.client");
    ...
     
    private IContainerFactory getContainerFactory() {
      if (containerFactoryServiceTracker == null) {
        containerFactoryServiceTracker = new ServiceTracker(bundleContext, IContainerFactory.class.getName(), null);
        containerFactoryServiceTracker.open();
      }
      return (IContainerFactory) containerFactoryServiceTracker.getService();
    }
  • Consume the remote service with OSGi ServiceTracker:
    // Create service tracker to track IHello instances that have the 'service.imported'
      // property set (as defined by OSGi 4.2 remote services spec).
      helloServiceTracker = new ServiceTracker(bundleContext, createRemoteFilter(), this);
      helloServiceTracker.open();
      ...
     
      private Filter createRemoteFilter() throws InvalidSyntaxException {
        // This filter looks for IHello instances that have the 
        // 'service.imported' property set, as specified by OSGi 4.2
        // remote services spec (Chapter 13)
        return bundleContext.createFilter("(&(" + org.osgi.framework.Constants.OBJECTCLASS + "=" + IHello.class.getName() + ")(" + SERVICE_IMPORTED + "=*))");
      }
      ...
     
      public Object addingService(ServiceReference reference) {
    		System.out.println("IHello service proxy being added");
    		// Since this reference is for a remote service,
    		// The service object returned is a proxy implementing the
    		// IHello interface
    		IHello hello = (IHello) bundleContext.getService(reference);
    		// This makes a remote 'hello' call
    		hello.hello(CONSUMER_NAME);
       ...
       }

    Here the same code of creation of OSGi Filter with constant value:

    private Filter createRemoteFilter() throws InvalidSyntaxException {
      return bundleContext.createFilter("(&(objectClass=org.eclipse.ecf.examples.remoteservices.hello.IHello)(service.imported=*))");

Remote Services with Spring DM

The Spring DM example code is found in these two projects/bundles:

  • org.eclipse.ecf.examples.remoteservices.hello.dm.host: host bundle -- which exports the Hello service implementation with ECF IContainer type "ecf.generic.server".
  • org.eclipse.ecf.examples.remoteservices.hello.dm.consumer: consumer bundle -- which creates a Thread HelloClientThread, and calls the service IHello every second by using an ECF IContainer type of "ecf.generic.client".

Here is a diagram showing how ECF's OSGi Remote Services implementation works with Spring DM:

ECFRemotingServicesWithSpringDM.png

This scheme shows that ECF IContainer creation and exporting and consuming services can be done declaratively with Spring DM. Host and Consumer bundles define a XML Spring file (in this sample module-context.xml is used but you can used any name and it's better to split files for simple bean definition and osgi definition).

The Spring bundle Extender load each XML Spring files stored into META-INF/Spring.

  • Host bundle define Spring file module-context.xml which exports the services (with ECF 3.2 no need to create the IContainer) by using <osgi:service with classic Spring DM.
  • Consumer bundle define Spring file module-context.xml which create the ECF Container by using ECF Spring support and consume the service by using <osgi:reference with classic Spring DM.

The Consumer Spring file module-context.xml define a Spring bean which create and start a Thread which use the service IHello getted. The IHello service is filled to this Thread by using Spring Dependency Injection. Here the code for this Thread to test the actual calling of the remote IHello service:

package org.eclipse.ecf.examples.internal.remoteservices.hello.dm.consumer;
 
import org.eclipse.ecf.examples.remoteservices.hello.IHello;
 
public class HelloClientThread extends Thread {
 
  private IHello hello;
 
  public void setHello(IHello hello) {
    this.hello = hello;
  }
 
  @Override
  public void run() {
    while (true) {
      try {
        hello.hello("HelloClientThread (Spring DM)");
	System.out.println("IHello service called with HelloClientThread (Spring DM).");
        Thread.sleep(1000);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

When run, will see in the console:

org.springframework.osgi.service.ServiceUnavailableException: service matching filter=[(&(objectClass=org.eclipse.ecf.examples.remoteservices.hello.IHello)(service.imported=*))] unavailable
	at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:419)

which means that the Consumer is searching IHello service from the OSGi services registry. Once the service is discovered and can be accessed, the console will display each second:

IHello service called with HelloClientThread (Spring DM).

Using Spring DM on Host

  • Create an ECF IContainer server instance declaratively by using ECF Spring support:
    <bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
    	<property name="containerType" value="ecf.generic.server" />
    </bean>

    In ECF 3.2's OSGi Remote Service implementation, this declaration is NOT required/optional as described above. The ECF implementation will lazily create the "ecf.generic.server" instance lazily.

  • Export your remote service declaratively with Spring DM:
    <bean id="helloService" class="org.eclipse.ecf.examples.remoteservices.hello.impl.Hello" />
     
    <osgi:service ref="helloService"
    	interface="org.eclipse.ecf.examples.remoteservices.hello.IHello">
    	<osgi:service-properties>
    		<entry key="service.exported.interfaces" value="*" />
    		<entry key="service.exported.configs" value="ecf.generic.server" />
                    <entry key="org.eclipse.ecf.containerFactoryArgs" value="ecftcp://localhost:3787/server" />
    	</osgi:service-properties>
    </osgi:service>

Host Spring file module-context.xml

Here the full XML file spring module-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" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/osgi  
       http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
        <!-- 1. Create an ECF (server) IContainer -->
	<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
		<property name="containerType" value="ecf.generic.server" />
	</bean>
 
	<!-- 2. Publish Hello Service implementation -->
	<bean id="helloService" class="org.eclipse.ecf.examples.remoteservices.hello.impl.Hello" />
 
	<osgi:service ref="helloService"
		interface="org.eclipse.ecf.examples.remoteservices.hello.IHello">
		<osgi:service-properties>
			<entry key="service.exported.interfaces" value="*" />
			<entry key="service.exported.configs" value="ecf.generic.server" />
			<entry key="org.eclipse.ecf.containerFactoryArgs" value="ecftcp://localhost:3787/server" />
		</osgi:service-properties>
	</osgi:service>
 
</beans>

Using Spring DM on Consumer

  • Create an ECF IContainer client instance declaratively via Spring ECF Spring support:
    <bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
    	<property name="containerType" value="ecf.generic.client" />
    </bean>
  • Retrieve the service with declarative mean by using Spring Dynamic Module :
    <osgi:reference id="helloService"
    	interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"
    	timeout="1000" cardinality="0..1" filter="(service.imported=*)" />
  • Inject the service to the Thread HelloClientHread and start the Thread:
    <bean id="helloClient"
      class="org.eclipse.ecf.examples.internal.remoteservices.hello.dm.consumer.HelloClientThread"
      init-method="start" destroy-method="interrupt">
      <property name="hello" ref="helloService" />
    </bean>

Note you have cardinality="0..1" defined into <osgi:reference. this attribute is very important. Indead by default cardinality="1..1" and it means that the service MUST be retrieved. When you start the consumer bundle the service can be retrieved the first time and if you set not the cardinality to "0..1", the bean HelloClientThread which use this service can be NOT created.

Consumer Spring file module-context.xml

Here the full XML file spring module-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" xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/osgi  
       http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
        <!-- 1. Create an ECF (client) IContainer -->
	<bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
		<property name="containerType" value="ecf.generic.client" />
	</bean>
 
        <!-- 2. Retrieve service from OSGi services registry -->
	<osgi:reference id="helloService"
		interface="org.eclipse.ecf.examples.remoteservices.hello.IHello"
		timeout="1000" cardinality="0..1" filter="(service.imported=*)" />
 
        <!-- 3. Create Thread HelloClientThread which call the IHello service which is retrieved from OSGI services and filled with Spring Dependency Injection-->
	<bean id="helloClient"
		class="org.eclipse.ecf.examples.internal.remoteservices.hello.dm.consumer.HelloClientThread"
		init-method="start" destroy-method="interrupt">
		<property name="hello" ref="helloService" />
	</bean>
 
</beans>

Getting and Using the ECF/Spring Integration Bundle

ECF provides a very small and simple bundle org.eclipse.ecf.springframework which is a support for Spring to manage:

This bundle is now available in the ECF incubation area. In anonymous CVS, it can be accessed here

protocol: pserver
host: dev.eclipse.org
path: /cvsroot/rt
Eclipse repository: :pserver:anonymous@dev.eclipse.org:/cvsroot/rt
module: org.eclipse.ecf/incubation/bundles/org.eclipse.ecf.springframework

NOTE: This project is currently in incubation, and so is not distributed as part of ECF's upcoming 3.2 release (Feb 19, 2010). We expect to include this work in our Helios/3.3 release, however.

NOTE: The ECF project is working with the propose Virgo project, to provide integration between ECF's support for OSGi 4.2 Remote Services and Virgo. The work described on this page will very likely be done in concert with the Virgo team.

Early/initial documentation of the contents of this project follows:

ContainerFactoryBean

HostContainerFactoryBean

HostContainerFactoryBean is Spring factory bean to create an ECF IContainer on server side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.server"

<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
  <property name="containerType" value="ecf.generic.server" />
</bean>

This déclaration is the same thing like:

ContainerFactory.getDefault().createContainer("ecf.generic.server");
containerFactory parameter

The ECF IContainerFactory can be retrieved from OSGi services regisrty. With Java, you write this code:

IContainerFactory containerFactory = getContainerFactoryByUsingServiceTracker();
containerFactory.createContainer("ecf.generic.server");

You can manage that with XML Spring declaration like this:

<osgi:reference id="containerFactory"
		interface="org.eclipse.ecf.core.IContainerFactory" timeout="1000" />
 
<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
  <property name="containerType" value="ecf.generic.server" />
  <property name="containerFactory" ref="containerFactory" />
</bean>
containerManager parameter

You can use too the IContainerManager to create a factory into Java:

IContainerManager containerManager = getContainerManagerByUsingServiceTracker();
IContainerFactory containerFactory = containerManager.getContainerFactory();
containerFactory.createContainer("ecf.generic.server");

You can manage that with XML Spring declaration like this:

<osgi:reference id="containerManager"
		interface="org.eclipse.ecf.core.IContainerManager" timeout="1000" />
 
<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
  <property name="containerType" value="ecf.generic.server" />
  <property name="containerManager" ref="containerManager" />
</bean>
containerId parameter

ECF ID can be used to set the URL server where the client must be connected. Here the java code used to set the server URL at "ecftcp://localhost:3787/server":

ID containerID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
IContainer container = ContainerFactory.getDefault().createContainer("ecf.generic.server", containerID);

You can manage that with XML Spring declaration like this:

<bean id="containerId"
  class="org.eclipse.ecf.springframework.identity.StringIDFactoryBean">
  <property name="stringID" value="ecftcp://localhost:3787/server" />
</bean>
 
<bean class="org.eclipse.ecf.springframework.HostContainerFactoryBean">
  <property name="containerType" value="ecf.generic.server" />
  <property name="containerId" ref="containerId" />
</bean>

ConsumerContainerFactoryBean

ConsumerContainerFactoryBean is Spring factory bean to create an ECF IContainer on client side. Here the XML bean declaration to create an ECF IContainer with type "ecf.generic.client"

<bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
  <property name="containerType" value="ecf.generic.client" />
</bean>

You can too set the IContainerFactory or the IContainerManager retrieved by OSGi services registry like HostContainerFactoryBean .

targetId parameter

ECF ID can be used to set the URL server where the client must be connected. Here teh java code used to set the server URL at "ecftcp://localhost:3787/server":

ID targetID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
IContainer container = ContainerFactory.getDefault().createContainer("ecf.generic.client");
container.connect(targetID ,null);

You can manage that with XML Spring declaration like this :

<bean id="targetId"
  class="org.eclipse.ecf.springframework.identity.StringIDFactoryBean">
  <property name="stringID" value="ecftcp://localhost:3787/server" />
</bean>
 
<bean class="org.eclipse.ecf.springframework.ConsumerContainerFactoryBean">
  <property name="containerType" value="ecf.generic.client" />
  <property name="targetId" ref="targetId" />
</bean>

IDFactoryBean

StringIDFactoryBean

StringIDFactoryBean is Spring factory bean to create an ECF String ID. Here the XML bean declaration to create an ECF String ID with value ecftcp://localhost:3787/server":

<bean id="containerId"
  class="org.eclipse.ecf.springframework.identity.StringIDFactoryBean">
  <property name="stringID" value="ecftcp://localhost:3787/server" />
</bean>

This déclaration is the same thing like:

ID stringID = IDFactory.getDefault().createStringID("ecftcp://localhost:3787/server");
idFactory parameter

The ECF IIDFactory can be retrieved from OSGi services regisrty. With Java, you can code like this:

NOT SURE FOR THAT!!!

IIDFactory idFactory = getIDFactoryByUsingServiceTracker();
idFactory.createStringID("ecftcp://localhost:3787/server");

You can manage that with XML Spring declaration like this:

<osgi:reference id="idFactory"
		interface="org.eclipse.ecf.core.IIDFactory" timeout="1000" />
 
<bean id="containerId"
  class="org.eclipse.ecf.springframework.identity.StringIDFactoryBean">
  <property name="stringID" value="ecftcp://localhost:3787/server" />
  <property name="idFactory" ref="idFactory" />
</bean>

LongIDFactoryBean

Exist but NOT tested. TODO: create another IDFactoryBean.

Example Usage: TODO

ConnectContextFactoryBean

ConnectContextFactoryBean is Spring factory bean to create an ECF IConnectContext.

Example Usage: TODO

Creation of Launch/Product

Launch (Eclipse Application or OSGi Framework) is used to start your Host and Consumer Bundle. With launch, you can configre the bundles that you want start and configure it (start-level, auto-start...). Into DM example you have products (wgich generate launch) that you can use to start Host/Consumer bundles.

If you wish use ECF with Spring into Host/Consumer you must :

  • add required dependencies like Spring DM and ECF dependencies (and other like your API services, log4j configuration....)
  • configure several bundles to auto-start to true.

Product/Dependencies

SCOT COULD YOU EXPLAIN EACH BUNDLE OF ECF (discovery, ssl....)??? ECFRemotingServicesHostDependenciesProduct.png

Product/Configuration

Here a screenshot of the Configuration tab of the product "Hello Service DM Host (generic).product" from the bundle Host org.eclipse.ecf.examples.remoteservices.hello.dm.host :

ECFRemotingServicesHostConfigurationProduct.png

As you can see, you must set the auto-start to true for 3 bundles :

  • org.eclipse.ecf.examples.remoteservices.hello.dm.host which is the bundle which publish/export the implementation of the services.
  • org.eclipse.ecf.osgi.services.distribution : SCOTT COULD YOU EXPLAIN THE GOAL OF THIS BUNDLE PLEASE??? THANK A LOT.
  • org.springframework.osgi.extender which is the Spring Extender Bundle which detect for each bundles if it contains XML Spring files and load it. It's adwice to start this bunlde before others bundles. To manage that you can for instance set the start-level to 3.

This "recipe" must be followed too for the Consumer bundle :

ECFRemotingServicesConsumerConfigurationProduct.PNG

Back to the top