You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Ivan Dubrov <wf...@gmail.com> on 2008/12/09 16:37:38 UTC

Asynchronously sending POSTed data to the JMS queue.

Hi!

The question is how can I asynchronously submit data received by Jetty
component to the JMS queue?

The use-case:

1) Client submits data using the POST to the specific URL
2) The message is received by the application and submitted to the JMS queue
3) Empty response is sent to the client (HTTP code is 200, meaning
everything is OK, message was received for later processing).
...
4) Message is extracted from the queue and processed by some logic.

I’ve tried this variant:

<route>
  <from uri="jetty:http://localhost:8080/greeter"/>
  <to uri="activemq:queue:GREET" />
</route>

but it works synchronously, the response is not sent to the client (who
sends the POST) until the message is processed. The reason is that Jetty
component generates HttpExchange that always has exchange pattern InOut,
therefore JmsProducer, created by the JmsComponent waits for the reply.

I found the following workaround:

<route>
 <from uri="jetty:http://localhost:8080/greeter"/>
 <to uri="bean:async?method=send" />
</route>

there async bean is instance of:

public class AsyncBean {
    @EndpointInject(uri = "activemq:GREET")
    ProducerTemplate<Exchange> producer;
    public String doSomething(String msg) {
        producer.sendBody(msg);
        return ""; // Send empty HTTP response to the client
    }
}

but I don’t like this solution too much, because I need one bean for
each HTTP->JMS queue case (because of endpoint hard-coded in the
annotation). Is there cleaner way to do this? Ideally, I want everything
specified in the camel-context.xml only.

-- 
WBR,
Ivan S. Dubrov



Re: Asynchronously sending POSTed data to the JMS queue.

Posted by James Strachan <ja...@gmail.com>.
2008/12/9 Ivan Dubrov <wf...@gmail.com>:
> James Strachan wrote:
>> The JMS endpoint uses whatever exchange pattern its given. For more
>> background see
>> http://activemq.apache.org/camel/exchange-pattern.html
>>
>> so you could explicitly configure the endpoint to use inOnly...
>>
>> <route>
>>  <from uri="jetty:http://localhost:8080/greeter"/>
>>  <to uri="activemq:queue:GREET?exchangePattern=InOnly" />
>> </route>
>>
>>
>>
>>
> Does not work for me. I found that exchange passed to the
> JmsProducer#exchange method (which posts message to the JMS queue) is
> HttpExchange, which has ExchangePattern always set to InOut by
> HttpExchange constructor. Therefore, JmsProducer#exchange method always
> chooses to wait for the reply.

Damn! I guess the only option is the custom processor then - until we
add explicit pattern methods to the DSL


-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Re: Asynchronously sending POSTed data to the JMS queue.

Posted by Ivan Dubrov <wf...@gmail.com>.
James Strachan wrote:
> The JMS endpoint uses whatever exchange pattern its given. For more
> background see
> http://activemq.apache.org/camel/exchange-pattern.html
>
> so you could explicitly configure the endpoint to use inOnly...
>
> <route>
>  <from uri="jetty:http://localhost:8080/greeter"/>
>  <to uri="activemq:queue:GREET?exchangePattern=InOnly" />
> </route>
>
>
>
>   
Does not work for me. I found that exchange passed to the
JmsProducer#exchange method (which posts message to the JMS queue) is
HttpExchange, which has ExchangePattern always set to InOut by
HttpExchange constructor. Therefore, JmsProducer#exchange method always
chooses to wait for the reply.


-- 
WBR,
Ivan S. Dubrov



Re: Asynchronously sending POSTed data to the JMS queue.

Posted by James Strachan <ja...@gmail.com>.
2008/12/9 Ivan Dubrov <wf...@gmail.com>:
> Hi!
>
> The question is how can I asynchronously submit data received by Jetty
> component to the JMS queue?
>
> The use-case:
>
> 1) Client submits data using the POST to the specific URL
> 2) The message is received by the application and submitted to the JMS queue
> 3) Empty response is sent to the client (HTTP code is 200, meaning
> everything is OK, message was received for later processing).
> ...
> 4) Message is extracted from the queue and processed by some logic.
>
> I've tried this variant:
>
> <route>
>  <from uri="jetty:http://localhost:8080/greeter"/>
>  <to uri="activemq:queue:GREET" />
> </route>
>
> but it works synchronously, the response is not sent to the client (who
> sends the POST) until the message is processed. The reason is that Jetty
> component generates HttpExchange that always has exchange pattern InOut,
> therefore JmsProducer, created by the JmsComponent waits for the reply.
>
> I found the following workaround:
>
> <route>
>  <from uri="jetty:http://localhost:8080/greeter"/>
>  <to uri="bean:async?method=send" />
> </route>
>
> there async bean is instance of:
>
> public class AsyncBean {
>    @EndpointInject(uri = "activemq:GREET")
>    ProducerTemplate<Exchange> producer;
>    public String doSomething(String msg) {
>        producer.sendBody(msg);
>        return ""; // Send empty HTTP response to the client
>    }
> }
>
> but I don't like this solution too much, because I need one bean for
> each HTTP->JMS queue case (because of endpoint hard-coded in the
> annotation). Is there cleaner way to do this? Ideally, I want everything
> specified in the camel-context.xml only.

