Re: Questions about cxfrs

2014-02-07 Thread Sergey Beryozkin

For those who may be interested, see the attached files to
https://issues.apache.org/jira/browse/CAMEL-7147

(blueprint.xml, jaxrs-beans.xml), the route works nicely with CXF 2.7.7 
with minor modifications, which won't be needed with the newer CXF versions


Sergey
On 22/01/14 22:13, David wrote:

I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON
provider instead of JacksonJsonProvider, and that results in an exception
being thrown, telling me that no message body reader was found for my
class. I'm using the same test case that's attached to the JIRA, just with
a different JSON provider, and adding @XmlRootElement(name="container") to
the domain class.



On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote:


Hi, sure, I only referenced Jettison as a possible alternative.
I think Jackson is picked up, Jettison only works, as you mentioned, with
JAXB sending the write events to it, and as I understand you've no
XMLRootElement/etc added to the data beans

Sergey

On 21/01/14 21:14, David wrote:


Comments in-line.


On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin 
wrote:


  Hi

Please see comments below,

On 21/01/14 17:01, David wrote:

  I think this is more of a Camel question than a CXF question, but let me

know if that's not the case (would it have been bad form to cross-post
this
to cxf-user?).

I have questions regarding use of Jackson with CXF, as well as how to
get
CXFRS not to wrap the root value of a JSON payload.

I am trying to use Camel and CXF as part of a service orchestration
using
JSON over REST. My biggest question is how to configure cxfrs to use
Jackson for all JSON marshal/unmarshal operations.

So far, I've configured a cxf:rsServer and added a cxf:providers element
with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
bean.
I've also added the following to my route, although I haven't found
anywhere to reference it yet:

   
   
   

I'm basically exposing the configured cxf:rsServer service as an
external
entry-point:

http://localhost:8182";
serviceClass="org.my.Service"
loggingFeatureEnabled="true">






I'm then using a couple cxfrs producer endpoints to invoke external
REST/JSON services implemented using RESTEasy:

   
   POST
   
   
   /service1/operation1
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>
   
   POST
   
   
   /service2/operation2
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>


The idea is that each of those services will modify the payload, and the
resulting object will be passed back to the caller.

The services themselves are pretty standard. Class annotated with @Path,
along with a single method annotated with @POST, @Consumes and @Produces
(both types are set to MediaType.APPLICATION_JSON). The methods expect
and
return a single container class with id and a couple string values.

When I call my service, however, an exception is thrown by the code
that's
attempting to call the cxfrs producer endpoint, saying there's no
message
body writer for my container class and applicaiton/json. At one point I
had
it working (not sure what was different back then) and I was running
into
issues where the CXF client code was wrapping the JSON payload (I.e.
{"classname": {"id": 1, ...}}), which the RESTEasy services didn't
like. I
got around it by registering a custom ContextResolver for the RESTEasy
services that sets the WRAP_ROOT_VALUE feature on the Jackson object
mapper, and adding a @JsonRootName annotation to my container class, but
would prefer to solve the problem by telling the CXFRS client not to
wrap
the root value. From looking at
http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
that both rsServer and rsClient have a "features" element that I think
might allow me to do this, .but I can't find any documentation or
examples
for using it.

I hope the above made sense, and thanks in advance for your help.

   The client-side wrapper is added by the active JSON provider which is


Jackson in this case.




