Aujourd’hui nous verrons comment publier un web service depuis Camel. Il y a plusieurs façons de le faire.
En fait c’est très simple avec Spring. Cependant, ça l’est moins quand il faut traiter une requête entrante et déclencher le bon routage en fonction de la méthode invoquée.Il faut donc tester une en-tête du message qui contient la méthode invoquée. Pour se faire, il y a deux méthodes. Nous allons faire tourner le tout sur un Tomcat (cf article précédent).
Prenons donc cette belle interface représentant notre non moins magnifique service :
package org.giwi.camel.ws; import javax.jws.WebParam; import javax.jws.WebResult; @javax.jws.WebService(name = "sayHelloService", targetNamespace = "https://giwi.free.fr") public interface SayHelloService { @WebResult(name = "status") public String sayHello(@WebParam(name = "name") String name); @WebResult(name = "status") public String sayGoodby(@WebParam(name = "name") String name); }
Et ce splendide ApplicationContext.xml :
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:sec="http://cxf.apache.org/configuration/security" xsi:schemaLocation=" http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <!-- needed cxf imports --> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> <!-- use the CXF servlet --> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <!-- Déclaration des routes camel à éxécuter --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <package>org.giwi.camel.route</package> </camelContext> </beans>
La première consiste à utiliser l’EIP « Content Based Router » :
package org.giwi.camel.route; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.cxf.CxfConstants; public class SayHelloRoute extends RouteBuilder { @Override public void configure() throws Exception { from("cxf:/helloService?serviceClass=org.giwi.camel.ws.SayHelloService") .choice() .when(header(CxfConstants.OPERATION_NAME).isEqualTo("sayHello")) .to("direct:sayHello1") .when(header(CxfConstants.OPERATION_NAME).isEqualTo("sayGoodby")) .to("direct:sayGoodBy1") .otherwise().throwException(new Exception("unknown method")); from("direct:sayHello1").process(new Processor() { @Override public void process(Exchange ex) throws Exception { ex.getOut().setBody("hello"); } }); from("direct:sayGoodBy1").process(new Processor() { @Override public void process(Exchange ex) throws Exception { ex.getOut().setBody("goodby"); } }); } }
Bref, c’est un peu lourd. La seconde méthode consiste à utiliser l’EIP « Recipient List » :
package org.giwi.camel.route; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; public class SayBetterHello extends RouteBuilder { @Override public void configure() throws Exception { from("cxf:/helloBetterService?serviceClass=org.giwi.camel.ws.SayHelloService") .recipientList(simple("direct:${header.operationName}2")); from("direct:sayHello2").process(new Processor() { @Override public void process(Exchange ex) throws Exception { ex.getOut().setBody("hello"); } }); from("direct:sayGoodby2").process(new Processor() { @Override public void process(Exchange ex) throws Exception { ex.getOut().setBody("goodby"); } }); } }
Plus simple, non?