camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David <wakarima...@gmail.com>
Subject Re: Questions about cxfrs
Date Thu, 23 Jan 2014 14:27:36 GMT
Thanks for the suggestion, I'll look into it as a temporary workaround.


On Thu, Jan 23, 2014 at 5:17 AM, Sergey Beryozkin <sberyozkin@gmail.com>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 <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
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message