The JMS endpoint uses whatever exchange pattern its given. For more
background see
http://activemq.apache.org/camel/exchange-pattern.html

so you could explicitly configure the endpoint to use inOnly...

<route>
 <from uri="jetty:http://localhost:8080/greeter"/>
 <to uri="activemq:queue:GREET?exchangePattern=InOnly" />
</route>



-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Re: Asynchronously sending POSTed data to the JMS queue.

Posted by James Strachan <ja...@gmail.com>.
Yeah - I'm hoping for 2.0 we can add exchange pattern specification to
the DSL. Maybe something like

from("...").inOnly("...");

or

from("...").inOut("...");


2008/12/9 Ivan Dubrov <wf...@gmail.com>:
> Ivan Dubrov wrote:
>
> Oh, actually, the solution was already mentioned in this list. Simply
> add this processor:
>
> private class InOnlyProcessor implements Processor {
>    public void process(Exchange exchange) throws Exception {
>        exchange.setPattern(ExchangePattern.*InOnly*);
>    }
> }
>
> to the pipeline:
>
> <bean id="inonly" class="my.InOnlyProcessor"/>
> <route>
>  <from uri="jetty:http://localhost:8080/greeter"/>
>  <process ref="inonly" />
>  <to uri="activemq:queue:GREET"/>
> </route>
>
>> Hi!
>>
>> The question is how can I asynchronously submit data received by Jetty
>> component to the JMS queue?
>>
>> The use-case:
>>
>> 1) Client submits data using the POST to the specific URL
>> 2) The message is received by the application and submitted to the JMS queue
>> 3) Empty response is sent to the client (HTTP code is 200, meaning
>> everything is OK, message was received for later processing).
>> ...
>> 4) Message is extracted from the queue and processed by some logic.
>>
>> I've tried this variant:
>>
>> <route>
>>   <from uri="jetty:http://localhost:8080/greeter"/>
>>   <to uri="activemq:queue:GREET" />
>> </route>
>>
>> but it works synchronously, the response is not sent to the client (who
>> sends the POST) until the message is processed. The reason is that Jetty
>> component generates HttpExchange that always has exchange pattern InOut,
>> therefore JmsProducer, created by the JmsComponent waits for the reply.
>>
>> I found the following workaround:
>>
>> <route>
>>  <from uri="jetty:http://localhost:8080/greeter"/>
>>  <to uri="bean:async?method=send" />
>> </route>
>>
>> there async bean is instance of:
>>
>> public class AsyncBean {
>>     @EndpointInject(uri = "activemq:GREET")
>>     ProducerTemplate<Exchange> producer;
>>     public String doSomething(String msg) {
>>         producer.sendBody(msg);
>>         return ""; // Send empty HTTP response to the client
>>     }
>> }
>>
>> but I don't like this solution too much, because I need one bean for
>> each HTTP->JMS queue case (because of endpoint hard-coded in the
>> annotation). Is there cleaner way to do this? Ideally, I want everything
>> specified in the camel-context.xml only.
>>
>>
>
>
> --
> WBR,
> Ivan S. Dubrov
>
>



-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Re: Asynchronously sending POSTed data to the JMS queue.

Posted by Ivan Dubrov <wf...@gmail.com>.
Ivan Dubrov wrote:

Oh, actually, the solution was already mentioned in this list. Simply
add this processor:

private class InOnlyProcessor implements Processor {
    public void process(Exchange exchange) throws Exception {
        exchange.setPattern(ExchangePattern.*InOnly*);
    }
}

to the pipeline:

<bean id="inonly" class="my.InOnlyProcessor"/>
<route>
  <from uri="jetty:http://localhost:8080/greeter"/>
  <process ref="inonly" />
  <to uri="activemq:queue:GREET"/>
</route>

> Hi!
>
> The question is how can I asynchronously submit data received by Jetty
> component to the JMS queue?
>
> The use-case:
>
> 1) Client submits data using the POST to the specific URL
> 2) The message is received by the application and submitted to the JMS queue
> 3) Empty response is sent to the client (HTTP code is 200, meaning
> everything is OK, message was received for later processing).
> ...
> 4) Message is extracted from the queue and processed by some logic.
>
> I’ve tried this variant:
>
> <route>
>   <from uri="jetty:http://localhost:8080/greeter"/>
>   <to uri="activemq:queue:GREET" />
> </route>
>
> but it works synchronously, the response is not sent to the client (who
> sends the POST) until the message is processed. The reason is that Jetty
> component generates HttpExchange that always has exchange pattern InOut,
> therefore JmsProducer, created by the JmsComponent waits for the reply.
>
> I found the following workaround:
>
> <route>
>  <from uri="jetty:http://localhost:8080/greeter"/>
>  <to uri="bean:async?method=send" />
> </route>
>
> there async bean is instance of:
>
> public class AsyncBean {
>     @EndpointInject(uri = "activemq:GREET")
>     ProducerTemplate<Exchange> producer;
>     public String doSomething(String msg) {
>         producer.sendBody(msg);
>         return ""; // Send empty HTTP response to the client
>     }
> }
>
> but I don’t like this solution too much, because I need one bean for
> each HTTP->JMS queue case (because of endpoint hard-coded in the
> annotation). Is there cleaner way to do this? Ideally, I want everything
> specified in the camel-context.xml only.
>
>   


-- 
WBR,
Ivan S. Dubrov