camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Questions about cxfrs
Date Thu, 23 Jan 2014 10:17:16 GMT
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 <sberyozkin@gmail.com>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 <sberyozkin@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:
>>>>>
>>>>>        <dataFormats>
>>>>>            <json library="Jackson" id="jack"/>
>>>>>        </dataFormats>
>>>>>
>>>>> I'm basically exposing the configured cxf:rsServer service as an
>>>>> external
>>>>> entry-point:
>>>>>
>>>>> <cxf:rsServer id="processService" address="http://localhost:8182"
>>>>> serviceClass="org.my.Service"
>>>>> loggingFeatureEnabled="true">
>>>>> <cxf:providers>
>>>>> <ref component-id="jsonProvider" />
>>>>> </cxf:providers>
>>>>> </cxf:rsServer>
>>>>> <bean id="jsonProvider"
>>>>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
>>>>>
>>>>> I'm then using a couple cxfrs producer endpoints to invoke external
>>>>> REST/JSON services implemented using RESTEasy:
>>>>>
>>>>>            <setHeader headerName="CamelHttpMethod">
>>>>>                <simple>POST</simple>
>>>>>            </setHeader>
>>>>>            <setHeader headerName="CamelHttpPath">
>>>>>                <simple>/service1/operation1</simple>
>>>>>            </setHeader>
>>>>>            <setHeader headerName="Content-Type">
>>>>>                <simple>application/json</simple>
>>>>>            </setHeader>
>>>>>            <to uri="cxfrs:http://localhost:8080?exchangePattern=InOut"/>
>>>>>            <setHeader headerName="CamelHttpMethod">
>>>>>                <simple>POST</simple>
>>>>>            </setHeader>
>>>>>            <setHeader headerName="CamelHttpPath">
>>>>>                <simple>/service2/operation2</simple>
>>>>>            </setHeader>
>>>>>            <setHeader headerName="Content-Type">
>>>>>                <simple>application/json</simple>
>>>>>            </setHeader>
>>>>>            <to uri="cxfrs: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. <to uri="cxfrs: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.
>>>
>>> <cxf:rsServer id="processService" address="http://localhost:8182"
>>> serviceClass="my.Service1"
>>> loggingFeatureEnabled="true">
>>> <cxf:providers>
>>> <ref component-id="jsonProvider" />
>>> </cxf:providers>
>>> </cxf:rsServer>
>>>
>>> <cxf:rsClient id="auditService"
>>> address="http://localhost:8080/service2/service2path"
>>> serviceClass="my.Service2"
>>> loggingFeatureEnabled="true">
>>> <cxf:providers>
>>> <ref component-id="jsonProvider" />
>>> </cxf:providers>
>>> </cxf:rsClient>
>>>
>>> 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 flexible in the
>>>> way it can shape the sequence
>>>>
>>>
>>>
>>> I would rather avoid using Jettison for JSON because of the intermediate
>>> JAXB marshal step it performs. I would also like to avoid annotating my
>>> domain classes with @XmlRootElement (or any other annotation, for that
>>> matter). I'm open to using Jettison, however, if it will allow me to
>>> accomplish what I want.
>>>
>>> the sequence is very simple. I basically included the entire camel route
>>> in
>>> my original message. I have a camelContext which contains the dataFormat
>>> configuration for JSON that I posted, along with a route that contains the
>>> two jaxrs calls I posted in the original message (all that was missing
>>> from
>>> that route was the <route></route>. I also have that rsServer bean
with
>>> the
>>> JSON provider wired in, and have now added a rsClient that I tried to use
>>> in my route, but it failed as described above. I'm open to trying
>>> something
>>> that is simpler than what I have been doing.
>>>
>>>
>>>
>>>
>>>
>>>>
>>>> Sergey
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>>
>



Mime
View raw message