We are doing a request reply pattern with aggregation where camel routes a message from one endpoint to many other endpoints; Camel aggregates the replies back and sends them to the original sender.
We are using the TimeoutAwareAggregationStrategy and capturing a timeout in the callback to the timeout method.
The timeout method takes in Exchange oldExchange, int index, int total, long timeout. However, I am not able to find out the name or the URL of the endpoint which timed out.
I imagine that the index can be used to get the endpoint that timed out but I am not able to find out how to get it.
Any help is appreciated. Thanks.
Related
Here is the scenario
1) Alexa sends a request to an API
2) API handles the request and functionality and sends back a response
Please find my questions below
How long can the API take to respond back to Alexa or in other words
how long will Alexa (echo) device wait for the response until it times
out ?
Also it is configurable?
Any solution to make sure the API returns back the response before a
timeout?
The Alexa timeout is 10 seconds and you cannot change this, please follow this thread
I have to integrate with a legacy host that uses TCP/IP communication with separate request and response channels. You send a request to the host on one channel where it is the server, and you need to have a server channel open on which it will send the response some time later. The communication is asynchronous, so there is no guarantee that the next message you receive will be the response to the request you just sent - you have to use a correlation key in the response to tie it back to the request.
I have a Camel route that takes the incoming request and sends it out to the host, and another route that listens for the responses. I have a third route that uses an aggregator to tie the response back to the request using a correlation key. Roughly speaking, the routes look like this:
from("direct:myService")
.process(exchange -> exchange.setProperty("CorrelationKey", exchange.getIn().getBody(MyMessage.class).getCorrelationKey())
.to("netty4:tcp://somehost:555")
.to("direct:aggregate");
from("netty4:tcp://localhost:555")
.process(exchange -> exchange.setProperty("CorrelationKey", exchange.getIn().getBody(MyResponse.class).getCorrelationKey())
.to("direct:aggregate");
from("direct:aggregate")
.aggregate(header("CorrelationKey"), (oldEx, newEx) -> {
if (oldEx == null) {
return newEx;
}
oldEx.getOut().setBody(newEx.getIn().getBody());
oldEx.setProperty(Exchange.AGGREGATION_COMPLETE_CURRENT_GROUP, true)
return oldEx;
}).completionTimeout(5000)
.process(exchange -> logger.log("Received response"));
The aggregation strategy works in the sense that I only see the log message once the response has been processed. The problem is that the request route ("direct:myService") doesn't wait for the aggregation - it has already returned back to the caller. What I want is for that route to block until the aggregation strategy has got the response, so that the message received by the netty4 consumer is used as the out message of the direct:myService route. Is that possible?
I have 1,000,000 IDs, and need to call a REST API once per day for each user. How can I use Camel to send batch HTTP requests?
My current solution is to create an HTTP component for every ID, using Quartz. But It will create 1,000,000 Quartz jobs, the performance is bad.
I have two ideas:
If Camel can provide a batch API, I could use that to send 1,000,000
requests to the same URL but with different parameters. That is one
Quartz job. Does Camel support that API?
Every HTTP request only visit one time, and use spring schedule to
control. But for each request Camel will poll the server. How can I
make Camel only call the REST API once?
The codes here:
// ids is a List, contains 1,000,000 id
for (final String id : ids) {
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from(String.format("quartz://%s/?cron=0+0+12+*+*+?", id))
.to(String.format("http:xxx.com?id=%s", id))
.to("file:to");
}
});
}
It could more heave to create million routes for sending the request with different id.
with the help of bean, you can define the loop of sending the request in the bean method.
BTW, you can change the id with message header "CamelHttpQuery".
I'm trying to consume a webservice from camel using the cxf component, like this:
<cxf:cxfEndpoint id="webservice"
address="http://webservice.url.com/webservice"
serviceClass="com.url.webservice.MyWebService"/>
<camel:camelContext>
<camel:route>
<camel:from uri="direct:a"/>
<camel:inOnly uri="cxf:bean:webservice?defaultOperationName=sendMessage"/>
</camel:route>
</camel:camelContext>
The sendMessage method has no response, hence the inOnly rather than to (although I have the same problem when I try to instead). The problem is that apparently camel still expects a response, and the route hangs while waiting for one. I suppose if I let it try long enough, it would eventually time out.
To be clear, I'm running a test method:
/* ... */
#Produce(uri = "direct:a")
protected ProducerTemplate directA;
#Test
public void sendMessage() throws Exception {
directA.sendBody(new String[] {"client id", "message"});
directB.sendBody(new String[] {"client id", "message 2"});
}
And I'm seeing the effect of the first call (that is, the message arrives at the server), but not the second, and the method doesn't finish running (again, I'm assuming it'll timeout at some point... if so, the timeout's pretty long: I ran the test as I started writing this, and it's still running).
Am I missing something? Is it a bug? Is it just bad practice to have webservice methods with no response?
By the way, when testing methods which have a response, it works fine.
I think Willem Jiang recently fixed some issue with one-way CXF in Camel recently. Maybe try Camel 2.6-SNAPSHOT from trunk.
I personally prefer two-way with web services, just returning some ACK back in case there is no data to return back. The client most often want some confirmation the server has received and acknowledged the data.
camel-cxf producer decides if it will handle the response message by checking if the operation is oneway. Even the sendMessage operation is oneway invocation, your server should send Http states 202 message to the client according the HTTP protocol, otherwise camel-cxf producer will still wait for the response.
BTW, I think the issue[1] that Claus said was related to async invocation of camel-cxf producer with one way message, not sure if it's the same issue as you mentioned(I didn't know which version of camel are you using).
[1]https://issues.apache.org/jira/browse/CAMEL-3426
Willem
I'd like to start multiple HTTP requests rapidly after each other, without having to wait on the previous response to arrive. I've tried this using WebClient.UploadStringAsync, but this doesn't work. I'd like to efficiently implement the following scenario:
Send request 1
Send request 2
Send request 3
And in another thread:
Receive response 1
Receive response 2
Receive response 3
Can this be done in Silverlight?
I'd like to start multiple HTTP requests rapidly after each other, without having to wait on the previous response to arrive
That's called HTTP Pipelining (assuming you hope to use the same socket) and it's not supported by many proxies and gateway devices. I would be surprised if Silverlight tried to support it.
Yes it can be done. What leads you to believe that UploadStringAsync isn't working?
Here is my guess you are posting to ASP.NET with Sessions turned on (the default) right?
The requests will be queued at the server end because ASP.NET will only process one request for a specific Session at a time.