Skip to main content
Jump to: navigation, search

Using the Bndtools Remote Services Project Templates

Once you have created a Workspace using the Remote Services template, it's now possible to use Bndtools project templates to create a new remote service API project, create an implementation of this remote service, create a consumer of the remote service, and run/test the implementation and consumer.

Create a Remote Service API Project

In the new workspace there is a Remote Services API Project template to help create a Remote Service API project. To use this template, select File->New->Bnd OSGi Project

Bndtools.2.png

Select Remote Service API Project->Next

Project Name: org.example.remoteservice.api

Note: this is a suggested name for the example project, when you use this template for creating your own remote service you can specify an appropriate project/bundle/package name.

Choose Next->Finish. This will create a new project in your workspace named org.example.remoteservice.api

Create a Remote Service Impl Project

Select File->Next->Bnd OSGi Project->Remote Service Impl Project template

Project Name: org.example.remoteservice.impl

Select Next. Under Template Parameters for the apipackage parameter specify the name of the API project created above (e.g. org.example.remoteservice.api) and Next->Finish.

Create a Remote Service Consumer Project

Similar to the Impl project above, create a consumer project by selecting the Remote Service Consumer Project template.

Once all three (API, Impl, Consumer) projects are created, the workspace should look something like this

Bndtools.3.png

Create and Use Bnd Run Descriptor for Impl and Consumer

In the Package Explorer select the impl project (e.g. org.example.remoteservice.impl), and then File->New->Run Descriptor File (.bndrun). Select the ECF Generic Distribution Provider template->Next, and give an appropriate File Name...e.g. impl and Finish. Click Resolve under the Run Requirements section and then choose the Run OSGi or Debug OSGi icons in the upper right of the Resolve/Run. This should result in a Console opening and output similar to the following in the console

____________________________
Welcome to Apache Felix Gogo

g! 14:05:38.659;EXPORT_REGISTRATION;exportedSR=[org.example.remoteservice.api.ExampleRemoteService];cID=StringID[ecftcp://slewis-lenovo:54390/server];rsId=1
--Endpoint Description---
<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
  <endpoint-description>
    <property name="ecf.endpoint.id" value-type="String" value="ecftcp://slewis-lenovo:54390/server"/>
    <property name="ecf.endpoint.id.ns" value-type="String" value="org.eclipse.ecf.core.identity.StringID"/>
    <property name="ecf.endpoint.ts" value-type="Long" value="1524171938628"/>
    <property name="ecf.rsvc.id" value-type="Long" value="1"/>
    <property name="endpoint.framework.uuid" value-type="String" value="45a4a861-3487-4089-a940-be622466a7bc"/>
    <property name="endpoint.id" value-type="String" value="937b3136-0864-4e3b-bf87-0462502eb1a5"/>
    <property name="endpoint.package.version.org.example.remoteservice.api" value-type="String" value="1.0.0"/>
    <property name="endpoint.service.id" value-type="Long" value="64"/>
    <property name="objectClass" value-type="String">
      <array>
        <value>org.example.remoteservice.api.ExampleRemoteService</value>
      </array>
    </property>
    <property name="remote.configs.supported" value-type="String">
      <array>
        <value>ecf.generic.server</value>
      </array>
    </property>
    <property name="remote.intents.supported" value-type="String">
      <array>
        <value>osgi.basic</value>
        <value>osgi.async</value>
        <value>osgi.private</value>
        <value>passByValue</value>
        <value>exactlyOnce</value>
        <value>ordered</value>
      </array>
    </property>
    <property name="service.imported" value-type="String" value="true"/>
    <property name="service.imported.configs" value-type="String">
      <array>
        <value>ecf.generic.server</value>
      </array>
    </property>
    <property name="service.intents" value-type="String" value="osgi.basic"/>
  </endpoint-description>
</endpoint-descriptions>
---End Endpoint Description

This debug output indicates that the ExampleRemoteServiceImpl was exported by the ECF RSA implementation and is ready to be used by a consumer.

Consumer

Similar to the Impl described above, create a Bnd Run Descriptor for the consumer project, then resolve and Run/Debug OSGi.

If the Zeroconf discovery is enabled on your LAN, after a few seconds the following output should appear on the consumer's console

Welcome to Apache Felix Gogo

g! service responds=Hello ExampleRemoteServiceConsumer
14:08:52.185;IMPORT_REGISTRATION;importedSR=[org.example.remoteservice.api.ExampleRemoteService];cID=StringID[ecftcp://slewis-lenovo:54390/server];rsId=1
--Endpoint Description---
<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
  <endpoint-description>
    <property name="ecf.endpoint.id" value-type="String" value="ecftcp://slewis-lenovo:54390/server"/>
    <property name="ecf.endpoint.id.ns" value-type="String" value="org.eclipse.ecf.core.identity.StringID"/>
    <property name="ecf.endpoint.ts" value-type="Long" value="1524171938628"/>
    <property name="ecf.rsvc.id" value-type="Long" value="1"/>
    <property name="endpoint.framework.uuid" value-type="String" value="45a4a861-3487-4089-a940-be622466a7bc"/>
    <property name="endpoint.id" value-type="String" value="937b3136-0864-4e3b-bf87-0462502eb1a5"/>
    <property name="endpoint.package.version.org.example.remoteservice.api" value-type="String" value="1.0.0"/>
    <property name="endpoint.service.id" value-type="Long" value="64"/>
    <property name="objectClass" value-type="String">
      <array>
        <value>org.example.remoteservice.api.ExampleRemoteService</value>
      </array>
    </property>
    <property name="remote.configs.supported" value-type="String">
      <array>
        <value>ecf.generic.server</value>
      </array>
    </property>
    <property name="remote.intents.supported" value-type="String">
      <array>
        <value>osgi.basic</value>
        <value>osgi.async</value>
        <value>osgi.private</value>
        <value>passByValue</value>
        <value>exactlyOnce</value>
        <value>ordered</value>
      </array>
    </property>
    <property name="service.imported.configs" value-type="String">
      <array>
        <value>ecf.generic.client</value>
      </array>
    </property>
    <property name="service.intents" value-type="String" value="osgi.basic"/>
  </endpoint-description>
</endpoint-descriptions>
---End Endpoint Description

Note the line in the output:

g! service responds=Hello ExampleRemoteServiceConsumer

This indicates that the remote service was discovered, the endpoint description imported, and the proxy injected into the ExampleRemoteServiceConsumer. Then the ExampleRemoteServiceConsumer.activated method was called by DS, which is implemented with a call to the ExampleRemoteService.hello remote service method.

Breakpoints can be set in the Impl, and/or Consumer projects to inspect what's happening at runtime. The example code can also be refactored/renamed/modified.

Back to the top