I created a simple web service using CXF that has MTOM enabled, it also expects a time stamp and the body to be signed, it configured like this:
#ComponentScan(basePackageClasses={MyService.class})
#Configuration
#ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CXFConfig {
#Autowired
Bus cxfBus;
#Autowired
MyService ws;
#Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(cxfBus, ws);
endpoint.publish("/MyService");
SOAPBinding binding = (SOAPBinding)endpoint.getBinding();
binding.setMTOMEnabled(true);
Map<String, Object> inProps = new HashMap<String, Object>();
inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE+" "+WSHandlerConstants.TIMESTAMP);
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "wsserver.properties");
WSS4JInInterceptor inc = new WSS4JInInterceptor(inProps);
endpoint.getInInterceptors().add(inc);
return endpoint;
}
}
My Service Interface is:
#WebService
#Component
public interface MyService {
#WebMethod(action="doStuff")
public String doStuff(#WebParam(name="FileData") MTOMMessage message) throws IOException;
}
My Data Type is:
#XmlType
#XmlAccessorType(XmlAccessType.FIELD)
public class MTOMMessage {
#XmlElement(name = "data", required = true)
#XmlMimeType("text/xml")
protected DataHandler data;
#XmlElement(name = "FileName", required = true)
protected String fileName;
//Getters and Setters
}
I then have a client to call it:
public static void main(String[] args) throws IOException {
String xmlLoc = "classpath:com/avum/dasn/ws/test/client-context.xml";
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(xmlLoc);
MyService svc = ctx.getBean(MyService.class);
MTOMMessage msg = new MTOMMessage();
msg.setXmlData(new DataHandler(getURLForTestFile()));
msg.setFileName("TestFileName");
System.out.println(svc.doStuff(msg));
}
The client-context.xml looks like this:
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature Timestamp"/>
<entry key="signaturePropFile" value="wsclient.properties"/>
<entry key="user" value="ws-security" />
<entry key="passwordCallbackClass" value="com.co.test.PasswordCallbackHandler"/>
</map>
</constructor-arg>
</bean>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
If I’m using CXF version 3.0.5 or lower this works fine. However if I use 3.0.6 or later I get “A security error was encountered when verifying the message.”. On the server I’m getting messages like “Couldn't validate the References”. This is because the server doesn’t get the same DigestValue that comes across in the ds:DigestValue element.
I think it has something to do with the way MTOM message are handled by the server side code because if I disable MTOM (on the client and server) then it works fine. I’m not sure how to get this working in later versions of CXF. Does anyone have any ideas what I’m doing wrong?
Thanks
David
Related
I am trying out a sample service application of spring data mongoDB + spring data solr where MongoDB is used to persist the data and solr for indexing and searching.
The save operation to MongoDB happens successfully in the service class. But on calling the SolrOperation save() method the service crashes with the error log as below:
SEVERE [com.sun.jersey.spi.container.ContainerResponse] (defaulttask-1)The
RuntimeException could not be mapped to a response, re-throwing the HTTP
container:org.springframework.data.solr.UncategorizedSolrException:No
association fond!; nested exception is java.lang.IllegalStateException: No
association found! at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:171)
As I analyse the log further deep it says:
Caused by: java.lang.IllegalStateException:No association found!
at org.springframework.data.mapping.PersistentProperty.getRequiredAssociation(PersistentProperty.java:166)
The line getConverter().write(bean, document) inside convertBeanToSolrInputDocument () inside SolrTemplate is throwing the error.
The DAO method
public String addToRepo(MyEntity myEntity){
mongoOperation.save(myEntity); //works fine data saved to MongoDB
solrOperation.save("collectionName",myEntity); //generates above exception
return "success";
}
I am using Spring 5 + solrj-6.1.0 + spring-data-solr-4.0.2.
The solroperation has been correctly loaded as:
ApplicationContext SOLR_CONFIG_APP_CTX = new AnnotationConfigApplicationContext(SpringSolrConfig.class);
SolrOperations solrOperation = (SolrOperations)ctx.getBean("solrTemplate");
public static final SolrOperations SOLR_OPS=
(SolrOperations)SOLR_CONFIG_APP_CTX.getBean("solrTemplate");
SpringSolrConfig.java
#Configuration
public class SpringSolrConfig extends AbstractSolrConfig {
public SolrClientFactory solrClientFactory (){
SolrClient solrClient = new HttpSolrClient.Builder(solrUrl).build();
HttpSolrClientFactory solrClientFactory = new HttpSolrClientFactory (solrClient);
return solrClientFactory;
}
}
The SpringConfig.xml file looks like this:
<mongo:mongo host="195.168.1.140" port="27017"/>
<mongo:dbfactory dbname="myDB"/>
<bean id="mongoTemplate"
class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg-name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
<repositories base-package="sample.package.repositories"/>
<bean id="myEntityRepo" class="sample.package..repositories.MyEntityRepositoryInterface"/>
<solr:repositories base-package="sample.package.repositories"/>
<solr:sorl-server id="solrServer" url="http://localhost:8983/solr"/>
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg index="0" ref="solrServer"/>
</bean>
Thanks in advance for helping me troubleshoot this!
I updated my SpringSolrConfig file as below to fix the problem. Courtesy: https://jira.spring.io/browse/DATASOLR-394
#Configuration
public class SpringSolrConfig extends AbstractSolrConfig {
String solrUrl = "http://localhost:8983/solr/"; // TODO read this ideally from spring-configuration.xml file
public SolrClientFactory solrClientFactory (){
SolrClient solrClient = new HttpSolrClient.Builder(solrUrl).build();
HttpSolrClientFactory solrClientFactory = new HttpSolrClientFactory (solrClient);
return solrClientFactory;
}
#Bean
public SolrTemplate solrTemplate () {
SolrTemplate solrTemplateObj = new SolrTemplate(solrClientFactory));
// This ensures that the default MappingSolrConverter.java is not used for converting the bean to a Solr Document before indexing
solrTemplateObj.setSolrConverter(new SolrJConverter());
return solrTemplateObj;
}
}
I am invoking a web service from the camel, and when I try to evaluate its response, I get an error. This is the camel code:
<!-- Transformatio to the ws backend -->
<process id="_transformToValidaAccesoUsuario" ref="transformToValidaAccesoUsuario"/>
<!-- Invoke the ws -->
<to id="invokeAutenticaSesion" uri="cxf:bean:autenticaSesionProxy?defaultOperationName=validarAccesoUsuario"/>
<!-- Validate the response -->
<choice id="validacionAutenticaUsuario">
<when id="validacionUsuarioOK">
<simple>${body.getResponseStatus.getDescripcionRespuesta} == 'OK'</simple>
<log id="logValidacionUsuario" message="validacionUsuario correcto"/>
</when>
<otherwise id="validacionUsuarioError">
<log id="logValidacionUsuario2" message="validacionUsuario incorrecto"/>
</otherwise>
</choice>
I have this error when I run the service:
<faultstring>Failed to invoke method: getResponseStatus on null due to: org.apache.camel.component.bean.MethodNotFoundException: Method with name: getResponseStatus not found on bean: [pe.gob.sis.esb.negocio.consultaafiliados.proxy.autenticasesion.ValidarAccesoUsuarioResponseType#f482049] of type: org.apache.cxf.message.MessageContentsList. Exchange[]</faultstring>
Edit:
The class already has the method getResponseStatus()
package pe.gob.sis.esb.negocio.consultaafiliados.proxy.autenticasesion;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ValidarAccesoUsuarioResponseType", namespace = "http://sis.gob.pe/esb/tecnico/autenticaSesion/messages/validarAccesoUsuario/v1/", propOrder = {
"responseStatus",
"login"
})
public class ValidarAccesoUsuarioResponseType {
protected ResponseStatus responseStatus;
protected Login login;
public ResponseStatus getResponseStatus() {
return responseStatus;
}
public void setResponseStatus(ResponseStatus value) {
this.responseStatus = value;
}
public Login getLogin() {
return login;
}
public void setLogin(Login value) {
this.login = value;
}
}
Ah its maybe the crappy MessageContentsList from camel-cxf / CXF. Its a design fault in camel-cxf I think. So what you can do is to convert the message body to not include that, by
<setBody><simple>${body[0]}</simple></setBody>
Which will take the first element from that MessageContentsList and store that as the message body, which will be that POJO class.
It depends a bit how you configure camel-cxf / CXF and what is stored as the message body. But the MessageContentsList is a smell.
I'm new to Camel. I'm trying to read a file from one location, making some change in the file content and sending the file to another location. I trying to get exchange related information added in the file like the following:
Exchange[ExchangePattern: InOnly, BodyType: String, Body:
Test Message from custom processor:
Text from input file.
First line in the above sample is not coming. So far I wrote the following code:
applicationContext.xml:
<bean id="customProcessor" class="com.javacodegeeks.camel.CustomProcessor"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:C:\\inputdir\\" />
<process ref="customProcessor"/>
<to uri="file:C:\\outputdir\\" />
</route>
CustomProcessor.java:
public class CustomProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String msgBody = exchange.getIn().getBody(String.class);
exchange.getIn().setBody("Test Message from custom processor: " + msgBody);
}
}
Main class:
public static final void main(String[] args) throws Exception {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
CamelContext camelContext = SpringCamelContext.springCamelContext(
appContext, false);
try {
camelContext.start();
Thread.sleep(200000);
} finally {
camelContext.stop();
}
}
You can access all the properties of Camel Exchange using Exchanges' method getProperties() i.e. exchange.getProperties() which return Map, so using this you can get the information and save it into the file using your CustomProcessor Camel processor.
For more information have a look on:
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/Exchange.html
I am trying to write a Camel test that checks to ensure a content based router is routing XML files correctly. Here are the enpoints and the route in my blueprint.xml:
<endpoint uri="activemq:queue:INPUTQUEUE" id="jms.queue.input" />
<endpoint uri="activemq:queue:QUEUE1" id="jms.queue.1" />
<endpoint uri="activemq:queue:QUEUE2" id="jms.queue.2" />
<route id="general-jms.to.specific-jms">
<from ref="jms.queue.input" />
<choice>
<when>
<xpath>//object-type = '1'</xpath>
<log message="Sending message to queue: QUEUE1" />
<to ref="jms.queue.1" />
</when>
<when>
<xpath>//object-type = '2'</xpath>
<log message="Sending message to queue: QUEUE2" />
<to ref="jms.queue.2" />
</when>
<otherwise>
<log message="No output was able to be determined based on the input." />
</otherwise>
</choice>
</route>
Right now, all I am trying to do is send in a sample source file that has an <object-type> of 1 and verify that is it routed to the correct queue (QUEUE1) and is the correct data (should just send the entire XML file to QUEUE1). Here is my test code:
public class RouteTest extends CamelBlueprintTestSupport {
#Override
protected String getBlueprintDescriptor() {
return "/OSGI-INF/blueprint/blueprint.xml";
}
#Override
public String isMockEndpointsAndSkip() {
return "activemq:queue:QUEUE1";
}
#Test
public void testQueue1Route() throws Exception {
getMockEndpoint("mock:activemq:queue:QUEUE1").expectedBodiesReceived(context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));
template.sendBody("activemq:queue:INPUTQUEUE", context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));
assertMockEndpointsSatisfied();
}
}
When I run this test, I see the log message that I put in the route definition that says it is sending it to QUEUE1, but the JUnit test fails with this error message: java.lang.AssertionError: mock://activemq:queue:QUEUE1 Received message count. Expected: <1> but was: <0>.
Can someone help me understand what I am doing wrong?
My understanding is that Camel will automatically mock the QUEUE1 endpoint since I overrode the isMockEndpointsAndSkip() and provided the QUEUE1 endpoint uri. I thought this meant I should be able to use that endpoint in the getMockEnpoint() method just by appending "mock:" to the beginning of the uri. Then I should have a mocked endpoint of which I can set expections on (i.e. that is has to have the input file).
If I am unclear on something please let me know and any help is greatly appreciated!
The solution is to use CamelTestSupport.replaceRouteFromWith.
This method is completely lacking any documentation, but it works for me when invoking it like this:
public class FooTest extends CamelTestSupport {
#Override
public void setUp() throws Exception {
replaceRouteFromWith("route-id", "direct:route-input-replaced");
super.setUp();
}
// other stuff ...
}
This will also prevent the starting of the original consumer of the from destination of the route. For example that means it isn't necessary anymore to have a activemq instance running when a route with an activemq consumer is to be tested.
After working on this for quite some time, the only solution I came up with that actaully worked for me was to use the createRouteBuilder() method in my test class to add a route to a mocked endpoint at the end of the route defined in my blueprint.xml file. Then I can check that mocked endpoint for my expectations. Below is my final code for the test class. The blueprint XML remained the same.
public class RouteTest extends CamelBlueprintTestSupport {
#Override
protected String getBlueprintDescriptor() {
return "/OSGI-INF/blueprint/blueprint.xml";
}
#Test
public void testQueue1Route() throws Exception {
getMockEndpoint("mock:QUEUE1").expectedBodiesReceived(context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));
template.sendBody("activemq:queue:INPUTQUEUE", context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue1-test.xml")));
assertMockEndpointsSatisfied();
}
#Test
public void testQueue2Route() throws Exception {
getMockEndpoint("mock:QUEUE2").expectedBodiesReceived(context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue2-test.xml")));
template.sendBody("activemq:queue:INPUTQUEUE", context.getTypeConverter().convertTo(String.class, new File("src/test/resources/queue2-test.xml")));
assertMockEndpointsSatisfied();
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
from("activemq:queue:QUEUE1").to("mock:QUEUE1");
from("activemq:queue:QUEUE2").to("mock:QUEUE2");
}
};
}
}
While this solution works, I don't fully understand why I can't just use isMockEndpointsAndSkip() instead of having to manually define a new route at the end of my existing blueprint.xml route. It is my understanding that defining isMockEndpointsAndSkip() with return "*"; will inject mocked endpoints for all of your endpoints defined in your blueprint.xml file. Then you can check for your expections on those mocked endpoints. But for some reason, this does not work for me.
I am having trouble getting my Camel route to successfully POST a message to an existing RESTful web service. I have tried all the examples in the camel cxf package but none of them produce a web service call (they are consumers). I would love to find a working example for this so I can step through the CxfRsProducer execution to hopefully discover why my route is not posting correctly to the web service.
Here is my RouteBuilder's configuration:
public void configure()
{
//errorHandler(deadLetterChannel(String.format("file:%s/../errors", sourceFolder)).useOriginalMessage().retriesExhaustedLogLevel(LoggingLevel.DEBUG));
errorHandler(loggingErrorHandler());
/*
* JMS to WS route for some of the events broadcast to the jms topic
*/
Endpoint eventTopic = getContext().getEndpoint(String.format("activemq:topic:%s?clientId=%s&durableSubscriptionName=%s", eventTopicName, durableClientId, durableSubscriptionName));
from(eventTopic) // listening on the jms topic
.process(eventProcessor) // translate event into a Notifications object (JAX-RS annotated class)
.choice() // gracefully end the route if there is no translator for the event type
.when(header("hasTranslator").isEqualTo(false)).stop() // no translator stops the route
.otherwise() // send the notification to the web service
.to("cxfrs:bean:rsClient");
}
Here is the rsClientBean:
<cxf:rsClient id="rsClient"
address="http://localhost/ws"
serviceClass="com.foo.notifications.NotificationsResource"
loggingFeatureEnabled="true" />
I'm pretty new to REST and I don't really understand what the serviceClass does for the rsClient because it looks to me like the definition of the exposed web service on the server.
The NotificationsResource class:
#Path("/notifications/")
public class NotificationManagerResource
{
// NOTE: The instance member variables will not be available to the
// Camel Exchange. They must be used as method parameters for them to
// be made available
#Context
private UriInfo uriInfo;
public NotificationManagerResource()
{
}
#POST
public Response postNotification(Notifications notifications)
{
return null;
}
}
The processor creates a Notifications object to put in the exechange message body:
private class EventProcessor implements Processor
{
#Override
public void process(Exchange exchange) throws Exception
{
Message in = exchange.getIn();
IEvent event = (IEvent) in.getBody();
Notifications notifications = null;
in.setHeader("hasTranslator", false);
in.setHeader("Content-Type", "application/xml");
in.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, false);
// I've tried using the HTTP API as 'true', and that results in a 405 error instead of the null ptr.
INotificationTranslator translator = findTranslator(event);
if (translator != null)
{
notifications = translator.build(event);
in.setHeader("hasTranslator", true);
}
// replace the IEvent in the body with the translation
in.setBody(notifications);
exchange.setOut(in);
}
}
The Notifications class is annotated with JAXB for serialization
#XmlRootElement(name = "ArrayOfnotification")
#XmlType
public class Notifications
{
private List<Notification> notifications = new ArrayList<>();
#XmlElement(name="notification")
public List<Notification> getNotifications()
{
return notifications;
}
public void setNotifications(List<Notification> notifications)
{
this.notifications = notifications;
}
public void addNotification(Notification notification)
{
this.notifications.add(notification);
}
}
The error that is returned from the web service:
Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
Id ID-PWY-EHANSEN-01-62376-1407805689371-0-50
ExchangePattern InOnly
Headers {breadcrumbId=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47, CamelCxfRsUsingHttpAPI=false, CamelRedelivered=false, CamelRedeliveryCounter=0, Content-Type=application/xml, hasTranslator=true, JMSCorrelationID=null, JMSDeliveryMode=2, JMSDestination=topic://SysManEvents, JMSExpiration=1407805812574, JMSMessageID=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=null, JMSTimestamp=1407805782574, JMSType=null, JMSXGroupID=null, JMSXUserID=null}
BodyType com.ehansen.notification.types.v2.Notifications
Body <?xml version="1.0" encoding="UTF-8"?><ArrayOfnotification xmlns="http://schemas.datacontract.org/2004/07/ehansen.Notifications.Dto"> <notification> <causeType>EVENT_NAME</causeType> <causeValue>DeviceEvent</causeValue> <details> <notificationDetail> <name>BUSY</name> <value>false</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>DESCRIPTION</name> <value>Software Computer UPS Unit</value> <unit>name</unit> </notificationDetail> <notificationDetail> <name>DEVICE_NUMBER</name> <value>1</value> <unit>number</unit> </notificationDetail> <notificationDetail> <name>DEVICE_SUB_TYPE</name> <value>1</value> <unit>type</unit> </notificationDetail> <notificationDetail> <name>DEVICE_TYPE</name> <value>UPS</value> <unit>type</unit> </notificationDetail> <notificationDetail> <name>FAULTED</name> <value>false</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>RESPONDING</name> <value>true</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>STORAGE_UNIT_NUMBER</name> <value>1</value> <unit>number</unit> </notificationDetail> </details> <sourceType>DEVICE_ID</sourceType> <sourceValue>1:UPS:1</sourceValue> <time>2014-08-11T18:09:42.571-07:00</time> </notification></ArrayOfnotification>
]
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
java.lang.NullPointerException
at java.lang.Class.searchMethods(Class.java:2670)
at java.lang.Class.getMethod0(Class.java:2694)
at java.lang.Class.getMethod(Class.java:1622)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.findRightMethod(CxfRsProducer.java:266)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.invokeProxyClient(CxfRsProducer.java:222)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.process(CxfRsProducer.java:90)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:143)
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:307)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:138)
It is the methodName parameter in the following method from CxfRsProducer class that is null... so I assume there is something about my rsClient that is not configured correctly.
private Method findRightMethod(List<Class<?>> resourceClasses, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
Method answer = null;
for (Class<?> clazz : resourceClasses) {
try {
answer = clazz.getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
// keep looking
} catch (SecurityException ex) {
// keep looking
}
if (answer != null) {
return answer;
}
}
throw new NoSuchMethodException("Cannot find method with name: " + methodName + " having parameters: " + arrayToString(parameterTypes));
}
Thanks for any help anyone can provide!
The serviceClass is a JAX-RS annotated Java class that defines the operations of a REST web service.
When configuring a CXF REST client, you must specify and address and a serviceClass. By inspecting the annotations found on the serviceClass, the CXF client proxy knows which REST operations are supposed to be available on the REST service published on the specified address.
So in your case, you need to add in.setHeader.setHeader(CxfConstants.OPERATION_NAME, "postNotification"); to the EventProcessor to tell camel which method of the service class you want to call.
Alright then. Here is the camel configuration xml file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
>
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="helloBean" class="com.examples.camel.cxf.rest.resource.HelloWorldResource" />
<cxf:rsServer id="helloServer" address="/helloapp" loggingFeatureEnabled="true">
<cxf:serviceBeans>
<ref bean="helloBean" />
</cxf:serviceBeans>
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
<camelContext id="context" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs:bean:helloServer />
<log message="Processing CXF route....http method ${header.CamelHttpMethod}" />
<log message="Processing CXF route....path is ${header.CamelHttpPath}" />
<log message="Processing CXF route....body is ${body}" />
<choice>
<when>
<simple>${header.operationName} == 'sayHello'</simple>
<to uri="direct:invokeSayHello" />
</when>
<when>
<simple>${header.operationName} == 'greet'</simple>
<to uri="direct:invokeGreet" />
</when>
</choice>
</route>
<route id="invokeSayHello">
<from uri="direct:invokeSayHello" />
<bean ref="helloBean" method="sayHello" />
</route>
<route id="invokeGreet">
<from uri="direct:invokeGreet" />
<bean ref="helloBean" method="greet" />
</route>
</camelContext>
</beans>
The actual resource implementation class looks like below.
package com.examples.camel.cxf.rest.resource;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
public class HelloWorldResource implements HelloWorldIntf
{
public Response greet() {
return Response.status(Status.OK).
entity("Hi There!!").
build();
}
public Response sayHello(String input) {
Hello hello = new Hello();
hello.setHello("Hello");
hello.setName("Default User");
if(input != null)
hello.setName(input);
return Response.
status(Status.OK).
entity(hello).
build();
}
}
class Hello {
private String hello;
private String name;
public String getHello() { return hello; }
public void setHello(String hello) { this.hello = hello; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
You don't need , and cxf:rsServer> to be provided.
The tag alone will suffice to handle a web service request and invoke a route.
In case you have both and the then invoking the former will not help you in executing a route. For a route to get invoked, the request must reach to the address published by .
Hope this helps.