I might be doing something wrong, but that doesn't seem to be the case. It
seems to be using Jackson for the service I'm exposing using cxf:rsServer.
However, the cxfrs client endpoint (I.e. http://etc.../>)
seems to still be using Jettison. I also tried configuring a cxf:rsClient
to access one of my external services, but the paths from my configured
cxf:rsServer bean keep getting appended to the end of my URL. Are the two
beans tightly coupled somehow? I.e.

http://localhost:8182";
serviceClass="my.Service1"
loggingFeatureEnabled="true">





http://localhost:8080/service2/service2path";
serviceClass="my.Service2"
loggingFeatureEnabled="true">





When my route attempts to invoke Service2, the URI is set to:
http://localh

Re: Questions about cxfrs

2014-01-23 Thread David
Thanks for the suggestion, I'll look into it as a temporary workaround.


On Thu, Jan 23, 2014 at 5:17 AM, Sergey Beryozkin wrote:

> Hi,
>
> I haven't had a chance to look into it yet, will do asap
> What about this alternative (assuming you'd like to do it the JAX-RS way):
> Create a CXF jaxrs:server entry endpoint with the address like
> "camel://myservice", and link to it from Camel Servlet. This endpoint
> service implementation will be a regular JAX-RS server (there will be no
> null returns, etc) which will do a couple of HTTP invocations using
> whatever Http API is preferred, example, you can try CXF WebClient or proxy
> support.
> Not sure if it will fir the purpose, suggesting it as a possible
> workaround.
>
> Sergey
>
>
> On 22/01/14 22:13, David wrote:
>
>> I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON
>> provider instead of JacksonJsonProvider, and that results in an exception
>> being thrown, telling me that no message body reader was found for my
>> class. I'm using the same test case that's attached to the JIRA, just with
>> a different JSON provider, and adding @XmlRootElement(name="container")
>> to
>> the domain class.
>>
>>
>>
>> On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin > >wrote:
>>
>>  Hi, sure, I only referenced Jettison as a possible alternative.
>>> I think Jackson is picked up, Jettison only works, as you mentioned, with
>>> JAXB sending the write events to it, and as I understand you've no
>>> XMLRootElement/etc added to the data beans
>>>
>>> Sergey
>>>
>>> On 21/01/14 21:14, David wrote:
>>>
>>>  Comments in-line.


 On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin <
 sberyoz...@gmail.com

> wrote:
>

   Hi

> Please see comments below,
>
> On 21/01/14 17:01, David wrote:
>
>   I think this is more of a Camel question than a CXF question, but
> let me
>
>> know if that's not the case (would it have been bad form to cross-post
>> this
>> to cxf-user?).
>>
>> I have questions regarding use of Jackson with CXF, as well as how to
>> get
>> CXFRS not to wrap the root value of a JSON payload.
>>
>> I am trying to use Camel and CXF as part of a service orchestration
>> using
>> JSON over REST. My biggest question is how to configure cxfrs to use
>> Jackson for all JSON marshal/unmarshal operations.
>>
>> So far, I've configured a cxf:rsServer and added a cxf:providers
>> element
>> with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
>> bean.
>> I've also added the following to my route, although I haven't found
>> anywhere to reference it yet:
>>
>>
>>
>>
>>
>> I'm basically exposing the configured cxf:rsServer service as an
>> external
>> entry-point:
>>
>> http://localhost:8182";
>> serviceClass="org.my.Service"
>> loggingFeatureEnabled="true">
>> 
>> 
>> 
>> 
>> > class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
>>
>> I'm then using a couple cxfrs producer endpoints to invoke external
>> REST/JSON services implemented using RESTEasy:
>>
>>
>>POST
>>
>>
>>/service1/operation1
>>
>>
>>application/json
>>
>>http://localhost:8080?exchangePattern=InOut
>> "/>
>>
>>POST
>>
>>
>>/service2/operation2
>>
>>
>>application/json
>>
>>http://localhost:8080?exchangePattern=InOut
>> "/>
>>
>>
>> The idea is that each of those services will modify the payload, and
>> the
>> resulting object will be passed back to the caller.
>>
>> The services themselves are pretty standard. Class annotated with
>> @Path,
>> along with a single method annotated with @POST, @Consumes and
>> @Produces
>> (both types are set to MediaType.APPLICATION_JSON). The methods expect
>> and
>> return a single container class with id and a couple string values.
>>
>> When I call my service, however, an exception is thrown by the code
>> that's
>> attempting to call the cxfrs producer endpoint, saying there's no
>> message
>> body writer for my container class and applicaiton/json. At one point
>> I
>> had
>> it working (not sure what was different back then) and I was running
>> into
>> issues where the CXF client code was wrapping the JSON payload (I.e.
>> {"classname": {"id": 1, ...}}), which the RESTEasy services didn't
>> like. I
>> got around it by registering a custom ContextResolver for the RESTEasy
>> services that sets the WRAP_ROOT_VALUE feat

Re: Questions about cxfrs

2014-01-23 Thread Sergey Beryozkin

Hi,

I haven't had a chance to look into it yet, will do asap
What about this alternative (assuming you'd like to do it the JAX-RS way):
Create a CXF jaxrs:server entry endpoint with the address like 
"camel://myservice", and link to it from Camel Servlet. This endpoint 
service implementation will be a regular JAX-RS server (there will be no 
null returns, etc) which will do a couple of HTTP invocations using 
whatever Http API is preferred, example, you can try CXF WebClient or 
proxy support.
Not sure if it will fir the purpose, suggesting it as a possible 
workaround.


Sergey

On 22/01/14 22:13, David wrote:

I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON
provider instead of JacksonJsonProvider, and that results in an exception
being thrown, telling me that no message body reader was found for my
class. I'm using the same test case that's attached to the JIRA, just with
a different JSON provider, and adding @XmlRootElement(name="container") to
the domain class.



On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote:


Hi, sure, I only referenced Jettison as a possible alternative.
I think Jackson is picked up, Jettison only works, as you mentioned, with
JAXB sending the write events to it, and as I understand you've no
XMLRootElement/etc added to the data beans

Sergey

On 21/01/14 21:14, David wrote:


Comments in-line.


On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin 
wrote:


  Hi

Please see comments below,

On 21/01/14 17:01, David wrote:

  I think this is more of a Camel question than a CXF question, but let me

know if that's not the case (would it have been bad form to cross-post
this
to cxf-user?).

I have questions regarding use of Jackson with CXF, as well as how to
get
CXFRS not to wrap the root value of a JSON payload.

I am trying to use Camel and CXF as part of a service orchestration
using
JSON over REST. My biggest question is how to configure cxfrs to use
Jackson for all JSON marshal/unmarshal operations.

So far, I've configured a cxf:rsServer and added a cxf:providers element
with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
bean.
I've also added the following to my route, although I haven't found
anywhere to reference it yet:

   
   
   

I'm basically exposing the configured cxf:rsServer service as an
external
entry-point:

http://localhost:8182";
serviceClass="org.my.Service"
loggingFeatureEnabled="true">






I'm then using a couple cxfrs producer endpoints to invoke external
REST/JSON services implemented using RESTEasy:

   
   POST
   
   
   /service1/operation1
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>
   
   POST
   
   
   /service2/operation2
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>


The idea is that each of those services will modify the payload, and the
resulting object will be passed back to the caller.

The services themselves are pretty standard. Class annotated with @Path,
along with a single method annotated with @POST, @Consumes and @Produces
(both types are set to MediaType.APPLICATION_JSON). The methods expect
and
return a single container class with id and a couple string values.

When I call my service, however, an exception is thrown by the code
that's
attempting to call the cxfrs producer endpoint, saying there's no
message
body writer for my container class and applicaiton/json. At one point I
had
it working (not sure what was different back then) and I was running
into
issues where the CXF client code was wrapping the JSON payload (I.e.
{"classname": {"id": 1, ...}}), which the RESTEasy services didn't
like. I
got around it by registering a custom ContextResolver for the RESTEasy
services that sets the WRAP_ROOT_VALUE feature on the Jackson object
mapper, and adding a @JsonRootName annotation to my container class, but
would prefer to solve the problem by telling the CXFRS client not to
wrap
the root value. From looking at
http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
that both rsServer and rsClient have a "features" element that I think
might allow me to do this, .but I can't find any documentation or
examples
for using it.

I hope the above made sense, and thanks in advance for your help.

   The client-side wrapper is added by the active JSON provider which is


Jackson in this case.




I might be doing something wrong, but that doesn't seem to be the case. It
seems to be using Jackson for the service I'm exposing using cxf:rsServer.
However, the cxfrs client endpoint (I.e. http://etc.../>)
seems to still be using Jettison. I also tried configuring a cxf:rsClient
to access one of my external services, but the paths from my configured
cxf:rsServer bean keep getting appended to the end of my U

Re: Questions about cxfrs

2014-01-22 Thread David
I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON
provider instead of JacksonJsonProvider, and that results in an exception
being thrown, telling me that no message body reader was found for my
class. I'm using the same test case that's attached to the JIRA, just with
a different JSON provider, and adding @XmlRootElement(name="container") to
the domain class.



On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote:

> Hi, sure, I only referenced Jettison as a possible alternative.
> I think Jackson is picked up, Jettison only works, as you mentioned, with
> JAXB sending the write events to it, and as I understand you've no
> XMLRootElement/etc added to the data beans
>
> Sergey
>
> On 21/01/14 21:14, David wrote:
>
>> Comments in-line.
>>
>>
>> On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin > >wrote:
>>
>>  Hi
>>> Please see comments below,
>>>
>>> On 21/01/14 17:01, David wrote:
>>>
>>>  I think this is more of a Camel question than a CXF question, but let me
 know if that's not the case (would it have been bad form to cross-post
 this
 to cxf-user?).

 I have questions regarding use of Jackson with CXF, as well as how to
 get
 CXFRS not to wrap the root value of a JSON payload.

 I am trying to use Camel and CXF as part of a service orchestration
 using
 JSON over REST. My biggest question is how to configure cxfrs to use
 Jackson for all JSON marshal/unmarshal operations.

 So far, I've configured a cxf:rsServer and added a cxf:providers element
 with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
 bean.
 I've also added the following to my route, although I haven't found
 anywhere to reference it yet:

   
   
   

 I'm basically exposing the configured cxf:rsServer service as an
 external
 entry-point:

 http://localhost:8182";
 serviceClass="org.my.Service"
 loggingFeatureEnabled="true">
 
 
 
 
 >>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />

 I'm then using a couple cxfrs producer endpoints to invoke external
 REST/JSON services implemented using RESTEasy:

   
   POST
   
   
   /service1/operation1
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>
   
   POST
   
   
   /service2/operation2
   
   
   application/json
   
   http://localhost:8080?exchangePattern=InOut"/>


 The idea is that each of those services will modify the payload, and the
 resulting object will be passed back to the caller.

 The services themselves are pretty standard. Class annotated with @Path,
 along with a single method annotated with @POST, @Consumes and @Produces
 (both types are set to MediaType.APPLICATION_JSON). The methods expect
 and
 return a single container class with id and a couple string values.

 When I call my service, however, an exception is thrown by the code
 that's
 attempting to call the cxfrs producer endpoint, saying there's no
 message
 body writer for my container class and applicaiton/json. At one point I
 had
 it working (not sure what was different back then) and I was running
 into
 issues where the CXF client code was wrapping the JSON payload (I.e.
 {"classname": {"id": 1, ...}}), which the RESTEasy services didn't
 like. I
 got around it by registering a custom ContextResolver for the RESTEasy
 services that sets the WRAP_ROOT_VALUE feature on the Jackson object
 mapper, and adding a @JsonRootName annotation to my container class, but
 would prefer to solve the problem by telling the CXFRS client not to
 wrap
 the root value. From looking at
 http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
 that both rsServer and rsClient have a "features" element that I think
 might allow me to do this, .but I can't find any documentation or
 examples
 for using it.

 I hope the above made sense, and thanks in advance for your help.

   The client-side wrapper is added by the active JSON provider which is

>>> Jackson in this case.
>>>
>>
>>
>> I might be doing something wrong, but that doesn't seem to be the case. It
>> seems to be using Jackson for the service I'm exposing using cxf:rsServer.
>> However, the cxfrs client endpoint (I.e. http://etc.../>)
>> seems to still be using Jettison. I also tried configuring a cxf:rsClient
>> to access one of my external services, but the paths from my configured
>> cxf:rsServer bean keep getting appended to the end of my URL. Are the two
>> beans tightly coupled someh

Re: Questions about cxfrs

2014-01-22 Thread David
See https://issues.apache.org/jira/browse/CAMEL-7147


On Wed, Jan 22, 2014 at 10:58 AM, Sergey Beryozkin wrote:

> Hi,
>
> On 22/01/14 14:20, David wrote:
>
>> I can create a test project. How would I get it to you, email to the list
>> as attachment? Or would it be better to open a JIRA, maybe?
>>
>>  Can you please open a JIRA and attach a test project there
> Many thanks
> Sergey
>
>>
>>
>> On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin > >wrote:
>>
>>  The stack trace suggests that JacksonJsonProvider did have a thread local
>>> context representing JAX-RS Providers injected into it at the
>>> registration
>>> time but at the invocation time no thread-local entry has been added to
>>> it
>>> and hence NPE.
>>> I have a lot of tests in CXF where client-side providers have the
>>> contexts
>>> injected, so I think it is somehow related to the way the client
>>> invocation
>>> is managed by cxfrs.
>>> I'm just curious how to reproduce it. Is there any chance that you can
>>> create a basic test project ? I will try to reproduce it on my own too
>>>
>>> Sergey
>>>
>>>
>>>
>>> On 22/01/14 03:51, David wrote:
>>>
>>>  On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang >>>
> wrote:
>


  On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com)
> wrote:
>
>  When my route attempts to invoke Service2, the URI is set to:
>>
>>>
>>>  http://localhost:8080/service2/service2path/service1/service1path,
>> where
>> service1/service1path is configured in my.Service1. I'm also
>> not sure why
>> I'm providing a serviceClass for rsClient. I thought maybe it
>> was going to
>> instantiate my service, but that doesn't seem to be the case.
>>
>>
>>  If you routing the response of first service to second service, you
> may
> need to clean up the CamelHttpPath message header.
>
>
>   Thanks, that was very helpful, but I'm not quite there yet. Shouldn't
>
 this
 header be cleared when I set inheritHeaders to false?

 I had made both the first and second service have the same http path in
 order to trick the camel route into working, and initially removing the
 header had the desired effect -- I.e.I got a 404 response because the
 path
 for the second service had been truncated. However, when I changed the
 entry-point service back to its original path, I got an NPE (at
 org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(
 ThreadLocalProviders.java:50)).
 I fixed that by instead setting the CamelHttpPath to the path for the
 next
 service, which worked.

 Next, I added in the third service, by wiring a second rsClient for it
 and
 duplicating the setHeader and cxfrs producer endpoint in the camel
 route.
 This mostly works, but not quite. When the response comes back from
 service2, my object is populated as expected. However, by the time the
 call
 to service3 happens, all variables in the object have been set to 0 for
 the
 int and null for the strings. Service3 is then called with this empty
 object and returns. Finally, I again get the same NPE from Service1. I
 tried resetting the CamelHttpPath to the initial value, but that didn't
 fix
 the NPE. Removing Service3 also doesn't fix the NPE during the Service1
 response, and the variables in the object are also still reset to
 0/null.

 Here's my route, as it stands now:

 
 
 /service2/service2path  >>> uri="cxfrs:bean:Service2"/>
 
 /service3/service3path 
 
 

 The same NPE I'm seeing was also seen here, apparently:

 http://mail-archives.apache.org/mod_mbox/cxf-users/201311.
 mbox/%3c52987699.6040...@gmail.com%3E

 Here's a more complete stacktrace from my logs:

 --
 22:38:54,309 | INFO  | tp2013341004-662 | response
 | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut,
 BodyType: mycompany.MyObject, Body:
 {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}]
 22:38:54,311 | WARN  | tp2013341004-662 | PhaseInterceptorChain
