While trying to use the Apache camel aggregation strategy, I am running into an issue as described below:
My application : Exposed a simple soap service that takes in the names of the departments in an organisation (finance, sales...). Inside my camel route, I route the request accordingly to the department specific routes. In these routes, I query a table, and get the employees for that department.
As a response for the soap service, I want to aggregate all the employees together and send.
Below is my camel Route:
<camelContext id="camel"
xmlns="http://camel.apache.org/schema/spring">
<camel:dataFormats>
<camel:jaxb contextPath="org.example.departments" id="jaxb"/>
</camel:dataFormats>
<route id="simple-route">
<!-- <camel:to id="unmarshallDeps" uri="bean:departmentProcessor"></camel:to> -->
<from id="_from1" uri="cxf:bean:departmentsEndpoint?dataFormat=PAYLOAD&loggingFeatureEnabled=true"/>
<camel:unmarshal id="_unmarshal1" ref="jaxb"/>
<camel:setHeader headerName="departments" id="_setHeader1">
<camel:method method="getDepartmentRoute" ref="depRouter"/>
</camel:setHeader>
<camel:recipientList id="_recipientList1">
<camel:header>departments</camel:header>
</camel:recipientList>
<camel:log id="_log1" message="Body in original cxf after aggregation ******** ${body} and exchange id is ${exchangeId}"/>
</route>
<camel:route id="_route1">
<camel:from id="_from2" uri="direct:finance"/>
<camel:to id="_to1" uri="mySqlComponent:select id,Location,Head,email,create_date from finance"/>
<camel:to id="_to2" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route2">
<camel:from id="_from3" uri="direct:sales"/>
<camel:to id="_to3" uri="mySqlComponent:select id,Location,Head,email,create_date from sales"/>
<camel:to id="_to4" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route3">
<camel:from id="_from4" uri="direct:hr"/>
<camel:to id="_to5" uri="mySqlComponent:select id,Location,Head,email,create_date from hr"/>
<camel:to id="_to6" pattern="InOut" uri="seda:departmentAggregator"/>
</camel:route>
<camel:route id="_route4">
<camel:from id="_from5" uri="seda:departmentAggregator"/>
<camel:aggregate completionSize="2" id="_aggregate1" strategyRef="myAggregator">
<camel:correlationExpression>
<camel:constant>Constant</camel:constant>
</camel:correlationExpression>
<camel:log message="Aggregated Body : ${body} and exchange id is ${exchangeId}"></camel:log>
<!-- <camel:marshal id="_marshal1" ref="jaxb"/> -->
<!-- <camel:setBody id="_setBody1">
<camel:simple>${body}</camel:simple>
</camel:setBody> -->
</camel:aggregate>
<camel:log id="_log4" message="Body outside aggregate : ${body} and exchange id is ${exchangeId}"/>
</camel:route>
</camelContext>
Now, what I notice is that the body when printed inside the aggregate is indeed an aggregated body, containing all the employees, but when I print the body outside the aggregate, it prints the latest exchange and not the aggregated exchange. Below is my aggregation strategy:
public Exchange aggregate(Exchange oldExchange, Exchange newExchange)
{
ArrayList<Map<String, Object>> depList = newExchange.getIn().getBody(ArrayList.class);
int depCount = depList.size();
System.out.println("Department Count is : " + depCount);
if (oldExchange == null) {
for (int i = 0; i < depCount; i++) {
Map<String, Object> row = (Map) depList.get(i);
Department newDepartment = new Department();
newDepartment.setLocation((String) row.get("Location"));
newDepartment.setHead((String) row.get("Head"));
newDepartment.setEmail((String) row.get("email"));
departments.getDepartment().add(newDepartment);
}
newExchange.getIn().setBody(departments);
return newExchange;
} else {
System.out.println("New Exchange: Department Count is : " + depCount);
departments = oldExchange.getIn().getBody(Departments.class);
System.out.println("Aggregate Department count : " + departments.getDepartment().size());
for (int j = 0; j < depCount; j++) {
Map<String, Object> row = (Map) newExchange.getIn().getBody(ArrayList.class).get(j);
Department newDepartment = new Department();
newDepartment.setLocation((String) row.get("Location"));
newDepartment.setHead((String) row.get("Head"));
newDepartment.setEmail((String) row.get("email"));
departments.getDepartment().add(newDepartment);
}
newExchange.getIn().setBody(departments);
oldExchange.getIn().setBody(departments);
}
// System.out.println("exchange is out capable ? : " +
// newExchange.getPattern().isOutCapable());
return oldExchange;
}
Aggregation Strategy is usually something that gets seamlessly embedded into EIPs; you don't have to call it manually, Camel does it for you.
recipientList is precisely one of those EIPs that accepts an aggregation strategy as a parameter.
See example in Camel doc.
Thus your "seda:departmentAggregator" route is in fact not needed (along with all the calls towards it in your "direct:[department]" routes). Instead, its content should be +/- included into the recipientList definition.
Related
I am a starter for camel. I have a question. I have one route.
<route>
<from uri="file:/test/inBox"/>
<bean method="processingAuditInsert(*, 'RD', 'AA')" ref="fileAuditHandler"/>
<bean method="processingAuditUpdate(*, 'IU')" ref="fileAuditHandler"/>
<toD uri="file:/test/outBox"/>
<bean method="processingAuditUpdate(*, 'CO')" ref="fileAuditHandler"/>
</route>
I applied each parameter for processingAuditUpdate method.
'IU' parameter is correct set to processingAuditUpdate method.
And during second calling method 'processingAuditUpdate', I want to set 'CO' value.
But after processing, this value is the body value of exchange.
I don't understand this situation.
Please help about this situation.
Thank you.
fileAuditHandler.java
#Handler
public void processingAuditUpdate(Exchange ex, String status) {
if (status.equals("IU")) {
// Update Status 'IU'
} else (status.equals("CO")) {
// Update Status 'CO'
} else {
log.error("Update Status value is invalid!!!! ::::: {}", status);
}
}
I have a timer route that is initially not started. I would like to activate it from another route. I am attempting to use the camel's controlbus EIP pattern.
// From my other route
.to("controlbus:route?routeId=fileConsumerRoute&action=start&async=true")
from("timer://camel-fileConsumerRoute?fixedRate=true&period=5s")
.routeId("fileConsumerRoute").noAutoStartup()
.log("Route is running");
I see in the logs aft the controlbus line is run that the route is being resumed
Context action: [resume]
but the timer still does not fire. I dont see the log line "Route is running"
How do I activate the timer endpoint with the controlbus?
Is there another EIP pattern or diffrent way to achieve activating the timer endpoint?
I realize I'm late to the party, but, you could use controlbus or something like this start stop routes. if there is some predicate some other boolean test.
example:
we test if some condition exists every period and perform operation on result of condition...
<!-- Token Database -->
<route autoStartup="true" id="core.predix.tkndependencyCheckerRoute">
<from id="_from2" uri="timer://tkndbAvailable?fixedRate=true&period=30000"/>
<process id="_process2" ref="tkndbAvailableProcessor"/>
</route>
public class TknDbAvailableProcessor implements Processor {
private static final Logger LOG = LoggerFactory.getLogger(TknDbAvailableProcessor.class);
private TKNDataService tknDataService = null;
#Override
public void process(Exchange exchange) throws Exception {
ServiceStatus status = exchange.getContext().getRouteStatus("core.fleet.EnrichmentRoute");
if (null == tknDataService) {
if (status.isStarted()) {
exchange.getContext().stopRoute("core.fleet.EnrichmentRoute");
}
} else {
if (tknDataService.isTKNDataServiceAvailable()) {
if (status.isStopped()) {
exchange.getContext().startRoute("core.fleet.EnrichmentRoute");
}
} else {
if (status.isStarted()) {
exchange.getContext().stopRoute("core.fleet.EnrichmentRoute");
}
}
}
}
public void setDataService(TKNDataService dataService) {
this.tknDataService = dataService;
}
}
If needing a master singleton route if needing redundancy - on diff nodes use a JGroups Cluster with ControlBus
<bean class="org.apache.camel.component.jgroups.JGroupsFilters"
factory-method="dropNonCoordinatorViews"
id="dropNonCoordinatorViews" scope="prototype"/>
<bean class="org.apache.camel.component.jgroups.JGroupsExpressions"
factory-method="delayIfContextNotStarted"
id="delayIfContextNotStarted" scope="prototype">
<argument value="5000"/>
</bean>
<route autoStartup="true" id="FleetMainClusterControlRoute">
<from id="_from2" uri="jgroups:mainCluster?enableViewMessages=true&channelProperties=etc/jgroups.xml"/>
<filter id="filterNonCoordinatorViews">
<method ref="dropNonCoordinatorViews"/>
<threads id="threads1" threadName="ControlThreads">
<delay id="_delay1">
<ref>delayIfContextNotStarted</ref>
<log id="logCR" loggingLevel="INFO" message="Starting Main Cluster consumer!!!!!!!!!!!!!!!!!!!!!"/>
<to id="_toCR" uri="controlbus:route?routeId=core.predix.tkndependencyCheckerRoute&action=start&async=true"/>
</delay>
</threads>
</filter>
</route>
I have implemented following route with Apache camel XML mode.
<restConfiguration component="servlet" bindingMode="json" contextPath="/abc-esb/rest" port="8181">
<dataFormatProperty key="prettyPrint" value="true" />
<dataFormatProperty key="json.in.disableFeatures" value="FAIL_ON_EMPTY_BEANS,FAIL_ON_UNKNOWN_PROPERTIES" />
</restConfiguration>
<rest path="/service-http" consumes="application/json" produces="application/json">
<put type="com.abc.abcd.esb.models.UserServiceMapping" uri="/create">
<route>
<setHeader headerName="Authorization">
<simple>Basic YWRtaW46YWRtaW4=</simple>
</setHeader>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<setBody>
<simple>
{"SystemUserDetails":{"userName":"${body.objectDetails.userName}",
"password": "${body.objectDetails.password}"}}
</simple>
</setBody>
<to uri="http://192.168.1.20:8081/abcd/services/UserServiceRest/V1.0/users/create?bridgeEndpoint=true" />
</route>
</put>
</rest>
Functionality happens as expected. But camel returns HTTP 500 mentioning following error.
com.fasterxml.jackson.databind.JsonMappingException: No serializer
found for class
org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream
and no properties discovered to create BeanSerializer (to avoid
exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) at
com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
at
com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
at
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
When I analyze a tcp dump related to this scenario, I found this HTTP 500 occurred when trying to mapping the {"status" : "Success"} response from the external webservice.
Content of the UserServiceMapping class
private String serviceName;
private String serviceMethod;
private String mappedServiceObject;
private SystemUserDetails objectDetails;
// private StatusDetails statusDetails;
public String getMappedServiceObject() {
return mappedServiceObject;
}
public void setMappedServiceObject(String mappedServiceObject) {
this.mappedServiceObject = mappedServiceObject;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getServiceMethod() {
return serviceMethod;
}
public void setServiceMethod(String serviceMethod) {
this.serviceMethod = serviceMethod;
}
public SystemUserDetails getObjectDetails() {
return objectDetails;
}
public void setObjectDetails(SystemUserDetails objectDetails) {
this.objectDetails = objectDetails;
}
/*
* public StatusDetails getStatusDetails() { return statusDetails; }
*
* public void setStatusDetails(StatusDetails statusDetails) {
* this.statusDetails = statusDetails; }
*/
Request response flow of the scenario
How ever up to now I couldn't find an exact reason for this issue but I could by-pass the problem by setting Accept: application/xml other than Accept: application/json in my external REST client which makes the initial REST request. (REST service endpoint in other end configured to produce both json and xml)
I'm trying to create a response to a REST web service call in a CXFRS Camel route, but no matter what I do the response to the client is always the same 200, not 201. Here's my route:
<route id="front-end">
<from uri="cxfrs:bean:myService" />
<setBody>
<constant>Will do...</constant>
</setBody>
<setHeader headerName="CamelHttpResponseCode">
<constant>201</constant>
</setHeader>
<setHeader headerName="Content-Type">
<constant>more/blah</constant>
</setHeader>
</route>
The body is returned but the response code and content type are ignored. What am I doing wrong?
Thanks,
Matt
Basically camel-cxfrs overwrites any headers set in exchange when it converts the exchange to actual HTTP response
See here:
exchange.getOut().setHeaders(binding.bindResponseHeadersToCamelHeaders(response, exchange));
And this happens because DefaultCxfRsBinding expects a jaxrs Response as a parameter.
So to fix the issue you either override DefaultCxfRsBinding with custom one in order to copy headers from exchange.getIn().
<cxf:rsServer id="MyService" address="/myAddress">
<cxf:binding><bean class="MyCustomCxfRsBinding" /></cxf:binding>
<cxf:serviceBeans>
<ref bean="myResourceWithJSR311Annotations" />
</cxf:serviceBeans>
</cxf:rsServer>
Or make your camel route to return a jaxrs Response with headers instead of setting headers in the rout or in camel processors. Something
class HttpHeaderProcessor implements Processor
{
#Override
public void process(Exchange exchange) throws Exception
{
Message message = exchange.getIn();
Response response = convertToJaxRs(message);
exchange.getIn().setBody(response);
exchange.getIn().setHeader("Test", "Won't work unless DefaultCxfRsBinding is not replaced with a custom one");
}
private Response convertToJaxRs(Message message)
{
ResponseBuilder jaxrsResponseBuilder = Response.ok(message.getBody(), MediaType.APPLICATION_XML);
jaxrsResponseBuilder.header("header1", "you'll see this");
Response response = jaxrsResponseBuilder.build();
return response;
}
}
For your sample:
<route id="front-end">
<from uri="cxfrs:bean:myService" />
<setBody>
set it to Response.ok(your message).header(x, y).build()
</setBody>
You can also use a Service bean returning a jaxrs.Response with headders
<route id="front-end">
<from uri="cxfrs:bean:myService" />
<bean ref="myServiceImpl">
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.