Re: Aries jax-rs whiteboard

2019-11-15 Thread Tim Ward
Hi Matthias,

So from the example that you’ve given I’m not sure why you have the whiteboard 
application at all. Providing an empty whiteboard application doesn’t really 
give you any benefit - the primary use case is for registering existing 
non-OSGi JAX-RS applications, or for where you already have a bunch of resource 
classes.

In any event, the reason that what you have isn’t working for you is that the 
JSON extension isn’t targeting your application. It’s not enough to just put 
"osgi.jaxrs.application.select=(osgi.jaxrs.name=MyApp)” on the resource, it 
must also go on the extension, meaning that you need to configure the Aries 
JAX-RS support to add that property.


The other suggested fix, as Oleg outlined, is for example:

@Component(
service = Application.class,
property = {
  "osgi.jaxrs.name =MyApp",
  "osgi.jaxrs.application.base=/app",
})
public class MyApp extends Application {
@Reference(target="(osgi.jaxrs.name =jaxb-json)”)
Object writer;

@Override
public Set getSingletons() {
Feature f = fc -> fc.register(writer, MessageBodyWriter.class, 
MessageBodyReader.class);
Set singletons = new HashSet<>();
singletons.add(f);
return singletons;
}
}

@Path("/service")
@Component(
service = MyService.class,
property = {
  "osgi.jaxrs.resource=true",
  "osgi.jaxrs.application.select=(osgi.jaxrs.name 
=MyApp)",
})
public class MyService ...