| 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for {
 http://myservice.mycompany.com/}Service1 has thrown exception,
 unwinding
 now
 javax.ws.rs.InternalServerErrorException:
 java.lang.NullPointerException
 at
 org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.
 handleWriteException(JAXRSOutInterceptor.java:396)[
 166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
 at
 org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(
 JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-
 frontend-jaxrs:2.7.0]
 at
 org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(
 JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-
 frontend-jaxrs

Re: Questions about cxfrs

2014-01-22 Thread Sergey Beryozkin

Hi,
On 22/01/14 14:20, David wrote:

I can create a test project. How would I get it to you, email to the list
as attachment? Or would it be better to open a JIRA, maybe?


Can you please open a JIRA and attach a test project there
Many thanks
Sergey



On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin wrote:


The stack trace suggests that JacksonJsonProvider did have a thread local
context representing JAX-RS Providers injected into it at the registration
time but at the invocation time no thread-local entry has been added to it
and hence NPE.
I have a lot of tests in CXF where client-side providers have the contexts
injected, so I think it is somehow related to the way the client invocation
is managed by cxfrs.
I'm just curious how to reproduce it. Is there any chance that you can
create a basic test project ? I will try to reproduce it on my own too

Sergey



On 22/01/14 03:51, David wrote:


On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang 
wrote:




On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote:


When my route attempts to invoke Service2, the URI is set to:



http://localhost:8080/service2/service2path/service1/service1path,
where
service1/service1path is configured in my.Service1. I'm also
not sure why
I'm providing a serviceClass for rsClient. I thought maybe it
was going to
instantiate my service, but that doesn't seem to be the case.



If you routing the response of first service to second service, you may
need to clean up the CamelHttpPath message header.


  Thanks, that was very helpful, but I'm not quite there yet. Shouldn't

this
header be cleared when I set inheritHeaders to false?

I had made both the first and second service have the same http path in
order to trick the camel route into working, and initially removing the
header had the desired effect -- I.e.I got a 404 response because the path
for the second service had been truncated. However, when I changed the
entry-point service back to its original path, I got an NPE (at
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(
ThreadLocalProviders.java:50)).
I fixed that by instead setting the CamelHttpPath to the path for the next
service, which worked.

Next, I added in the third service, by wiring a second rsClient for it and
duplicating the setHeader and cxfrs producer endpoint in the camel route.
This mostly works, but not quite. When the response comes back from
service2, my object is populated as expected. However, by the time the
call
to service3 happens, all variables in the object have been set to 0 for
the
int and null for the strings. Service3 is then called with this empty
object and returns. Finally, I again get the same NPE from Service1. I
tried resetting the CamelHttpPath to the initial value, but that didn't
fix
the NPE. Removing Service3 also doesn't fix the NPE during the Service1
response, and the variables in the object are also still reset to 0/null.

Here's my route, as it stands now:



/service2/service2path  

/service3/service3path 



The same NPE I'm seeing was also seen here, apparently:

http://mail-archives.apache.org/mod_mbox/cxf-users/201311.
mbox/%3c52987699.6040...@gmail.com%3E

Here's a more complete stacktrace from my logs:

--
22:38:54,309 | INFO  | tp2013341004-662 | response
| 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut,
BodyType: mycompany.MyObject, Body:
{"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}]
22:38:54,311 | WARN  | tp2013341004-662 | PhaseInterceptorChain
   | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for {
http://myservice.mycompany.com/}Service1 has thrown exception, unwinding
now
javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.
handleWriteException(JAXRSOutInterceptor.java:396)[
166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(
JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-
frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(
JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-
frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(
JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-
frontend-jaxrs:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(
PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(
OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(
PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.resume(
PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(
ChainInitiationObserver.java:78)[150:org.apac

Re: Questions about cxfrs

2014-01-22 Thread David
I can create a test project. How would I get it to you, email to the list
as attachment? Or would it be better to open a JIRA, maybe?



On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin wrote:

> The stack trace suggests that JacksonJsonProvider did have a thread local
> context representing JAX-RS Providers injected into it at the registration
> time but at the invocation time no thread-local entry has been added to it
> and hence NPE.
> I have a lot of tests in CXF where client-side providers have the contexts
> injected, so I think it is somehow related to the way the client invocation
> is managed by cxfrs.
> I'm just curious how to reproduce it. Is there any chance that you can
> create a basic test project ? I will try to reproduce it on my own too
>
> Sergey
>
>
>
> On 22/01/14 03:51, David wrote:
>
>> On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang > >wrote:
>>
>>
>>> On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote:
>>>
 When my route attempts to invoke Service2, the URI is set to:
>
 http://localhost:8080/service2/service2path/service1/service1path,
 where
 service1/service1path is configured in my.Service1. I'm also
 not sure why
 I'm providing a serviceClass for rsClient. I thought maybe it
 was going to
 instantiate my service, but that doesn't seem to be the case.


>>> If you routing the response of first service to second service, you may
>>> need to clean up the CamelHttpPath message header.
>>>
>>>
>>>  Thanks, that was very helpful, but I'm not quite there yet. Shouldn't
>> this
>> header be cleared when I set inheritHeaders to false?
>>
>> I had made both the first and second service have the same http path in
>> order to trick the camel route into working, and initially removing the
>> header had the desired effect -- I.e.I got a 404 response because the path
>> for the second service had been truncated. However, when I changed the
>> entry-point service back to its original path, I got an NPE (at
>> org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(
>> ThreadLocalProviders.java:50)).
>> I fixed that by instead setting the CamelHttpPath to the path for the next
>> service, which worked.
>>
>> Next, I added in the third service, by wiring a second rsClient for it and
>> duplicating the setHeader and cxfrs producer endpoint in the camel route.
>> This mostly works, but not quite. When the response comes back from
>> service2, my object is populated as expected. However, by the time the
>> call
>> to service3 happens, all variables in the object have been set to 0 for
>> the
>> int and null for the strings. Service3 is then called with this empty
>> object and returns. Finally, I again get the same NPE from Service1. I
>> tried resetting the CamelHttpPath to the initial value, but that didn't
>> fix
>> the NPE. Removing Service3 also doesn't fix the NPE during the Service1
>> response, and the variables in the object are also still reset to 0/null.
>>
>> Here's my route, as it stands now:
>>
>> 
>> 
>> /service2/service2path  > uri="cxfrs:bean:Service2"/>
>> 
>> /service3/service3path 
>> 
>> 
>>
>> The same NPE I'm seeing was also seen here, apparently:
>>
>> http://mail-archives.apache.org/mod_mbox/cxf-users/201311.
>> mbox/%3c52987699.6040...@gmail.com%3E
>>
>> Here's a more complete stacktrace from my logs:
>>
>> --
>> 22:38:54,309 | INFO  | tp2013341004-662 | response
>> | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut,
>> BodyType: mycompany.MyObject, Body:
>> {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}]
>> 22:38:54,311 | WARN  | tp2013341004-662 | PhaseInterceptorChain
>>   | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for {
>> http://myservice.mycompany.com/}Service1 has thrown exception, unwinding
>> now
>> javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException
>> at
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.
>> handleWriteException(JAXRSOutInterceptor.java:396)[
>> 166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
>> at
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(
>> JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-
>> frontend-jaxrs:2.7.0]
>> at
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(
>> JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-
>> frontend-jaxrs:2.7.0]
>> at
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(
>> JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-
>> frontend-jaxrs:2.7.0]
>> at
>> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(
>> PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
>> at
>> org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(
>> OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0]
>> at
>> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(
>> PhaseInterceptorChain.java:272)[150:org.apache.cxf.

Re: Questions about cxfrs

2014-01-22 Thread Sergey Beryozkin

Hi, sure, I only referenced Jettison as a possible alternative.
I think Jackson is picked up, Jettison only works, as you mentioned, 
with JAXB sending the write events to it, and as I understand you've no

XMLRootElement/etc added to the data beans

Sergey
On 21/01/14 21:14, David wrote:

Comments in-line.


On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote:


Hi
Please see comments below,

On 21/01/14 17:01, David wrote:


I think this is more of a Camel question than a CXF question, but let me
know if that's not the case (would it have been bad form to cross-post
this
to cxf-user?).

I have questions regarding use of Jackson with CXF, as well as how to get
CXFRS not to wrap the root value of a JSON payload.

I am trying to use Camel and CXF as part of a service orchestration using
JSON over REST. My biggest question is how to configure cxfrs to use
Jackson for all JSON marshal/unmarshal operations.

So far, I've configured a cxf:rsServer and added a cxf:providers element
with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
bean.
I've also added the following to my route, although I haven't found
anywhere to reference it yet:

  
  
  

I'm basically exposing the configured cxf:rsServer service as an external
entry-point:

http://localhost:8182";
serviceClass="org.my.Service"
loggingFeatureEnabled="true">






I'm then using a couple cxfrs producer endpoints to invoke external
REST/JSON services implemented using RESTEasy:

  
  POST
  
  
  /service1/operation1
  
  
  application/json
  
  http://localhost:8080?exchangePattern=InOut"/>
  
  POST
  
  
  /service2/operation2
  
  
  application/json
  
  http://localhost:8080?exchangePattern=InOut"/>


The idea is that each of those services will modify the payload, and the
resulting object will be passed back to the caller.

The services themselves are pretty standard. Class annotated with @Path,
along with a single method annotated with @POST, @Consumes and @Produces
(both types are set to MediaType.APPLICATION_JSON). The methods expect and
return a single container class with id and a couple string values.

When I call my service, however, an exception is thrown by the code that's
attempting to call the cxfrs producer endpoint, saying there's no message
body writer for my container class and applicaiton/json. At one point I
had
it working (not sure what was different back then) and I was running into
issues where the CXF client code was wrapping the JSON payload (I.e.
{"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I
got around it by registering a custom ContextResolver for the RESTEasy
services that sets the WRAP_ROOT_VALUE feature on the Jackson object
mapper, and adding a @JsonRootName annotation to my container class, but
would prefer to solve the problem by telling the CXFRS client not to wrap
the root value. From looking at
http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
that both rsServer and rsClient have a "features" element that I think
might allow me to do this, .but I can't find any documentation or examples
for using it.

I hope the above made sense, and thanks in advance for your help.

  The client-side wrapper is added by the active JSON provider which is

Jackson in this case.



I might be doing something wrong, but that doesn't seem to be the case. It
seems to be using Jackson for the service I'm exposing using cxf:rsServer.
However, the cxfrs client endpoint (I.e. http://etc.../>)
seems to still be using Jettison. I also tried configuring a cxf:rsClient
to access one of my external services, but the paths from my configured
cxf:rsServer bean keep getting appended to the end of my URL. Are the two
beans tightly coupled somehow? I.e.

http://localhost:8182";
serviceClass="my.Service1"
loggingFeatureEnabled="true">





http://localhost:8080/service2/service2path";
serviceClass="my.Service2"
loggingFeatureEnabled="true">





When my route attempts to invoke Service2, the URI is set to:
http://localhost:8080/service2/service2path/service1/service1path, where
service1/service1path is configured in my.Service1. I'm also not sure why
I'm providing a serviceClass for rsClient. I thought maybe it was going to
instantiate my service, but that doesn't seem to be the case.





So one option is to configure org.codehaus.jackson.jaxrs.JacksonJsonProvider
directly in Spring to drop a root element - that should be possible. Can
you try it ?



I was able to find an example for wiring a Jackson ObjectMapper bean and
providing a reference to it to the JacksonJsonProvider bean, but I need to
get my service client working before I can test it.





By the way, how complex the actual sequence is ? The other alternative can
be to use CXF JSONProvider (Jettison-based) - it is quite 

Re: Questions about cxfrs

2014-01-22 Thread Sergey Beryozkin
The stack trace suggests that JacksonJsonProvider did have a thread 
local context representing JAX-RS Providers injected into it at the 
registration time but at the invocation time no thread-local entry has 
been added to it and hence NPE.
I have a lot of tests in CXF where client-side providers have the 
contexts injected, so I think it is somehow related to the way the 
client invocation is managed by cxfrs.
I'm just curious how to reproduce it. Is there any chance that you can 
create a basic test project ? I will try to reproduce it on my own too


Sergey


On 22/01/14 03:51, David wrote:

On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang wrote:



On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote:

When my route attempts to invoke Service2, the URI is set to:

http://localhost:8080/service2/service2path/service1/service1path,
where
service1/service1path is configured in my.Service1. I'm also
not sure why
I'm providing a serviceClass for rsClient. I thought maybe it
was going to
instantiate my service, but that doesn't seem to be the case.



If you routing the response of first service to second service, you may
need to clean up the CamelHttpPath message header.



Thanks, that was very helpful, but I'm not quite there yet. Shouldn't this
header be cleared when I set inheritHeaders to false?

I had made both the first and second service have the same http path in
order to trick the camel route into working, and initially removing the
header had the desired effect -- I.e.I got a 404 response because the path
for the second service had been truncated. However, when I changed the
entry-point service back to its original path, I got an NPE (at
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)).
I fixed that by instead setting the CamelHttpPath to the path for the next
service, which worked.

Next, I added in the third service, by wiring a second rsClient for it and
duplicating the setHeader and cxfrs producer endpoint in the camel route.
This mostly works, but not quite. When the response comes back from
service2, my object is populated as expected. However, by the time the call
to service3 happens, all variables in the object have been set to 0 for the
int and null for the strings. Service3 is then called with this empty
object and returns. Finally, I again get the same NPE from Service1. I
tried resetting the CamelHttpPath to the initial value, but that didn't fix
the NPE. Removing Service3 also doesn't fix the NPE during the Service1
response, and the variables in the object are also still reset to 0/null.

Here's my route, as it stands now:



/service2/service2path  

/service3/service3path 



The same NPE I'm seeing was also seen here, apparently:

http://mail-archives.apache.org/mod_mbox/cxf-users/201311.mbox/%3c52987699.6040...@gmail.com%3E

Here's a more complete stacktrace from my logs:

--
22:38:54,309 | INFO  | tp2013341004-662 | response
| 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut,
BodyType: mycompany.MyObject, Body:
{"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}]
22:38:54,311 | WARN  | tp2013341004-662 | PhaseInterceptorChain
  | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for {
http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now
javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:396)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0]
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)[176:org.apache.cxf.cxf-rt-transports-http-jetty:

Re: Questions about cxfrs

2014-01-21 Thread David
On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang wrote:

>
> On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote:
> > > When my route attempts to invoke Service2, the URI is set to:
> > http://localhost:8080/service2/service2path/service1/service1path,
> > where
> > service1/service1path is configured in my.Service1. I'm also
> > not sure why
> > I'm providing a serviceClass for rsClient. I thought maybe it
> > was going to
> > instantiate my service, but that doesn't seem to be the case.
> >
>
> If you routing the response of first service to second service, you may
> need to clean up the CamelHttpPath message header.
>
>
Thanks, that was very helpful, but I'm not quite there yet. Shouldn't this
header be cleared when I set inheritHeaders to false?

I had made both the first and second service have the same http path in
order to trick the camel route into working, and initially removing the
header had the desired effect -- I.e.I got a 404 response because the path
for the second service had been truncated. However, when I changed the
entry-point service back to its original path, I got an NPE (at
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)).
I fixed that by instead setting the CamelHttpPath to the path for the next
service, which worked.

Next, I added in the third service, by wiring a second rsClient for it and
duplicating the setHeader and cxfrs producer endpoint in the camel route.
This mostly works, but not quite. When the response comes back from
service2, my object is populated as expected. However, by the time the call
to service3 happens, all variables in the object have been set to 0 for the
int and null for the strings. Service3 is then called with this empty
object and returns. Finally, I again get the same NPE from Service1. I
tried resetting the CamelHttpPath to the initial value, but that didn't fix
the NPE. Removing Service3 also doesn't fix the NPE during the Service1
response, and the variables in the object are also still reset to 0/null.

Here's my route, as it stands now:



/service2/service2path  

/service3/service3path 



The same NPE I'm seeing was also seen here, apparently:

http://mail-archives.apache.org/mod_mbox/cxf-users/201311.mbox/%3c52987699.6040...@gmail.com%3E

Here's a more complete stacktrace from my logs:

--
22:38:54,309 | INFO  | tp2013341004-662 | response
| 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut,
BodyType: mycompany.MyObject, Body:
{"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}]
22:38:54,311 | WARN  | tp2013341004-662 | PhaseInterceptorChain
 | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for {
http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now
javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:396)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)[150:org.apache.cxf.cxf-api:2.7.0]
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0]
at
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0]
at
org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0]
at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1077)[93:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1013)[93:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131]
at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[93:org.eclipse.jetty.aggregat

Re: Questions about cxfrs

2014-01-21 Thread Willem Jiang

On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote:
> > When my route attempts to invoke Service2, the URI is set to:  
> http://localhost:8080/service2/service2path/service1/service1path,  
> where
> service1/service1path is configured in my.Service1. I'm also  
> not sure why
> I'm providing a serviceClass for rsClient. I thought maybe it  
> was going to
> instantiate my service, but that doesn't seem to be the case.  
>  

If you routing the response of first service to second service, you may need to 
clean up the CamelHttpPath message header.

-- 
Willem Jiang

Red Hat, Inc.
Web: http://www.redhat.com
Blog: http://willemjiang.blogspot.com(http://willemjiang.blogspot.com/) 
(English)
http://jnn.iteye.com(http://jnn.javaeye.com/) (Chinese)
Twitter: willemjiang 
Weibo: 姜宁willem




Re: Questions about cxfrs

2014-01-21 Thread David
Comments in-line.


On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote:

> Hi
> Please see comments below,
>
> On 21/01/14 17:01, David wrote:
>
>> I think this is more of a Camel question than a CXF question, but let me
>> know if that's not the case (would it have been bad form to cross-post
>> this
>> to cxf-user?).
>>
>> I have questions regarding use of Jackson with CXF, as well as how to get
>> CXFRS not to wrap the root value of a JSON payload.
>>
>> I am trying to use Camel and CXF as part of a service orchestration using
>> JSON over REST. My biggest question is how to configure cxfrs to use
>> Jackson for all JSON marshal/unmarshal operations.
>>
>> So far, I've configured a cxf:rsServer and added a cxf:providers element
>> with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider
>> bean.
>> I've also added the following to my route, although I haven't found
>> anywhere to reference it yet:
>>
>>  
>>  
>>  
>>
>> I'm basically exposing the configured cxf:rsServer service as an external
>> entry-point:
>>
>> http://localhost:8182";
>> serviceClass="org.my.Service"
>> loggingFeatureEnabled="true">
>> 
>> 
>> 
>> 
>> > class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
>>
>> I'm then using a couple cxfrs producer endpoints to invoke external
>> REST/JSON services implemented using RESTEasy:
>>
>>  
>>  POST
>>  
>>  
>>  /service1/operation1
>>  
>>  
>>  application/json
>>  
>>  http://localhost:8080?exchangePattern=InOut"/>
>>  
>>  POST
>>  
>>  
>>  /service2/operation2
>>  
>>  
>>  application/json
>>  
>>  http://localhost:8080?exchangePattern=InOut"/>
>>
>>
>> The idea is that each of those services will modify the payload, and the
>> resulting object will be passed back to the caller.
>>
>> The services themselves are pretty standard. Class annotated with @Path,
>> along with a single method annotated with @POST, @Consumes and @Produces
>> (both types are set to MediaType.APPLICATION_JSON). The methods expect and
>> return a single container class with id and a couple string values.
>>
>> When I call my service, however, an exception is thrown by the code that's
>> attempting to call the cxfrs producer endpoint, saying there's no message
>> body writer for my container class and applicaiton/json. At one point I
>> had
>> it working (not sure what was different back then) and I was running into
>> issues where the CXF client code was wrapping the JSON payload (I.e.
>> {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I
>> got around it by registering a custom ContextResolver for the RESTEasy
>> services that sets the WRAP_ROOT_VALUE feature on the Jackson object
>> mapper, and adding a @JsonRootName annotation to my container class, but
>> would prefer to solve the problem by telling the CXFRS client not to wrap
>> the root value. From looking at
>> http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
>> that both rsServer and rsClient have a "features" element that I think
>> might allow me to do this, .but I can't find any documentation or examples
>> for using it.
>>
>> I hope the above made sense, and thanks in advance for your help.
>>
>>  The client-side wrapper is added by the active JSON provider which is
> Jackson in this case.


I might be doing something wrong, but that doesn't seem to be the case. It
seems to be using Jackson for the service I'm exposing using cxf:rsServer.
However, the cxfrs client endpoint (I.e. http://etc.../>)
seems to still be using Jettison. I also tried configuring a cxf:rsClient
to access one of my external services, but the paths from my configured
cxf:rsServer bean keep getting appended to the end of my URL. Are the two
beans tightly coupled somehow? I.e.

http://localhost:8182";
serviceClass="my.Service1"
loggingFeatureEnabled="true">





http://localhost:8080/service2/service2path";
serviceClass="my.Service2"
loggingFeatureEnabled="true">





When my route attempts to invoke Service2, the URI is set to:
http://localhost:8080/service2/service2path/service1/service1path, where
service1/service1path is configured in my.Service1. I'm also not sure why
I'm providing a serviceClass for rsClient. I thought maybe it was going to
instantiate my service, but that doesn't seem to be the case.




> So one option is to configure org.codehaus.jackson.jaxrs.JacksonJsonProvider
> directly in Spring to drop a root element - that should be possible. Can
> you try it ?
>

I was able to find an example for wiring a Jackson ObjectMapper bean and
providing a reference to it to the JacksonJsonProvider bean, but I need to
get my service client working before I can test it.



>
> By the way, how complex the actual sequence is ? The other alternative can
> be to use CXF JSONProvider (Jettison-based) - it is q

Re: Questions about cxfrs

2014-01-21 Thread Sergey Beryozkin

Hi
Please see comments below,
On 21/01/14 17:01, David wrote:

I think this is more of a Camel question than a CXF question, but let me
know if that's not the case (would it have been bad form to cross-post this
to cxf-user?).

I have questions regarding use of Jackson with CXF, as well as how to get
CXFRS not to wrap the root value of a JSON payload.

I am trying to use Camel and CXF as part of a service orchestration using
JSON over REST. My biggest question is how to configure cxfrs to use
Jackson for all JSON marshal/unmarshal operations.

So far, I've configured a cxf:rsServer and added a cxf:providers element
with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean.
I've also added the following to my route, although I haven't found
anywhere to reference it yet:

 
 
 

I'm basically exposing the configured cxf:rsServer service as an external
entry-point:

http://localhost:8182";
serviceClass="org.my.Service"
loggingFeatureEnabled="true">






I'm then using a couple cxfrs producer endpoints to invoke external
REST/JSON services implemented using RESTEasy:

 
 POST
 
 
 /service1/operation1
 
 
 application/json
 
 http://localhost:8080?exchangePattern=InOut"/>
 
 POST
 
 
 /service2/operation2
 
 
 application/json
 
 http://localhost:8080?exchangePattern=InOut"/>


The idea is that each of those services will modify the payload, and the
resulting object will be passed back to the caller.

The services themselves are pretty standard. Class annotated with @Path,
along with a single method annotated with @POST, @Consumes and @Produces
(both types are set to MediaType.APPLICATION_JSON). The methods expect and
return a single container class with id and a couple string values.

When I call my service, however, an exception is thrown by the code that's
attempting to call the cxfrs producer endpoint, saying there's no message
body writer for my container class and applicaiton/json. At one point I had
it working (not sure what was different back then) and I was running into
issues where the CXF client code was wrapping the JSON payload (I.e.
{"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I
got around it by registering a custom ContextResolver for the RESTEasy
services that sets the WRAP_ROOT_VALUE feature on the Jackson object
mapper, and adding a @JsonRootName annotation to my container class, but
would prefer to solve the problem by telling the CXFRS client not to wrap
the root value. From looking at
http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see
that both rsServer and rsClient have a "features" element that I think
might allow me to do this, .but I can't find any documentation or examples
for using it.

I hope the above made sense, and thanks in advance for your help.

The client-side wrapper is added by the active JSON provider which is 
Jackson in this case. So one option is to configure 
org.codehaus.jackson.jaxrs.JacksonJsonProvider directly in Spring to 
drop a root element - that should be possible. Can you try it ?


By the way, how complex the actual sequence is ? The other alternative 
can be to use CXF JSONProvider (Jettison-based) - it is quite flexible 
in the way it can shape the sequence


Sergey