I'm trying to create en REST endpoint with Apache Camel. I already have a REST service that return me JSON content and I want this endpoint to get it. My problem is that I don't know what's happening when my Camel route is built.. For the moment, it doesn't do anything. Here is my code :
restConfiguration().component("servlet")
.bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true").host("localhost")
.port(9080);
rest("/ContextServices/rest/contextServices/document")
.consumes("application/json").produces("application/json")
.get("/testContext/557064c8f7f71f29cea0e657").outTypeList(String.class)
.to("bean:processor?method=affiche")
.to(dest.getRouteTo());
I'm running my REST service on a local Tomcat on port 9080, my full URL is
/ContextServices/rest/contextServices/document/{collection}/{id}.
I've tried to read the documentation but there is two syntax and both don't work:
from("rest:get:hello:/french/{me}").transform().simple("Bonjour ${header.me}");
or
rest("/say")
.get("/hello").to("direct:hello")
.get("/bye").consumes("application/json").to("direct:bye")
.post("/bye").to("mock:update");
The first is Java DSL, the second is REST DSL, what's the difference ?
Thanks a lot !
First of all, REST component itself is not a REST implementation.
It just declares language to describe REST endpoints.
You should use actual implementation of REST, something like Restlet (see the full list here)
I can be wrong, but AFAIR, REST endpoint is only for the case when you want to listen for REST requests from another application.
What you need is to make request to REST endpoint and process it.
The question is: when do you want to trigger request?
Is it some event, or may be you want to check external REST service periodically?
For the latter case I use the following pattern:
<route>
<from uri="timer:polling-rest?period=60000"/>
<setHeader headerName="CamelHttpMethod">
<constant>GET</constant>
</setHeader>
<recipientList>
<simple>http://${properties:service.url}/api/outbound-messages/all</simple>
</recipientList>
<unmarshal ref="message-format"/>
<!-- do something with the message, transform it, log,
send to another services, etc -->
<setHeader headerName="CamelHttpMethod">
<constant>DELETE</constant>
</setHeader>
<recipientList>
<simple>http://${properties:service.url}/api/outbound-messages/by-id/${header.id}</simple>
</recipientList>
</route>
Sorry for the example with http component instead of REST.
I simply copy-pasted it from my working project, which uses pure http.
I suppose, rewriting this via something like Restlet or CXF component.
Related
I am building a rest route on camel based on rest DSL. For example, based on the configuration, the rest route uses a direct component.
Rest Route
rest("resturi")
.post()
.to(direct:inbox);
resturi is dynamic
from(direct:inbox)
.process(camelprocessor)
.to(queue);
Is there any way we can remove the direct component and combine into one route.
I appreciate any advice regarding the above.
You can do that by adding .route()
.post().route().process(camelprocessor).to(queue);
But think from the feature reusable perspective, direct component will be the best choice.
https://access.redhat.com/documentation/en-us/red_hat_jboss_fuse/6.2/html/apache_camel_development_guide/restservices-restdsl
XML dsl example
<get uri="/some">
<route>
<setBody>
<constant>HW!</constant>
</setBody>
</route>
</get>
You can call your processor in this route.
SOAP WS with trivial characteristics:
- WSDL address:
http://<ip>:<port>/service/name?wsdl
- target method name:
getData(...)
Part of Spring-integration config ('spring-context.xml') for calling WS:
...
<int:chain input-channel="data" output-channel="stdout">
<!-- transform message to request -->
<int:transformer
ref="soapRequestTransformer"
method="createReq">
</int:transformer>
<!-- define the WS method to be called (getData) -->
<int:header-enricher>
<int:header
name="SoapAction"
value="http://<ip>:<port>/service/name/getData"/>
</int:header-enricher>
<!-- call WS -->
<int-ws:outbound-gateway uri="http://<ip>:<port>/service/name"/>
</int:chain>
...
After transformer (successful) i have request object:
request.getHeaders(): {sequenceNumber=1, correlationId=2bfb560c-
96ba-9c35-96dc-ba16104604b9, id=32f43a24-dee2-461c-a9b9-92c8ee37aaec,
sequenceSize=12, timestamp=1532509142590}
request.getPayload(): org.types.GetDataRequest#77409e4b
How to properly setup the spring-integration to correctly call the WS?
Problem is that WS is not called.
How does this problem look? We can't say anything without at least some stack trace.
Is the name of the WS method used correctly?
The SoapAction value is vendor-specific. You have to consult the WS provided to determine what and how should be presented in that header.
How are the parameters passed?
Not sure about nay parameter. Yes, you can send some query params as well, but doesn't look like that is your questions. Please, be more specific.
By the way, if you send some POJO (e.g. your org.types.GetDataRequest), you need to use a marshaling gateway instead of simple one:
<int-ws:outbound-gateway marshaller="someMarshaller" uri="http://<ip>:<port>/service/name"/>
Not sure, of course, if you have a good XSD-genarated model, based on the provided info in that WSDL...
I need to control my routes and I am using spring DSL for Camel.
I need to exposed a service which will perform thoses actions to the routeId given in paramaters.
The following code does not work (the body contain the routeId)
<route id="stopRoute">
<from uri="direct:stopRoute"/>
<log message="about to stop a route"/>
<to uri="controlbus:route?routeId=${body}&action=stop"/>
<to uri="controlbus:route?routeId=${body}&action=status"/>
</route>
I also tried with simple language but I can't figure out the correct syntax
See this FAQ
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
Use <toD> to make the to dynamic.
I have a simple route defined in a routeContext in Camel (this route will be used in multiple routes).
<route id="sendToRabbitQueue">
<from uri="direct:sendToQueue" />
<convertBodyTo type="java.lang.String"/>
<setHeader headerName="rabbitmq.ROUTING_KEY">
<constant>my.routing.key</constant>
</setHeader>
<to uri="ref:genericRabbitEndpoint"/>
</route>
And I have an endpoint (defined in an endpoints file)
<endpoint id="genericRabbitEndpoint" uri="rabbitmq://${rabbitmq.host}:${rabbitmq.port}/${rabbitmq.exchange.name}">
<camel:property key="autoDelete" value="false" />
<camel:property key="connectionFactory" value="#rabbitConnectionFactory" />
</endpoint>
Yes - I have seen the http://camel.apache.org/rabbitmq.html page - that's where I got the idea to set the header on the exchange. However no message is being published on the queue. I'm clearly overlooking something and any help would be appreciated.
So this seems like a bit of a gotcha and the answer relates to part of the route I didn't include in the question because I didn't think it was relevant.
The route starts at a RabbitMQ endpoint (not included above). As a result the exchange has some RabbitMQ headers set when it arrives:
rabbitmq.ROUTING_KEY
rabbitmq.EXCHANGE_NAME
rabbitmq.DELIVERY_TAG
These headers are used across the life of the route and appear to override the values when I try to publish at a different RabbitMQ endpoint. The way I've fixed is by introducing a bean which strips the headers out. Not ideal behaviour in my opinion...
public void stripRabbitHeaders(#Headers Map headers)
{
headers.remove("rabbitmq.ROUTING_KEY");
headers.remove("rabbitmq.DELIVERY_TAG");
headers.remove("rabbitmq.EXCHANGE_NAME");
}
I want to send a generic message from from java, that is then routed by camel. So far the messages always went to an activemq topic (Example 1) but in future I want to be able to change the route (i.e. sending the message to a rest webservice instead) without modifing the source code (via spring xml configuration). So I expect to do ~something like~ Example 2. How would I do this?
Example 1: (how it's done so far)
#EndpointInject(uri="activemq:topic:IMPORTANTEVENTS")
ProducerTemplate producer;
producer.sendBody("Hello world!");
Example 2: (how it is supposed to look like - more or less)
#EndpointINject(uri="myevents")
... (as above)
XML config:
<route id="SysoutRoute">
<from uri="myevents"/>
<to uri="activemq:topic:IMPORTANTEVENTSS"/>
</route>
You can use property placeholders: http://camel.apache.org/using-propertyplaceholder.html - then the java source code do not need to be changed, but the uri is defined in a .properties file which you can then easily change
Ok got it working. It es actually quite easy by using direct: component(http://camel.apache.org/direct.html)
#EndpointInject(uri="direct:outMessage")
ProducerTemplate producer;
Now I can send messages:
producer.sendBody("Hello world!");
And route them via Spring xml config e.g. like this:
<route id="outMessage">
<from uri="direct:outMessage"/>
<to uri="stream:out"/>
<to uri="activemq:topic:IMPORTANTEVENTS"/>
<to uri="restlet:http://localhost:8888/status/?restletMethod=post"/>
</route>