Quantcast

NoTypeConversionAvailableException : When using interface as Apache Camel Proxy

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

NoTypeConversionAvailableException : When using interface as Apache Camel Proxy

anand_tech
I have an interface which I am using as  Camel Proxy. My route is as below:

    from("direct:services")
    .onException(Exception.class)
    .process(new Processor() {
    @Override
    public void process(Exchange arg0) throws Exception {
    Exception e = arg0.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
    LOGGER.error(e, e.getMessage());
    }
    }).handled(true).end()
    .setHeader(Exchange.HTTP_URI, simple("${body.url}"))
    .setHeader(Exchange.HTTP_METHOD,simple("${body.httpMethod}"))
    .setHeader(Exchange.CONTENT_TYPE, simple("${body.contentType}"))
    .setBody(simple("${body.requestBody}"))
    .choice()
    .when(simple("${body.proxyRequired} == 'true'"))
    .inOut("{{http.urlProxy}}")
    .otherwise()
    .inOut("{{http.url}}")
    .end()
    .setBody(bean(appUtil, "extractResponse"));


The interface is :

    public interface ApiServices {
   
    ServiceProviderResponse performOperation(ServiceProviderRequest request);
   
    }

And the ServiceProviderResponse and ServiceProviderRequest classes :

    public class ServiceProviderRequest {
   
    private String url;
    private String requestBody;
    private String httpMethod;
    private String contentType;
    private boolean proxyRequired;
    private Map<String, String> headers;
   
    //getters and setters
   
    }

    public class ServiceProviderResponse {
   
    private int statusCode;
    private String body;
    private String errorMessage;
    private String contentType;
    private String url;
   
    //getters and setters
    }

This is how this whole thing is working :

    @Produce(uri = "direct:services")
    ApiServices appServices;
   
    ServiceProviderResponse response =  appServices.performOperation(request);

Earlier my interface's method was : `ServiceProviderResponse performOperation(String url);` and it worked fine(ofcourse my route was different earlier). So is it something that we cannot use custom object types like this? The exception that I get :

    Caused by: org.apache.camel.InvalidPayloadException: No body available of type: com.common.util.ServiceProviderResponse but has value: BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]] of type: org.apache.camel.component.bean.BeanInvocation on: Message: BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]]. Caused by: No type converter available to convert from type: org.apache.camel.component.bean.BeanInvocation to the required type: com.common.util.ServiceProviderResponse with value BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]]. Exchange[Message: BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]]]. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: org.apache.camel.component.bean.BeanInvocation to the required type: com.common.util.ServiceProviderResponse with value BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]]]
    at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:102)
    at org.apache.camel.component.bean.AbstractCamelInvocationHandler.getBody(AbstractCamelInvocationHandler.java:58)
    at org.apache.camel.component.bean.AbstractCamelInvocationHandler.afterInvoke(AbstractCamelInvocationHandler.java:148)
    at org.apache.camel.component.bean.AbstractCamelInvocationHandler$1.call(AbstractCamelInvocationHandler.java:85)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at org.apache.camel.component.bean.AbstractCamelInvocationHandler.invokeWithbody(AbstractCamelInvocationHandler.java:101)
    at org.apache.camel.component.bean.CamelInvocationHandler.invoke(CamelInvocationHandler.java:44)
    ... 43 more
    Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.apache.camel.component.bean.BeanInvocation to the required type: com.common.util.ServiceProviderResponse with value BeanInvocation public abstract com.common.util.ServiceProviderResponse com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest) with [com.common.util.ServiceProviderRequest@4ce55b]]
    at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:147)
    at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:100)
    ... 50 more

Exception says something about TypeConverters, do I need to implement a type converter also now ? If yes how to do it? I have already gone through Camel docs for type converter but I dont understand from it much.
Also I guess most of you have understood what I want to achieve, so if you guys have any different methods to accomplish this or some suggestions, please post it.


 

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NoTypeConversionAvailableException : When using interface as Apache Camel Proxy

Willem.Jiang
What's the appUtil.extractResponse looks like?

Did you try to converter the message body into ServiceProviderRequest?

