Route Webservice response to a POJO without implementing any camel specific interface - cxf

I am routing my webservice request to a bean which sends the response back to the service.
<camel:from uri="cxf:bean:authTest" />
<camel:to uri="bean:routeExitResponseProcessor"/>
Now in the bean class I have to implement Processor interface, access the Exchange object , call the implementation method and then send the response back to the client by setting the response object to exchange's body.
Can I get rid of all the Camel specific java code and configure everything in my applicationContext.xml?

If you use the bean component you do not have to implement the Processor interface.
If your class simply has one public method then it will be called and camel will try to convert the incoming body to your parameter and process the return as new body.
Try with a method like:
WebServiceResult myMethod(WebServiceInput input) {...}
Where the Parameters are those generated from the wsdl.
Christian

Related

Difference between #JMSListener and #Consume annotations?

I am trying to consume JMS messages sent via spring JmsTemplate using #Consume annotated bean. The consumer is not receiving messages when sent using JmsTemplate.
Whereas, when sent using ProducerTemplate of Camel the messages are received.
What is the difference between #org.springframework.jms.annotation.JmsListener and #org.apache.camel.Consume?
Producer Logic
jmsTemplate.convertAndSend("jms:mailbox", message);
Consumer Logic
#Consume(uri="jms:mailbox")
public void onRequest(String name) {
System.out.println("Received message > "+name);
}
Apache Camel #Consume annotation can consume from any endpoint, which supports consuming. This annotation takes uri as parameter. URI consists of scheme, path and optional params. In case of JMS component the scheme is jms, path is Destination (in your case mailbox) and params are additional options customizing behavior of Consumer.
Spring #JmsListener can consume from JMS and takes Destination as parameter.
Your code does not work because the Destination is mailbox, not jms:mailbox. Spring JmsTemplate does not know about jms scheme, it is Camel specific. So use jmsTemplate.convertAndSend("mailbox", message) on Spring side and #Consume(uri="jms:mailbox") on Camel side.

Intercept routes without tracing

