camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Raible <m...@raibledesigns.com>
Subject Re: Making a CXF Endpoint backwards compatible
Date Tue, 27 May 2014 23:24:44 GMT
I finally got this figured out - without the need to call .marshal or use camel-soap.

Basically, I had to add a number of annotations to get names to match, and then do a bit of
nesting on the response so it was understood. A lot of the names didn't seem to matter, but
I wanted to make the new response as close to the old one as possible.

Using http://www.charlesproxy.com/ was the biggest help - as it let me see the response was
in a soap envelop.

Cheers,

Matt

On May 27, 2014, at 1:59 PM, Matt Raible <matt@raibledesigns.com> wrote:

> I've made good progress on getting this to work, mostly by adding annotations to my service
interface. Everything is working as far as calling the service from my test. I did have to
change from ClientProxyFactoryBean to JaxWsProxyFactoryBean and set the binding to match the
@BindingType(SOAPBinding.SOAP12HTTP_BINDING) in my service.
> 
> 		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
> 		factory.setBindingId("http://schemas.xmlsoap.org/wsdl/soap12/");
> 
> Now I'm having issues getting the response wrapped in a soap envelop. 
> 
> Here's what I'm doing to try and marshal the response.
> 
> 	SoapJaxbDataFormat soap = new SoapJaxbDataFormat("com.company.app.model",
> 			new ServiceInterfaceStrategy(FooService.class, false));
> 
> 	....
> 
> 				.process(new Processor() {
> 					public void process(Exchange exchange) throws Exception {
> 						// get the value from the input
> 						List<HashMap> data = (ArrayList<HashMap>) exchange.getIn().getBody();
> 						// todo: handle value is empty
> 						FooResponse response = new FooResponse();
> 						response.setGpi(String.valueOf(data.get(0).get("value")));
> 						exchange.getOut().setBody(response);
> 					}
> 				})
> 				.marshal(soap);
> 
> The error I'm getting is:
> 
> java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object;
> 	at org.apache.camel.component.cxf.DefaultCxfBinding.populateCxfResponseFromExchange(DefaultCxfBinding.java:353)
> 	at org.apache.camel.component.cxf.CxfConsumer$1.setResponseBack(CxfConsumer.java:210)
> 	at org.apache.camel.component.cxf.CxfConsumer$1.asyncInvoke(CxfConsumer.java:109)
> 	at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:74)
> 
> Do I have to register a type converter or something to help put the response body in
a SOAP envelop?
> 
> Thanks,
> 
> Matt
> 
> On May 23, 2014, at 9:04 AM, Matt Raible <matt@raibledesigns.com> wrote:
> 
>> Hey all,
>> 
>> I have a route that produces a CXF Endpoint. 
>> 
>> public class FooRoute extends RouteBuilder {
>> 
>> 	private String uri = "cxf:/foo?serviceClass=" + FooService.class.getName();
>> 
>> 	@Override
>> 	public void configure() throws Exception {
>> 		from(uri)
>> 				.to("log:input")
>> 						// send the request to the route to handle the operation
>> 						// the name of the operation is in that header
>> 				.recipientList(simple("direct:${header.operationName}"));
>> 		from("direct:findById")
>> 				.process(new Processor() {
>> 					public void process(Exchange exchange) throws Exception {
>> 						// get the id from the input
>> 						String id = exchange.getIn().getBody(FooRequest.class).getId();
>> 						exchange.getOut().setBody(id);
>> 					}
>> 				})
>> 				.to("sql:select value from table where id = #?dataSource=ds")
>> 				.to("log:output")
>> 				.process(new Processor() {
>> 					public void process(Exchange exchange) throws Exception {
>> 						// get the value from the input
>> 						List<HashMap> data = (ArrayList<HashMap>) exchange.getIn().getBody();
>> 						// todo: handle value is empty
>> 						FooResponse response = new FooResponse();
>> 						response.setGpi(String.valueOf(data.get(0).get("value")));
>> 						exchange.getOut().setBody(response);
>> 					}
>> 				}).end();
>> 	}
>> }
>> 
>> This is easy to talk to thanks to CXF's ClientFactoryBean, allowing me to call methods
directly on the interface.
>> 
>> 	protected static FooService createCXFClient() {
>> 		// we use CXF to create a client for us as its easier than JAXWS and works
>> 		ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
>> 		factory.setServiceClass(FooService.class);
>> 		factory.setAddress(URL);
>> 		return (FooService) factory.create();
>> 	}
>> 
>> One of the things I'd like to do is make this new service backwards-compatible with
the old one. In other words, I should be able to change the endpoint URL in the existing client
and everything works the same. The existing client uses the javax.xml.soap API to talk to
the service. Below is a test I wrote that shows how it works. Is it possible to modify my
route/endpoint so this WS call will work?
>> 
>> SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
>> SOAPMessage message = MessageFactory.newInstance("SOAP 1.2 Protocol").createMessage();
>> SOAPPart soapPart = message.getSOAPPart();
>> SOAPEnvelope envelope = soapPart.getEnvelope();
>> envelope.addNamespaceDeclaration("soap", "http://www.w3.org/2003/05/soap-envelope");
>> envelope.addNamespaceDeclaration("ax22", "http://common.app.company.com/xsd");
>> SOAPBody body = envelope.getBody();
>> body.addNamespaceDeclaration("m", "http://ws.app.company.com");
>> 
>> ByteArrayOutputStream request = new ByteArrayOutputStream();
>> message.writeTo(request);
>> 
>> SOAPElement bodyChildOne = body.addChildElement("CompanyFooRequest", "m");
>> SOAPElement bodyChildTwo = bodyChildOne.addChildElement("args0", "m");
>> bodyChildTwo.addChildElement("ID", "ax22").addTextNode("123456");
>> SOAPMessage reply = connection.call(message, "http://localhost:7800/axis2/services/CompanyFooService_2_0");
>> if (reply != null) {
>> 	Iterator itr = reply.getSOAPBody().getChildElements();
>> 	Map resultMap = TestUtils.getResults(itr); // TestUtils loops through SOAPElements
to create a map
>> 	assertEquals("6610012", resultMap.get("value"));
>> }
>> 
>> Thanks,
>> 
>> Matt
>> 
> 


Mime
View raw message