--  
Willem Jiang

Red Hat, Inc.
FuseSource is now part of Red Hat
Web: http://www.fusesource.com | 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





On Tuesday, December 11, 2012 at 2:03 PM, anand_tech wrote:

> I have an interface which I am using as Camel Proxy
> <http://camel.apache.org/using-camelproxy.html> . My route is as below:
>  
> from("direct:services")
> .onException(Exception.class)
> .process(new Processor() {
> @Override
> public void process(Exchange arg0) throws Exception {
> Exception e = arg0.getProperty(Exchange.EXCEPTION_CAUGHT,
> Exception.class);
> LOGGER.error(e, e.getMessage());
> }
> }).handled(true).end()
> .setHeader(Exchange.HTTP_URI, simple("${body.url}"))
> .setHeader(Exchange.HTTP_METHOD,simple("${body.httpMethod}"))
> .setHeader(Exchange.CONTENT_TYPE, simple("${body.contentType}"))
> .setBody(simple("${body.requestBody}"))
> .choice()
> .when(simple("${body.proxyRequired} == 'true'"))
> .inOut("{{http.urlProxy}}")
> .otherwise()
> .inOut("{{http.url}}")
> .end()
> .setBody(bean(appUtil, "extractResponse"));
>  
>  
> The interface is :  
>  
> public interface ApiServices {
>  
> ServiceProviderResponse performOperation(ServiceProviderRequest
> request);
>  
> }
>  
> And the ServiceProviderResponse and ServiceProviderRequest classes :  
>  
> public class ServiceProviderRequest {
>  
> private String url;
> private String requestBody;
> private String httpMethod;
> private String contentType;
> private boolean proxyRequired;
> private Map<String, String> headers;
>  
> //getters and setters
>  
> }
>  
> public class ServiceProviderResponse {
>  
> private int statusCode;
> private String body;
> private String errorMessage;
> private String contentType;
> private String url;
>  
> //getters and setters
> }
>  
> This is how this whole thing is working :  
>  
> @Produce(uri = "direct:services")
> ApiServices appServices;
>  
> ServiceProviderResponse response =  
> appServices.performOperation(request);
>  
> Earlier my interface's method was : `ServiceProviderResponse
> performOperation(String url);` and it worked fine(ofcourse my route was
> different earlier). So is it something that we cannot use custom object
> types like this? The exception that I get :  
>  
> Caused by: org.apache.camel.InvalidPayloadException: No body available
> of type: com.common.util.ServiceProviderResponse but has value:
> BeanInvocation public abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]] of type:
> org.apache.camel.component.bean.BeanInvocation on: Message: BeanInvocation
> public abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]]. Caused by: No type
> converter available to convert from type:
> org.apache.camel.component.bean.BeanInvocation to the required type:
> com.common.util.ServiceProviderResponse with value BeanInvocation public
> abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]]. Exchange[Message:
> BeanInvocation public abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]]]. Caused by:
> [org.apache.camel.NoTypeConversionAvailableException - No type converter
> available to convert from type:
> org.apache.camel.component.bean.BeanInvocation to the required type:
> com.common.util.ServiceProviderResponse with value BeanInvocation public
> abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]]]
> at
> org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:102)
> at
> org.apache.camel.component.bean.AbstractCamelInvocationHandler.getBody(AbstractCamelInvocationHandler.java:58)
> at
> org.apache.camel.component.bean.AbstractCamelInvocationHandler.afterInvoke(AbstractCamelInvocationHandler.java:148)
> at
> org.apache.camel.component.bean.AbstractCamelInvocationHandler$1.call(AbstractCamelInvocationHandler.java:85)
> at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
> at java.util.concurrent.FutureTask.run(Unknown Source)
> at
> org.apache.camel.component.bean.AbstractCamelInvocationHandler.invokeWithbody(AbstractCamelInvocationHandler.java:101)
> at
> org.apache.camel.component.bean.CamelInvocationHandler.invoke(CamelInvocationHandler.java:44)
> ... 43 more
> Caused by: org.apache.camel.NoTypeConversionAvailableException: No type
> converter available to convert from type:
> org.apache.camel.component.bean.BeanInvocation to the required type:
> com.common.util.ServiceProviderResponse with value BeanInvocation public
> abstract com.common.util.ServiceProviderResponse
> com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> with [com.common.util.ServiceProviderRequest@4ce55b]]
> at
> org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:147)
> at
> org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:100)
> ... 50 more
>  
> Exception says something about TypeConverters, do I need to implement a type
> converter also now ? If yes how to do it? I have already gone through Camel
> docs for type converter but I dont understand from it much.
> Also I guess most of you have understood what I want to achieve, so if you
> guys have any different methods to accomplish this or some suggestions,
> please post it.
>  
>  
>  
>  
>  
>  
>  
> --
> View this message in context: http://camel.465427.n5.nabble.com/NoTypeConversionAvailableException-When-using-interface-as-Apache-Camel-Proxy-tp5723880.html
> Sent from the Camel - Users mailing list archive at Nabble.com (http://Nabble.com).



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NoTypeConversionAvailableException : When using interface as Apache Camel Proxy

Willem.Jiang
I just did a simple test[1] based on the description, you need to make sure you setup the message body rightly as a response.
Please check out the test case[1] as an example.

[1]http://svn.apache.org/viewvc?rev=1420015&view=rev 

--  
Willem Jiang

Red Hat, Inc.
FuseSource is now part of Red Hat
Web: http://www.fusesource.com | 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





On Tuesday, December 11, 2012 at 2:59 PM, Willem jiang wrote:

> What's the appUtil.extractResponse looks like?
>  
> Did you try to converter the message body into ServiceProviderRequest?
>  
> --  
> Willem Jiang
>  
> Red Hat, Inc.
> FuseSource is now part of Red Hat
> Web: http://www.fusesource.com | 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
>  
>  
>  
>  
>  
> On Tuesday, December 11, 2012 at 2:03 PM, anand_tech wrote:
>  
> > I have an interface which I am using as Camel Proxy
> > <http://camel.apache.org/using-camelproxy.html> . My route is as below:
> >  
> > from("direct:services")
> > .onException(Exception.class)
> > .process(new Processor() {
> > @Override
> > public void process(Exchange arg0) throws Exception {
> > Exception e = arg0.getProperty(Exchange.EXCEPTION_CAUGHT,
> > Exception.class);
> > LOGGER.error(e, e.getMessage());
> > }
> > }).handled(true).end()
> > .setHeader(Exchange.HTTP_URI, simple("${body.url}"))
> > .setHeader(Exchange.HTTP_METHOD,simple("${body.httpMethod}"))
> > .setHeader(Exchange.CONTENT_TYPE, simple("${body.contentType}"))
> > .setBody(simple("${body.requestBody}"))
> > .choice()
> > .when(simple("${body.proxyRequired} == 'true'"))
> > .inOut("{{http.urlProxy}}")
> > .otherwise()
> > .inOut("{{http.url}}")
> > .end()
> > .setBody(bean(appUtil, "extractResponse"));
> >  
> >  
> > The interface is :  
> >  
> > public interface ApiServices {
> >  
> > ServiceProviderResponse performOperation(ServiceProviderRequest
> > request);
> >  
> > }
> >  
> > And the ServiceProviderResponse and ServiceProviderRequest classes :  
> >  
> > public class ServiceProviderRequest {
> >  
> > private String url;
> > private String requestBody;
> > private String httpMethod;
> > private String contentType;
> > private boolean proxyRequired;
> > private Map<String, String> headers;
> >  
> > //getters and setters
> >  
> > }
> >  
> > public class ServiceProviderResponse {
> >  
> > private int statusCode;
> > private String body;
> > private String errorMessage;
> > private String contentType;
> > private String url;
> >  
> > //getters and setters
> > }
> >  
> > This is how this whole thing is working :  
> >  
> > @Produce(uri = "direct:services")
> > ApiServices appServices;
> >  
> > ServiceProviderResponse response =  
> > appServices.performOperation(request);
> >  
> > Earlier my interface's method was : `ServiceProviderResponse
> > performOperation(String url);` and it worked fine(ofcourse my route was
> > different earlier). So is it something that we cannot use custom object
> > types like this? The exception that I get :  
> >  
> > Caused by: org.apache.camel.InvalidPayloadException: No body available
> > of type: com.common.util.ServiceProviderResponse but has value:
> > BeanInvocation public abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]] of type:
> > org.apache.camel.component.bean.BeanInvocation on: Message: BeanInvocation
> > public abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]]. Caused by: No type
> > converter available to convert from type:
> > org.apache.camel.component.bean.BeanInvocation to the required type:
> > com.common.util.ServiceProviderResponse with value BeanInvocation public
> > abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]]. Exchange[Message:
> > BeanInvocation public abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]]]. Caused by:
> > [org.apache.camel.NoTypeConversionAvailableException - No type converter
> > available to convert from type:
> > org.apache.camel.component.bean.BeanInvocation to the required type:
> > com.common.util.ServiceProviderResponse with value BeanInvocation public
> > abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]]]
> > at
> > org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:102)
> > at
> > org.apache.camel.component.bean.AbstractCamelInvocationHandler.getBody(AbstractCamelInvocationHandler.java:58)
> > at
> > org.apache.camel.component.bean.AbstractCamelInvocationHandler.afterInvoke(AbstractCamelInvocationHandler.java:148)
> > at
> > org.apache.camel.component.bean.AbstractCamelInvocationHandler$1.call(AbstractCamelInvocationHandler.java:85)
> > at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
> > at java.util.concurrent.FutureTask.run(Unknown Source)
> > at
> > org.apache.camel.component.bean.AbstractCamelInvocationHandler.invokeWithbody(AbstractCamelInvocationHandler.java:101)
> > at
> > org.apache.camel.component.bean.CamelInvocationHandler.invoke(CamelInvocationHandler.java:44)
> > ... 43 more
> > Caused by: org.apache.camel.NoTypeConversionAvailableException: No type
> > converter available to convert from type:
> > org.apache.camel.component.bean.BeanInvocation to the required type:
> > com.common.util.ServiceProviderResponse with value BeanInvocation public
> > abstract com.common.util.ServiceProviderResponse
> > com.common.util.ApiServices.performOperation(com.common.util.ServiceProviderRequest)
> > with [com.common.util.ServiceProviderRequest@4ce55b]]
> > at
> > org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:147)
> > at
> > org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:100)
> > ... 50 more
> >  
> > Exception says something about TypeConverters, do I need to implement a type
> > converter also now ? If yes how to do it? I have already gone through Camel
> > docs for type converter but I dont understand from it much.
> > Also I guess most of you have understood what I want to achieve, so if you
> > guys have any different methods to accomplish this or some suggestions,
> > please post it.
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> > --
> > View this message in context: http://camel.465427.n5.nabble.com/NoTypeConversionAvailableException-When-using-interface-as-Apache-Camel-Proxy-tp5723880.html
> > Sent from the Camel - Users mailing list archive at Nabble.com (http://Nabble.com).
>  



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: NoTypeConversionAvailableException : When using interface as Apache Camel Proxy

anand_tech
Ok i will have a look at your unit tests. For the timing the AppUtil extract response code is :

public ServiceProviderResponse extractResponse(Exchange exchange){
                ServiceProviderResponse response = new ServiceProviderResponse();
                Message inMessage = exchange.getIn();
                int statusCode = (inMessage.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class));
                response.setStatusCode(statusCode);
                response.setUrl(inMessage.getHeader(Exchange.HTTP_URI, String.class));
                if(statusCode >= Status.BAD_REQUEST.getStatusCode()){
                        response.setErrorMessage(inMessage.getBody(String.class));
                }else{
                        response.setBody(inMessage.getBody(String.class));
                }
                return response;
        }

The whole working is -  i give a service provider request object in my route and then extract url, content type , HTTP method etc. from it and then make a HTTP request to some third party server. After receiving HTTP response from third party server i convert it into the Service Provider Response object(as above).
Loading...