OSGi JAX-RS and declarative bnd service

I want to port the EE application to OSGi. my application consists of business libraries, a JPA / Entities database, and REST / WS interfaces. It also has a web client.

I start by prototyping the structure and creating all the interfaces and bundles that talk to each other in OSGi. I want to use the pure specification as much as possible without any specific vendor or structure.

I use the bnd maven plugin to create manifest and declarative services. I want to make a call from my leisure resources to the OSGI service (on another bundle) using an injection, for example:

@Path("some-resources") @Component public class SomeResources{ private SomeService service = null; @Reference public void setController(SomeService service) { // <- this is never called this.service = service; } @GET @Produces(javax.ws.rs.core.MediaType.APPLICATION_XML) public Object getSomeService() { // <- called try { service.process("Hello World"); // <- Error null object } ... } 

Is it possible to annotate a resource using bnd @Component and is it possible to insert @Resource ? everything works fine, but the service is always zero.

What should be the way to declare my package for BND to make it a wab web package?

I am using maven bundle:

 <packaging>bundle</packaging> ... <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>2.3.7</version> <extensions>true</extensions> <dependencies> <dependency> <groupId>biz.aQute</groupId> <artifactId>bndlib</artifactId> <version>1.50.0</version> </dependency> </dependencies> <configuration> <supportedProjectTypes> <supportedProjectType>ejb</supportedProjectType> <supportedProjectType>war</supportedProjectType> <supportedProjectType>wab</supportedProjectType> <supportedProjectType>bundle</supportedProjectType> <supportedProjectType>jar</supportedProjectType> </supportedProjectTypes> <instructions> <_include>-osgi.bundle</_include> </instructions> </configuration> <executions> <execution> <id>bundle-manifest</id> <phase>process-classes</phase> <goals> <goal>manifest</goal> </goals> </execution> <execution> <id>bundle-install</id> <phase>install</phase> <goals> <goal>install</goal> </goals> </execution> </executions> </plugin> ... 

with bnd instructions

 Web-ContextPath: my-root-http/rest/ Service-Component: * 
+6
source share
3 answers

OSGi has a part of the specification called Remote Services. In a very short time, it works so that you can register services with special service properties and, based on the properties technologies, you must pick up your service and create an endpoint from them. This is not only about REST, but also about any technology that processes remote calls. You can find information in the OSGi Core specification in the Remote Services chapter.

Well, this is a specification, but who implements it? There are currently two large projects that I have tried. CXF DOSGi and Eclipse ECF. They offer several technologies that support the specification of remote services. CXF especially supports Jax-RS based on its implementation both on the server side and on the client side.

Since I did not want to use spring specific solutions inside OSGi, I did not use CXF at the end, but created my own solution. It is based on the Jersey and Remote Services specifications. When the OSGi Service is specified with service.exported.interfaces = * and service.exported.configs = org.everit.osgi.remote.jersey, it will create a rest endpoint along the path / rest / using the HttpService. Your kit does not have to be a wab, it can be a simple kit.

I should mention that if you provide your services through any of the remote service implementations, you should use Jax-RS annotations in the interface that your source class implements and expose your service based on that interface.

Instead of @Resource and @Component annotations inside OSGi, I suggest you use Blueprint (part of the OSGi specification), which is surprisingly similar to Spring. Apache Aries and Gemini Blueprint are currently implementing it. Using a drawing, you can easily create beans and connect them to each other. If you register the remote service this way, you can set any property using the drawing (like the bean property in spring applicationcontext.xml).

You can find an example application that I made at https://source.everit.biz/svn/everit-osgi/trunk/samples/jaxrs/ (user / passwd: guest / guest). There is a guide explaining how these samples can be run and developed at http://cookbook.everit.org

Hope the sample application helps you get started with the Remote Services Services specification section.

To learn how to use JPA and Injection (Blueprint), you should check the Compendium OSGi specification for features and find the implementation you need. I also made a sample project based on the project and hibernate-jpa, which you can find as a relative of the sample URL that I already provided.

Update

There is also a JAXRS extender implementation that I did at https://github.com/everit-org/osgi-remote-jersey . See the README documentation. It differs from the first in such a way that it works based on the properties of the whiteboard service.

+5
source

I had a similar issue with OSGi, Declarative Services and Jersey.

A resource can be annotated with @Component and @Reference annotations. This will instruct DS to create an instance of the SomeResource class and enter the correct link in this instance when all the dependencies (links) are executed.

The reason your links are null is because the JAX-RS implementation will create a new instance of the SomeResource class for each web request. This instance of the SomeResource class does not match the one that was created by DS.

I solved this problem by setting a static reference variable with the Java static keyword:

 private static SomeService service = null; 

This ensured that the dependency reference was bound to the class object instead of the instance, and then all instances could see the value entered.

This solution introduced a new problem. This link should be cleared during the unbind event (when the service becomes unavailable), since it will not be destroyed when the instance is destroyed.

+2
source

The problem will be resolved if the annotated @Path type is registered as the service itself. With DS, you can simply enter other services. I ran into this problem almost a year ago. That's why I wrote a small OSGi JAX-RS Connector that gives you exactly what I described. Try it if you want: https://github.com/hstaudacher/osgi-jax-rs-connector

0
source

Source: https://habr.com/ru/post/913465/


All Articles