> On 15 Nov 2019, at 15:35, Oleg Cohen  wrote:
> 
> Hi Matthias,
> 
> I was in the same situation. Here is what I ended up doing. Perhaps it will 
> work for you.
> 
> Here is my code:
> 
> import java.util.HashSet;
> import java.util.Set;
> 
> import javax.ws.rs.core.Application;
> 
> import org.apache.logging.log4j.Logger;
> import org.osgi.service.component.annotations.Activate;
> import org.osgi.service.component.annotations.Component;
> import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationBase;
> import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;
> 
> import com.fasterxml.jackson.annotation.JsonInclude.Include;
> import com.fasterxml.jackson.databind.DeserializationFeature;
> import com.fasterxml.jackson.databind.ObjectMapper;
> import com.fasterxml.jackson.databind.SerializationFeature;
> import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
> 
> @Component(service = Application.class)
> @JaxrsApplicationBase(“my-app")
> @JaxrsName(“MyApplication")
> public class MyApplication extends Application {
> 
>   private static final Logger logger = 
> org.apache.logging.log4j.LogManager.getLogger(MyApplication.class);
>   
>   private JacksonJsonProvider jsonProvider;
>   
>   @Activate
>   private void activate() {
>   
>   logger.info(“MyApplication.activate(): Entry ...");
>   
>   ObjectMapper objectMapper = new ObjectMapper();
>   
>   objectMapper = new ObjectMapper();
> 
>   objectMapper.setSerializationInclusion(Include.NON_NULL);
>   
>   
> objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
>   
>   
> objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE,
>  false);
>   
>   jsonProvider = new JacksonJsonProvider(objectMapper);
>   
>   logger.info(“MyApplication.activate(): jsonProvider = " + 
> jsonProvider);
>   }
>   
> @Override
> public Set getSingletons() {
> 
> Set singletons = new HashSet<>();
> 
> singletons.add(jsonProvider);
> 
> return singletons;
> }
> }
> 
> 
>> On Nov 15, 2019, at 10:26 AM, Matthias Leinweber > > wrote:
>> 
>> Ok that is something i already tried. But i don't want to use a own 
>> MessageWriter/Reader. I just want to use the one provided by aries-http 
>> whiteboard:
>> [javax.ws.rs.ext.MessageBodyReader, javax.ws.rs.ext.MessageBodyWriter]
>> --
>>  jackson.jaxb.version = 2.9.6
>>  jackson.jaxrs.json.version = 2.9.6
>>  osgi.jaxrs.extension = true
>>  osgi.jaxrs.media.type = application/json
>>  osgi.jaxrs.name  = jaxb-json
>>  service.bundleid = 46
>>  service.id  = 170
>>  service.ranking = -2147483648
>>  service.scope = prototype
>> Provided by : 
>>  Apache Aries JAX-RS JAX-RS Jackson (46)
>> Used by: 
>>  Apache Aries JAX-RS Whiteboard (47)
>> 
>> But something is wrong...
>> 
>> My components are configured this way...
>> 
>> @Component(
>> service = Application.class,
>> property = {
>>   "osgi.jaxrs.name =MyApp",
>>   "osgi.jaxrs.application.base=/app",
>>   
>> 

Re: Aries jax-rs whiteboard

2019-11-15 Thread Matthias Leinweber
Well yes that works but there must be a way to
use JsonProviderPrototypeServiceFactory provided by the
bundle: org.apache.aries.jax.rs.jackson.

regards Matthias

Am Fr., 15. Nov. 2019 um 16:35 Uhr schrieb Oleg Cohen <
oleg.co...@assurebridge.com>:

> Hi Matthias,
>
> I was in the same situation. Here is what I ended up doing. Perhaps it
> will work for you.
>
> Here is my code:
>
> *import* java.util.HashSet;
> *import* java.util.Set;
>
> *import* javax.ws.rs.core.Application;
>
> *import* org.apache.logging.log4j.Logger;
> *import* org.osgi.service.component.annotations.Activate;
> *import* org.osgi.service.component.annotations.Component;
> *import*
> org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationBase;
> *import* org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;
>
> *import* com.fasterxml.jackson.annotation.JsonInclude.Include;
> *import* com.fasterxml.jackson.databind.DeserializationFeature;
> *import* com.fasterxml.jackson.databind.ObjectMapper;
> *import* com.fasterxml.jackson.databind.SerializationFeature;
> *import* com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
>
> @Component(service = Application.*class*)
> @JaxrsApplicationBase(“my-app")
> @JaxrsName(“MyApplication")
> *public* *class* MyApplication *extends* Application {
>
> *private* *static* *final* Logger *logger* =
> org.apache.logging.log4j.LogManager.*getLogger*(MyApplication.*class*);
>
>
> *private* JacksonJsonProvider jsonProvider;
>
>
> @Activate
> *private* *void* activate() {
>
>
> *logger*.info(“MyApplication.activate(): Entry ...");
>
>
> ObjectMapper objectMapper = *new* ObjectMapper();
>
>
> objectMapper = *new* ObjectMapper();
>
> objectMapper.setSerializationInclusion(Include.*NON_NULL*);
>
>
> objectMapper.configure(SerializationFeature.*WRITE_DATES_AS_TIMESTAMPS*,
> *false*);
>
>
> objectMapper.configure(DeserializationFeature.
> *ADJUST_DATES_TO_CONTEXT_TIME_ZONE*, *false*);
>
>
> jsonProvider = *new* JacksonJsonProvider(objectMapper);
>
>
> *logger*.info(“MyApplication.activate(): jsonProvider = " + jsonProvider);
> }
>
>
> @Override
> *public* Set getSingletons() {
>
> Set singletons = *new* HashSet<>();
>
>
> singletons.add(jsonProvider);
>
> *return* singletons;
> }
>
> }
>
>
> On Nov 15, 2019, at 10:26 AM, Matthias Leinweber <
> m.leinwe...@datatactics.de> wrote:
>
> Ok that is something i already tried. But i don't want to use a own
> MessageWriter/Reader. I just want to use the one provided by aries-http
> whiteboard:
> [javax.ws.rs.ext.MessageBodyReader, javax.ws.rs.ext.MessageBodyWriter]
> --
>  jackson.jaxb.version = 2.9.6
>  jackson.jaxrs.json.version = 2.9.6
>  osgi.jaxrs.extension = true
>  osgi.jaxrs.media.type = application/json
>  osgi.jaxrs.name = jaxb-json
>  service.bundleid = 46
>  service.id = 170
>  service.ranking = -2147483648
>  service.scope = prototype
> Provided by :
>  Apache Aries JAX-RS JAX-RS Jackson (46)
> Used by:
>  Apache Aries JAX-RS Whiteboard (47)
>
> But something is wrong...
>
> My components are configured this way...
>
> @Component(
> service = Application.class,
> property = {
>   "osgi.jaxrs.name=MyApp",
>   "osgi.jaxrs.application.base=/app",
>
> "osgi.jaxrs.whiteboard.target=(service.pid=org.apache.aries.jax.rs.whiteboard.default)",
>   //"osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)" <- i
> tried it also here
> })
> public class MyApp extends Application {}
>
> @Path("/service")
> @Component(
> service = MyService.class,
> property = {
>   "osgi.jaxrs.resource=true",
>   "osgi.jaxrs.application.select=(osgi.jaxrs.name=MyApp)",
>   "osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)" <- with
> this line the complete karaf installation is not responding
> })
> public class MyService ...
>
> Am Fr., 15. Nov. 2019 um 11:47 Uhr schrieb Tim Ward  >:
>
>> Hi Matthias,
>>
>> So it sounds as though you’re in the following situation:
>>
>>1. Providing a custom Application to the whiteboard
>>2. The application service has the property osgi.jaxrs.name = MyApp
>>set on the service registration
>>3. Your application needs, but does not contain, JSON serialisation
>>support
>>4. You want to use an external MessageBodyReader and
>>MessageBodyWriter service to extend your application
>>
>>
>> Assuming that these are correct then:
>>
>>
>>1. Your Application needs to tell the whiteboard that it is missing
>>some required extensions. This will prevent it being deployed until the
>>extension is available. See the details of the
>>osgi.jaxrs.extension.select
>>
>> 
>>  property
>>which will need to match service properties on your whiteboard extension
>>2. Your external MessageBodyReader and MessageBodyWriter will need to
>>be registered 

Re: Aries jax-rs whiteboard

2019-11-15 Thread Oleg Cohen
Hi Matthias,

I was in the same situation. Here is what I ended up doing. Perhaps it will 
work for you.

Here is my code:

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import org.apache.logging.log4j.Logger;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationBase;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;

@Component(service = Application.class)
@JaxrsApplicationBase(“my-app")
@JaxrsName(“MyApplication")
public class MyApplication extends Application {

private static final Logger logger = 
org.apache.logging.log4j.LogManager.getLogger(MyApplication.class);

private JacksonJsonProvider jsonProvider;

@Activate
private void activate() {

logger.info(“MyApplication.activate(): Entry ...");

ObjectMapper objectMapper = new ObjectMapper();

objectMapper = new ObjectMapper();

objectMapper.setSerializationInclusion(Include.NON_NULL);


objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);


objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE,
 false);

jsonProvider = new JacksonJsonProvider(objectMapper);

logger.info(“MyApplication.activate(): jsonProvider = " + 
jsonProvider);
}

@Override
public Set getSingletons() {

Set singletons = new HashSet<>();

singletons.add(jsonProvider);

return singletons;
}
}


> On Nov 15, 2019, at 10:26 AM, Matthias Leinweber  
> wrote:
> 
> Ok that is something i already tried. But i don't want to use a own 
> MessageWriter/Reader. I just want to use the one provided by aries-http 
> whiteboard:
> [javax.ws.rs.ext.MessageBodyReader, javax.ws.rs.ext.MessageBodyWriter]
> --
>  jackson.jaxb.version = 2.9.6
>  jackson.jaxrs.json.version = 2.9.6
>  osgi.jaxrs.extension = true
>  osgi.jaxrs.media.type = application/json
>  osgi.jaxrs.name  = jaxb-json
>  service.bundleid = 46
>  service.id  = 170
>  service.ranking = -2147483648
>  service.scope = prototype
> Provided by : 
>  Apache Aries JAX-RS JAX-RS Jackson (46)
> Used by: 
>  Apache Aries JAX-RS Whiteboard (47)
> 
> But something is wrong...
> 
> My components are configured this way...
> 
> @Component(
> service = Application.class,
> property = {
>   "osgi.jaxrs.name =MyApp",
>   "osgi.jaxrs.application.base=/app",
>   
> "osgi.jaxrs.whiteboard.target=(service.pid=org.apache.aries.jax.rs.whiteboard.default)",
>   //"osgi.jaxrs.extension.select=(osgi.jaxrs.name 
> =jaxb-json)" <- i tried it also here
> })
> public class MyApp extends Application {}
> 
> @Path("/service")
> @Component(
> service = MyService.class,
> property = {
>   "osgi.jaxrs.resource=true",
>   "osgi.jaxrs.application.select=(osgi.jaxrs.name 
> =MyApp)",
>   "osgi.jaxrs.extension.select=(osgi.jaxrs.name 
> =jaxb-json)" <- with this line the complete karaf 
> installation is not responding
> })
> public class MyService ...
> 
> Am Fr., 15. Nov. 2019 um 11:47 Uhr schrieb Tim Ward  >:
> Hi Matthias,
> 
> So it sounds as though you’re in the following situation:
> Providing a custom Application to the whiteboard
> The application service has the property osgi.jaxrs.name 
>  = MyApp set on the service registration
> Your application needs, but does not contain, JSON serialisation support
> You want to use an external MessageBodyReader and MessageBodyWriter service 
> to extend your application
> 
> Assuming that these are correct then:
> 
> Your Application needs to tell the whiteboard that it is missing some 
> required extensions. This will prevent it being deployed until the extension 
> is available. See the details of the osgi.jaxrs.extension.select 
> 
>  property which will need to match service properties on your whiteboard 
> extension
> Your external MessageBodyReader and MessageBodyWriter will need to be 
> registered with
> The service has the property 

Re: Aries jax-rs whiteboard

2019-11-15 Thread Matthias Leinweber
Ok that is something i already tried. But i don't want to use a own
MessageWriter/Reader. I just want to use the one provided by aries-http
whiteboard:
[javax.ws.rs.ext.MessageBodyReader, javax.ws.rs.ext.MessageBodyWriter]
--
 jackson.jaxb.version = 2.9.6
 jackson.jaxrs.json.version = 2.9.6
 osgi.jaxrs.extension = true
 osgi.jaxrs.media.type = application/json
 osgi.jaxrs.name = jaxb-json
 service.bundleid = 46
 service.id = 170
 service.ranking = -2147483648
 service.scope = prototype
Provided by :
 Apache Aries JAX-RS JAX-RS Jackson (46)
Used by:
 Apache Aries JAX-RS Whiteboard (47)

But something is wrong...

My components are configured this way...

@Component(
service = Application.class,
property = {
  "osgi.jaxrs.name=MyApp",
  "osgi.jaxrs.application.base=/app",

"osgi.jaxrs.whiteboard.target=(service.pid=org.apache.aries.jax.rs.whiteboard.default)",
  //"osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)" <- i
tried it also here
})
public class MyApp extends Application {}

@Path("/service")
@Component(
service = MyService.class,
property = {
  "osgi.jaxrs.resource=true",
  "osgi.jaxrs.application.select=(osgi.jaxrs.name=MyApp)",
  "osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)" <- with
this line the complete karaf installation is not responding
})
public class MyService ...

Am Fr., 15. Nov. 2019 um 11:47 Uhr schrieb Tim Ward :

> Hi Matthias,
>
> So it sounds as though you’re in the following situation:
>
>1. Providing a custom Application to the whiteboard
>2. The application service has the property osgi.jaxrs.name = MyApp
>set on the service registration
>3. Your application needs, but does not contain, JSON serialisation
>support
>4. You want to use an external MessageBodyReader and MessageBodyWriter
>service to extend your application
>
>
> Assuming that these are correct then:
>
>
>1. Your Application needs to tell the whiteboard that it is missing
>some required extensions. This will prevent it being deployed until the
>extension is available. See the details of the
>osgi.jaxrs.extension.select
>
> 
>  property
>which will need to match service properties on your whiteboard extension
>2. Your external MessageBodyReader and MessageBodyWriter will need to
>be registered with
>   1. The service has the property osgi.jaxrs.extension = true (to say
>   that this is an extension)
>   2. The service registers the interfaces MessageBodyReader and
>   MessageBodyWriter (defining the types that the whiteboard will use it 
> as)
>   3. The service has the relevant property(ies) to match your
>   application’s extension select filter
>   4. The service has the property osgi.jaxrs.application.select = (
>   osgi.jaxrs.name=MyApp) to select your application as a target
>
>
> Another option is simply to set the extension as a part of your whiteboard
> application. This way you avoid the need to set quite so many service
> properties because the application is “complete” and doesn’t need to
> register a dependency or be targeted by an extension.
>
> All the best,
>
> Tim
>
> On 15 Nov 2019, at 00:07, Matthias Leinweber 
> wrote:
>
> Ok i hit an additional problem.
> When i create a JaxRsApplication i can reference them in my resource
> everything works fine except the MessageWriter and MessageReader e.g.
> Jackson Extension is not found.
> --> No message body writer has been found for class ... ContentType:
> application/json
> Without "osgi.jaxrs.application.select=(osgi.jaxrs.name=MyApp)",
> serialization works.
>
> I also tried to explicitly select the whiteboard for the Application,
> with 
> "osgi.jaxrs.whiteboard.target=(service.pid=org.apache.aries.jax.rs.whiteboard.default)"
> but that doesn't work.
> How does the injection mechanism work? I couldn't figure it out reading
> the aries source code.
>
> regards,
> Matthias
>
> Am Fr., 8. Nov. 2019 um 10:28 Uhr schrieb Tim Ward :
>
>> Hi,
>>
>> Yes, you can absolutely inject things using @Context (this is the only
>> way to do server sent events, so it’s not optional for any implementation).
>> It’s recommended that you inject into resource methods, rather than into
>> fields, unless you make your service prototype scope. This is to avoid any
>> potential threading mismatch if you inject invocation scoped objects (e.g.
>> an incoming HttpServletRequest) and get two http calls at the same time.
>>
>> Tim
>>
>> On 7 Nov 2019, at 16:24, Matthias Leinweber 
>> wrote:
>>
>> Great. Thank you very much.
>>
>> I dont want to add CXF or Jersey. thank to your answer I have come up
>> with the idea myself to inject the  @Context HttpServletRequest into the
>> JaxRS code. To mix in this:
>> 

Re: Aries jax-rs whiteboard

2019-11-15 Thread Tim Ward
Hi Matthias,

So it sounds as though you’re in the following situation:
Providing a custom Application to the whiteboard
The application service has the property osgi.jaxrs.name = MyApp set on the 
service registration
Your application needs, but does not contain, JSON serialisation support
You want to use an external MessageBodyReader and MessageBodyWriter service to 
extend your application

Assuming that these are correct then:

Your Application needs to tell the whiteboard that it is missing some required 
extensions. This will prevent it being deployed until the extension is 
available. See the details of the osgi.jaxrs.extension.select 

 property which will need to match service properties on your whiteboard 
extension
Your external MessageBodyReader and MessageBodyWriter will need to be 
registered with
The service has the property osgi.jaxrs.extension = true (to say that this is 
an extension)
The service registers the interfaces MessageBodyReader and MessageBodyWriter 
(defining the types that the whiteboard will use it as)
The service has the relevant property(ies) to match your application’s 
extension select filter
The service has the property osgi.jaxrs.application.select = 
(osgi.jaxrs.name=MyApp) to select your application as a target

Another option is simply to set the extension as a part of your whiteboard 
application. This way you avoid the need to set quite so many service 
properties because the application is “complete” and doesn’t need to register a 
dependency or be targeted by an extension.

All the best,

Tim

> On 15 Nov 2019, at 00:07, Matthias Leinweber  
> wrote:
> 
> Ok i hit an additional problem.
> When i create a JaxRsApplication i can reference them in my resource 
> everything works fine except the MessageWriter and MessageReader e.g. Jackson 
> Extension is not found.
> --> No message body writer has been found for class ... ContentType: 
> application/json
> Without "osgi.jaxrs.application.select=(osgi.jaxrs.name 
> =MyApp)", serialization works.
> 
> I also tried to explicitly select the whiteboard for the Application, with 
> "osgi.jaxrs.whiteboard.target=(service.pid=org.apache.aries.jax.rs.whiteboard.default)"
>  but that doesn't work.
> How does the injection mechanism work? I couldn't figure it out reading the 
> aries source code.
> 
> regards,
> Matthias
> 
> Am Fr., 8. Nov. 2019 um 10:28 Uhr schrieb Tim Ward  >:
> Hi,
> 
> Yes, you can absolutely inject things using @Context (this is the only way to 
> do server sent events, so it’s not optional for any implementation). It’s 
> recommended that you inject into resource methods, rather than into fields, 
> unless you make your service prototype scope. This is to avoid any potential 
> threading mismatch if you inject invocation scoped objects (e.g. an incoming 
> HttpServletRequest) and get two http calls at the same time.
> 
> Tim
> 
>> On 7 Nov 2019, at 16:24, Matthias Leinweber > > wrote:
>> 
>> Great. Thank you very much.
>> 
>> I dont want to add CXF or Jersey. thank to your answer I have come up with 
>> the idea myself to inject the  @Context HttpServletRequest into the JaxRS 
>> code. To mix in this: 
>> https://osgi.org/specification/osgi.cmpn/7.0.0/service.http.whiteboard.html#d0e120961
>>  
>> 
>> I didn't test it yet but does it work? I don't see that the aries JaxRs 
>> whiteboard impl somewhere defined 
>> osgi.http.whiteboard.servlet.multipart.enabled=true
>> 
>> Best regards,
>> Matthias
>> 
>> Am Do., 7. Nov. 2019 um 15:38 Uhr schrieb Tim Ward > >:
>> Hi Matthias
>> 
>>> I was a bit confused about how you could add a Servelt to the 
>>> JaxRsWhiteboard instead of the HttpWhiteboard for Multi-Part file uploads.
>> 
>> I hope it’s now clear that the JAX-RS whiteboard does not support Servlets. 
>> You can either:
>> Register a servlet with the Http Whiteboard and find a place to put the file
>> Handle the multipart file upload using JAX-RS
>> 
>> If the file upload is only needed by your JAX-RS components then I would 
>> recommend just using JAX-RS rather than a servlet.
>> 
>>> * So a JaxRsResource can but most not belong to an application?
>> 
>> A JAX-RS Whiteboard resource is just a “bare” resource in the service 
>> registry. In the most common case the resource service that you register 
>> will bind to the “default” application provided by the JAX-RS Whiteboard. 
>> There is no need to deploy a custom whiteboard application for resources to 
>> be hosted by the JAX-RS whiteboard.
>> 
>>> * It's fine to put all your Resources into the same JaxRsWhiteboard even if 
>>> you could separate them?
>> 
>> Yes. This will work fine. All the resources (by default) will get hosted in 
>> the