I currently have a polling html consumer that polls a http endpoint every 5 seconds. This works fine.
I need to now support a http endpoint that has SSE as the transport mode. The server will push every 3 seconds or so and I was hoping that camel could somehow handle this. In this case I am the consumer and I have the Server end point I wish to consumer from.
Any thoughts how I could do this?
thanks
You could certainly do this in Camel/Servlet as SSE is an HTTP protocol with a specific content-type, so you'd need something like this in your route.
<setHeader headerName="Content-Type">
<simple>text/event-stream</simple>
</setHeader>
You'd have to be careful about scale though as I imagine you'd get a new thread for each connection.
Related
I currently have a camel route that exposes a cxf endpoint. When a messages comes through the endpoint I would first enrich that message with some information from another webservice and then do more processing afterwards. However, I want make the first half of this route synchronous so I can send back a response to whomever called my exposed cxf endpoint.
The route looks something like this:
from(cxf:CxfEndpoint)
.process(someProcessing)
.to(cxf:ExternalCxfEndpoint)
.to(activemq:queue:somequeue)
//return a response back to caller here
from(activemq:queue:somequeue)
... //additional processing here
...
The reason for this is because when a message comes via my exposed cxf endpoint I don't know if it's a valid message. I need to first validate it with the message enrichment. Once the message is enriched, I want let whomever sent the message know that their message is accepted but don't want them to wait for the message to make it through the whole route as that could take hours.
Does anyone know how this would work?
Thanks in advance!
I believe all you need to do is set exchangePattern to InOnly a.k.a. make it an Event Message. This should have your route not wait for a reply from ActiveMQ. Camel exchange will default to InOut when it's originating from a web service, as in your case.
A related question with an answer from a Camel dev here.
Also see this one for some details on the behavior when your broker is down.
Yes definitely , 100% possible. A simple example would be this :
From cxf endpoint
Store your request in a camel property or header
To xslt - generate xslt for cxf endpoint - Synchronous flow
Reset your original payload using set body.
Wiretap Endpoint - to any endpoint downstream or even a route , this becomes asynchronous . This won't take part in the above sync response .
Note- step 2 & 4 may not be required, it depends on your use case .
There are whole lots of things you can do, I just gave a very simple example . It doesn't need to be wiretap as well, but wiretap helps us not to write any additional custom exceptional handling.
We need our Camel app to raise an exception and reject incoming request if the msg count exceeds specified threshold (i.e., allow 4 requests in 10 sec time span).
Below is the configuration we have in our camel context file right after jetty front side http listener.
<throttle timePeriodMillis="10000" rejectExecution="true">
<constant>4</constant>
<to uri="bean:someEndPoint"/>
</throttle>
When we invoke Camel app via jmeter, throttle happens for 5th request and subsequent requests too... however, throttle keeps happening forever even after the expiry of 10 sec time span. While, some other times throttle doesn't happen at all during the newer 10 sec time span windows.
Please help here.
Thx
Ramesh
I'm looking for a best practise how to monitor the functionality of camel routes.
I know there are monitoring tools like hawtio and camelwatch, but that's not exactly what I'm looking for.
I want to know if a route is "working" as aspected, for example you have a route which listens on a queue(from("jms...")). Maybe there are messages in the queue, but the listener is not able to dequeue them because of some db issues or something else(depends on the jms provider). With the monitoring tools mentioned above you just see inflight/failed/completed messages but you don't see if the listener is able to get the messages -> so the route is not "working".
I know there is also apache BAM, maybe I have to do some more research, but somehow it looks like BAM creates new routes and you can't monitor existing routes. I also don't want to implement/define such business cases for each route, I look for a more generic way. It's also mentioned on the camel 3.0 idea board that BAM wasn't touched for 5 years, so I think people don't use it that often(which means for me it doesn't fit their needs exactly).
I had similar requirement some time ago and at the end I developed a small Camel application for monitoring.
It run on timer, query different Camel applications installed in remote servers through JMX/Jolokia and if LastExchangeCompletedTimestamp of the route I am interested in is older than some time interval, send a mail to administrators.
Maybe this approach is too simple for your scenario, but could be an option.
(Edit: more details added)
Principal points:
Main routes queries DB for entities to control and spawns controlling routes
Controlling routes fires on quartz and http post the following url
.to("http://server:port/app/jolokia/?"+
"maxDepth=7&maxCollectionSize=500&ignoreErrors=true&canonicalNaming=false")
sending the following jsonRequest body
LinkedHashMap<String,Object> request=new LinkedHashMap<String,Object>();
request.put("type","read");
request.put("mbean","org.apache.camel:"+entity.getRouteId());
jsonRequest=mapper.writeValueAsString(request);
As response you get another JSON, parse it and get LastExchangeCompletedTimestamp value
The need is to have a Camel (Mina/Netty) based TCP server running on a specific port, which allows multiple TCP clients to connect to it. The content to be streamed is available in files and the TCP server has to send each line in the text files to one of the connected clients (round robin).
Can someone help me with the outline of a camel route to achieve this?
Also it is possible to throttle the streaming speed for example 100 msg/sec per connected client?
Thanks in advance.
MK
I have done something like this. Well not quite exactly to what you want but I can make some suggestions on how to get started.
Lets use the MINA component for this route as I had some issues with the Netty component see this link Exception thrown from Apache Camel Netty Consumer When more than one client sends data. Apparently this has been fixed but as my project got cancelled I never tested it again.
So from your description this will be a text line based protocol a simple route for this would look like this in the DSL
<route>
<from uri="mina2:tcp://localhost:5555?textline=true"/>
<to uri="bean:fileProcessing"/>
</route>
This route will open a listening socket on the localhost on port 5555. The route is also setup to use a textline codec. A textline codec is essentially a line of text terminated end of line character i.e. \n. If you are going to be using some other protocol you will need to look into the following items:
ProtocolEncoder—The ProtocolEncoder handles the task of taking an input
payload and putting bytes onto the TCP channel.
ProtocolDecoder—The ProtocolDecoder interprets the custom
binary protocol message to something your application can understand.
ProtocolCodecFactory— This creates the encoder and decoder.
You could implement some logic in the fileProcessing bean to send the replies back. There is a catch however the clients will have to request when they are ready to get a new line. From my understanding this follows a request reply scenario. However from what I have seen the route is only active when there is a message coming in from the client to the server.
There might be a way to initiate the sending from the server but you will need to experiment with that by yourself on getting it done I have not done anything like that myself.
Critical reading would be the following.
Mina Documentation
Blog Entry On Using MINA
My suggestion is to start with a basic route like this and then expand your logic and then come back with problems you might encounter.
UPDATE:
So I did a little research on this and it does not appear possible to send events from the server to the client without following one of the following patterns InOnly and InOut.
Try just using MINA or Netty then.
What's the best strategy to send SMS via SMPP with Camel ? Should I use the ProducerTemplate ?
I'm new to camel so I'm not confident if my strategy is the best.
In my application upon reception of an SMS, I have to send back an other SMS with some computed content.
I created a
route smsIn that looks like this
from "uri=smpp ..."
unmarshal ref="bindyDataFormat"
to "uri=bean:myBean
and a route smsOut with
from "uri=direct:smsOut"
to "uri=smpp ..."
The smsIn route, receives the sms, transforms its conent (csv data) in a pojo and send that pojo to myBean.
In myBean I do some processing and then call a ProducerTemplate which send my computed message to the endpoint "direct:smsOut".
The reason I use the producerTemplate is that I have to set some info from my pojo in the header (CamelSmppDestAddr) and the body of the Exchange.
I have tested with the logica SMSC simulator, this seems to work fine, but would like to have your opinion about this solution ?
What about reliability , transaction ?
Should I store my message before trying to send it to the SMSC ?
Should I store it in a database, post it to a queue ?
I'm not sure why you have a producer template, you could just build up the route instead (given that you return something from your bean or takes an Exchange as paramter).
<from uri="smpp: ..."/>
<bean ref="bean:myBean"/>
<to uri="jms:queue:myQueue"/>
then not use direct, but use a JMS queue that is transactional and persistent. Say your smpp call fails, the message would have been gone. Using a queue like this and make sure its transactional, you can make sure not to lose data in this stage of the route.
<from uri="jms:queue:myQueue"/>
<transactional/>
<to uri="smpp.."/>
I suggest using Apache ActiveMQ as JMS middleware. Actually, if you download ActiveMQ, you get camel bundled, so you could actually run your Camel routes from ActiveMQ.
You might want to tweak how retries and error handling occurs dependent on what you want to happen (retry every second forever?, retry five times, then put to error queue? etc).
Read this page: Transaction Error handling in Camel
For deeper info and more tweaks, you might also want to read this:
Transactional Client