On 11 Oct 2010, at 9:26 , Ivo Ladage-van Doorn wrote:

> From: amdatu-developers-bounces at amdatu.org 
> [mailto:amdatu-developers-bounces at amdatu.org] On Behalf Of Marcel Offermans
> Sent: vrijdag 8 oktober 2010 23:36
> To: amdatu-developers at amdatu.org
> Subject: Re: [Amdatu-developers] Unwanted dependency of REST services with 
> Apache Wink
>  
> On 8 Oct 2010, at 16:49 , Ivo Ladage-van Doorn wrote:
> 
> Evaluating the code of the REST services, Angelo and I identified two issues 
> with the current implementation: 
> -          The current implementation of the Apache Wink application bundle 
> embeds the JAX-RS packages and exports them. REST services using JAX-RS 
> should add JAX-RS annotations which packages are provided by the Wink 
> application bundle. This causes an unwanted dependency between the Wink 
> bundle and the REST service bundle.
>  
> So create a separate bundle that just exports the JAX-RS package and have 
> Apache Wink import that one.
> 
> 
> -          In the current implementation a ServiceTracker is used to listen 
> to the availability of _any_ service, checking if its class contains the 
> @Path annotation. This service must implement _an_ interface (no matter which 
> one) in order for this to work properly. Especially the fact that the service 
> should implement _any_ interface is error-prone and should be improved.
>  
> That's not entirely true.
>  
> A service does not need to implement an interface at all to be registered in 
> the service registry.
>  
> You can register it with an implementation class, or even just 
> "java.lang.Object". Not very pretty either though.
> [Ivo Ladage-van Doorn] The problem I tried to explain manifests itself in the 
> service tracker tracking all services and looking for the @Path annotation 
> (see WinkRegistrationServiceImpl line 170):
>  
>         public Object addingService(ServiceReference ref) {
>             // Check if this is a JAX-RS annotated class
>             Object service = m_bundleContext.getService(ref);
>             if (service.getClass().getAnnotation(Path.class) != null) {
>                 // Register a new REST servlet for this REST resource
>                 addRestServlet(service);
>             }
>             return context.getService(ref);
>         }
>  
> When a service is not registered with an interface, this code snippet doesn?t 
> work since getService returns null. In that case there seems to be no way to 
> access the class of the implementing service, required to evaluate the @Path 
> annotation.

Two observations:

1) First of all, I think we should be using the dependency manager everywhere, 
so I would discourage the use of a ServiceTracker directly here. I'm not 
argueing that it would not work this way, but once we start using more advanced 
patterns with the dependency manager (adapters and most definitely aspects) 
using a plain ServiceTracker will become more complicated and too low level. So 
instead, just define your code like this:

init:

dm.createComponent()
  .setImplementation(RestTracker.class)
  .add(createServiceDependency()
    .setService("(" + Constants.OBJECTCLASS + "=*)")
    .setCallbacks("add", "remove"))

class RestTracker {
  public void add(ServiceReference ref, Object instance) {
    /* annotation processing here,
        keep track of processed services using a Map with ServiceReference as 
its key */ 
  }
  public void remove(ServiceReference ref, Object instance) { /* cleanup here 
*/ }
}

2) A service can be registered not using an interface, but you need to do it 
like this:

dm.createComponent().setInterface(...).setImplementation(...)

so what you pass to setInterface does not need to be an interface.
 
>  There are two possible solutions:
> -          Introduce a new bundle with some RESTService interface, 
> implemented by REST services and picked up whiteboard style by the Wink 
> application bundle to register them in the Wink framework. Also the JAX-RS 
> classes should be moved to this bundle.
>  
> I like the whiteboard pattern here.
>  
> I do not like the "RESTService" which sounds more or less like a "marker" 
> interface. It's more common throughout OSGi to use a service property for 
> that, if necessary at all.
>  
> What I'm wondering is the following: if some service is exposed as a REST 
> service, will it be *only* exposed as a REST service or will there also be a 
> "normal" OSGi service in the service registry. This "normal" service probably 
> has a different API that might not be REST-like but more Java-style. However, 
> imagine an implementation A that publishes itself as an OSGi service S, then 
> we could simply annotate the implementation A with the JAX-RS annotations. 
> Tracking all services we can still pick up those annotations and we would 
> neither need marker interfaces, nor special service properties (even though 
> we could consider the latter to make it more explicit that some service also 
> should be exposed as a REST service).
> [Ivo Ladage-van Doorn] I think in general the  REST and Java interfaces of a 
> service will be very different. Taking a look at existing REST services in 
> Amdatu (see CourseResource for example), it?s quite clear that in general 
> these two interfaces will be very different.
> If you know a solution for how to ?track all services and pick up the 
> annotations? let me know? (see above)

I agree that a REST service and a Java service will be very different.

I do think they can share mostly the same implementation.

Also, I think that everything that is exposed as a REST service should also be 
exposed as a Java/OSGi service.

The solution above should work for tracking annotations (copied it from working 
code).

Greetings, Marcel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://lists.amdatu.org/pipermail/amdatu-developers/attachments/20101011/35e0a50f/attachment-0001.html
 

Reply via email to