We now have an API so the next step is to create an implementation for the Chat service. We can keep it extremely simple in this case since we’re not interested in competing with Facebook messenger or Skype. So we make a simple provider that just sends the messages to the console.
If we create a provider Bndtools project with the OSGi enRoute templates then we get the proper setup. It will creates a project with a Declarative Services component for us. To setup a provider project, make sure the name of the project ends with .provider
. In our case we will use the name osgi.enroute.examples.chat.provider
for the project.
This gives us a bundle with a component like:
package osgi.enroute.examples.chat.adapter;
import org.osgi.service.component.annotations.Component;
@Component(name = "osgi.enroute.examples.chat")
public class ChatImpl {
}
Our first task is to add the API project to our -buildpath
so we can add the Chat interface to our implementation. To extend the -buildpath
, double click on the bnd.bnd
file and select the Build
tab. You can then press the +
button or select the Source
tab and edit the -buildpath
instruction. It should look like:
-buildpath: \
osgi.enroute.base.api;version=1.0,\
osgi.enroute.examples.chat.api;version=latest
The version latest
is used because the project is in the same workspace.
To finish the implementation there are a number of things necessary.
Chat
service interfaceuser.name
The code looks then like:
package osgi.enroute.examples.chat.provider;
import org.osgi.service.component.annotations.Component;
import osgi.enroute.examples.chat.api.Chat;
import osgi.enroute.examples.chat.api.Message;
@Component(
name = "osgi.enroute.examples.chat", // CHANGE
property = "user.name=osgi"
)
public class ChatImpl implements Chat {
@Override
public boolean send(Message message) throws Exception {
System.out.printf("%s: %s%n", message.from, message.text);
return true;
}
}
Make sure to change the name of the component to your namespace.
In OSGi it is just very good practice to export any API that a bundle provides. In our case we provide the Chat API and we therefore should export it. The reason is that this is a lot more user friendly than bundles that require all kinds of dependencies that are always required and in general cannot be substituted.
Double click on the bnd.bnd
file and select the Contents
tab. Click on the +
of the Export Packages
list and add the API package.
We can now try running the Chat implementation. For this, double click the bnd.bnd
file and select the Run
tab.
If we run the provider as is then we have no diagnostic tools to see what works. And since the service is lazy by design, we won’t be able to use the debugger either. So we add the Gogo shell to make this work.
Ensure that the following requirements are listed in the Run Requirements
list:
osgi.enroute.chat.provider
— (your name of course!)org.apache.felix.gogo.shell
— Felix Gogo Shellorg.apache.felix.gogo.command
— Felix Gogo CommandsThe resolve, save, and debug. This should give you a shell:
----------------------------
Welcome to Apache Felix Gogo
g!
So let’s do a quick check if your service is alive and breathing:
g! servicereferences osgi.enroute.examples.chat.api.Chat null
000054 10 Chat
Yeah!
Obviously we should write a unit test for this class but we leave that as an exercise for the reader …
Instead, we will use Gogo, the OSGi command shell, for testing our implementation in the next chapter.