The application I'm working on is a middleware app that allows routing among tons of applications (mostly SOAP services).
We encountered saturation because of the automatic logs generated by Camel.
The log volume was reduced with the new interceptors. However, if a service is called inside a current route, all I got is the Request Body from the SendToEndpoint interceptor.
Given that all service calls in the application was made that way, I can not change the current routes.
Old interceptors:
getContext().setTracing(true); // <--- trace every step of all routes
interceptFrom().to("log:example");
configureRoutes() {
// route logic
}
New interceptors:
getContext().setTracing(false);
interceptFrom("cxf:*").to("log:example");
interceptSendToEndpoint("cxf:*").to("log:example");
configureRoutes() {
// route logic
}
Example of a route :
from("scheduler endpoint")
.to("DAO method to find the case from database")
.process(//First processor to call the SOAP service)
.to("SOAP endpoint")
.convertBodyTo(SOAP ResponseBody.class) <-- convert the MessageContentsList to SOAP response body generated from the WSDL
.process(//Second processor to check if the response code is OK in the SOAP response body);
How can I implement an interceptor that allows to log also the SOAP response body ?
Thank you for your help.
I dislike to use interceptors to this porpoise, I suggest you to use the EventNotifier interface, you just need to declare it as a bean in camel context and override the notify method.
See: https://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/spi/EventNotifier.html
Here is an usage example: http://camel.apache.org/eventnotifier-to-log-details-about-all-sent-exchanges.html
Note: Camel has some events that you can uss like: CamelContextCreated, ExchangeCreatedEvent, ExchangeSendingEvent, ExchangeSentEvent, ExchangeCompletedEvent, ExchangeFailedEvent, etc.

Intercepting cxf web service header with Apache Camel (Java DSL)

I created a web service client to handle cxf soap web services with apache camel.
String serviceUri = "cxf:http://localhost:10000/myservice?serviceClass=" +
MyRequest.class.getCanonicalName();
from(uri).to("mock:xyz");
The web service receives the soap call but throws an exception since the request requires a handling for wss.
org.apache.cxf.binding.soap.SoapFault: MustUnderstand headers: [{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood.
The reason is, that the service requires ws security, which can be seen by lloking at the request.
<SOAP-ENV:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1">
I found out that I need to implement an interceptor to handle header properties.
My questions:
How can I add an interceptor to handle the header attributes with Camel Java-DSL?
Will this be sufficient to get rid of the SOAP Fault?
You can do it through
cxfEndpointConfigurer option #see: Camel-CXF configuration
(I use Spring (it is much easier)), but I guess for DSL URI will look like:
String serviceUri = "cxf:http://localhost:10000/myservice?serviceClass=" +
MyRequest.class.getCanonicalName() +
"&cxfEndpointConfigurer="+ MyConfigurer.class.getCanonicalName();
by implementing org.apache.camel.component.cxf.CxfEndpointConfigurer you have ability to add an Interceptor inside configureServer method
server.getEndpoint().getInInterceptors().add(new MyJAASLoginInterceptor());
if you run your Camel in container with JAAS (like JBOSS) you can use extension from
org.apache.cxf.interceptor.security.JAASLoginInterceptor
with needed callback handler.
Simple example which validates user/password from WSS header against JBOSS users:
public class MyJAASLoginInterceptor extends javax.security.auth.callback.JAASLoginInterceptor {
#Override
protected CallbackHandler getCallbackHandler(String name, String password) {
return new org.apache.cxf.interceptor.security.NamePasswordCallbackHandler(name, password, "setCredential");
}
}

camel invoke third party webservice

I am new to the Fuse-camel,cxf.
i wan to invoke third party webservice. i don't want to use wsld2java or serviceclass. I have a wsdl.
Here is the requirement to make generic webservice call
json request data-->generate soap request --> cxf:endpoint in PAYLOAD format-->soap response -->json response data to client.
1 . how do i convert json to soaprequest(xml) and vice-versa ( Marshall-format-soapjxab is expecting jaxb annotated classes)
2.how do I call in soap in payload mode..
any help (link/example) is greatly appreciated.
Thanks,
Narendra
You can use Camel CXFRS to set up rest endpoints.
On parsing the JSON, set the values to JAXB annotated POJO's.
Then use ProducerTemplate to send SOAP request to third party service.
On receiving the response you can unmarshal it, either using JAXB unmarshaller in java code or incase of DSL use Camel JAXB DataFormat
Route the response to the client by setting the content in camel exchange.

Invoking a rest service passing dynamic key value parameters using cxf-rs components

I have to create a Fuse service which would in-turn invoke a REST service exposed by an external service provider. Fuse service will be receiving request in XML format and converting to a query string before invoking the REST service.
Sample request XML for Fuse service -
<CustomerDetails>
<CustomerName>ABC</CustomerName>
<CustomerAge>28</CustomerAge>
<CustomerName>DEF</CustomerName>
<CustomerAge>54</CustomerAge>
<CustomerDetails>
The REST service consumes request in key value params and responds back in XML format.
sample URL:
https://www.customer.com/cust/api/v1/store/abc.xml?Customername=ABC&Customerage=28&Customername=DEF&customerage=54)
I have tried searching a lot but couldn't find any tutorial in the net.
Can someone please provide suggestions on how to implement the fuse service using cxf-rs components (preferably Spring DSL camel configuration )
Thanks in advance..
If you just want to turn the XML request to the url parameter, you can just use jaxb data format to unmarshal the request and use a bean object to setup the URI request parameters. You don't need to use camel-cxf component.
from("direct:start").unmarshal(jaxb).process(new Processor() {
public void process(Exchange exchange) throws Exception {
// get the request object
CustomerDetail request = exchange.getIn().getBody();
// Just mapping the request object into a query parameters.
String query = requestToParameter(request);
exchange.getIn().setHeader(Exchange.HTTP_QUERY, query);
// to remove the body, so http endpoint can send the request with Get Method
exchange.getIn().setBody(null);
}).to("https://www.customer.com/cust/api/v1/store/abc.xml");

Resources