You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Nick Outram <ap...@nickoutram.name> on 2007/08/15 15:21:46 UTC

PollingConsumer with a seda endpoint

I've set up a PollingConsumer against a sesa enpoint:

Endpoint endpoint = camelContext.getEndpoint("seda:message.out.payments");
try {
  pollingConsumer = endpoint.createPollingConsumer();
} catch (Exception e) {
  ...
}

and am sending messages to it using CamelTemplate:

...
try {
  template.send("seda:message.out.payments", new Processor() {
    public void process(Exchange exchange) {
      Message in = exchange.getIn();
      in.setBody("Wibble);
    }
  });
} catch (Exception e) {
...
}

but the messages aren't reaching the PollingConsumer's BlockingQueue
although they are visible on the seda endpoint reference held by the
PollingConsumer.

Is there some trick to setting this up that I'm missing?

-N
-- 
View this message in context: http://www.nabble.com/PollingConsumer-with-a-seda-endpoint-tf4273057s22882.html#a12161911
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: PollingConsumer with a seda endpoint

Posted by James Strachan <ja...@gmail.com>.
On 8/16/07, Nick Outram <ap...@nickoutram.name> wrote:
> James.Strachan wrote:
> >
> > On 8/15/07, Nick Outram <ap...@nickoutram.name> wrote:
> >> Nick Outram wrote:
> >> >
> >> > I've set up a PollingConsumer against a sesa enpoint:
> >> >
> >> > Endpoint endpoint =
> >> camelContext.getEndpoint("seda:message.out.payments");
> >> > try {
> >> >   pollingConsumer = endpoint.createPollingConsumer();
> >> > } catch (Exception e) {
> >> >   ...
> >> > }
> >> >
> >> > and am sending messages to it using CamelTemplate:
> >> >
> >> > ...
> >> > try {
> >> >   template.send("seda:message.out.payments", new Processor() {
> >> >     public void process(Exchange exchange) {
> >> >       Message in = exchange.getIn();
> >> >       in.setBody("Wibble);
> >> >     }
> >> >   });
> >> > } catch (Exception e) {
> >> > ...
> >> > }
> >> >
> >> > but the messages aren't reaching the PollingConsumer's BlockingQueue
> >> > although they are visible on the seda endpoint reference held by the
> >> > PollingConsumer.
> >> >
> >> > Is there some trick to setting this up that I'm missing?
> >> >
> >> > -N
> >> >
> >>
> >> Silly me... I hadn't started the Consumer (sigh) Working now.:teeth:
> >
> > :)
> >
> > I wonder if there's a way to log a warning to a user maybe...
> >
> > Its a common gotcha with JMS - forgetting to start the connection.
> > There's a similar issue with Camel, starting the context / producer /
> > consumers. CamelTemplate helps, for a producer side though.
> >
> > Maybe using the bean integration can help hide folks from the
> > underlying Camel API and so insulate users from forgetting to call the
> > lifecycle?
> > http://activemq.apache.org/camel/bean-integration.html
> >
> > --
> > James
> > -------
> > http://macstrac.blogspot.com/
> >
> >
> The bean-integration can/does help a lot but it hard codes the endpoint url
> which is a problem for us.

Note that the @EndpointInject can use an actual uri argument like this...

class Cheese {
  @EndpointInject(uri="activemq:myQueeue")
  ProducerTemplate senderA;
...
}

Or it can use a named reference to an endpoint...

class Cheese {
  @EndpointInject(name="mySender")
  ProducerTemplate senderA;
...
}

The name is then used to lookup the endpoint in the registry (such as
the spring XML).

Incidentally - I guess we could also default the name of the endpoint
to the name of the field/property if no name is given?
http://issues.apache.org/activemq/browse/CAMEL-108

So you can use the actual URI or a named reference to an endpoint.


> In our application we've developed a provider component wrapper 'BusProxy'
> that takes any component implementing an iis.provider.Service interface and
> exposes it on the Bus with a standard set of endpoints: direct:pojo
> (Synchronous), direct:message.in & out, seda:message.in & out,
> activemq:message.in & out.

Thats an awesome idea. Its kinda the ServiceActivator pattern...
http://www.enterpriseintegrationpatterns.com/MessagingAdapter.html

or the Messaging Mapper
http://www.enterpriseintegrationpatterns.com/MessagingMapper.html


I'd love to add this feature as a standard Camel option; marking a
POJO as a service (maybe using a @Service annotation?) which camel
then has a default set of endpoints on which the service will be
exposed.

So you could have 100 POJOs and one configuration of the URIs to
expose all POJOs etc. e.g. imagine something like

<serviceActivator>
  <uri>direct:${service}</uri>
  <uri>seda:message.in.${service}</uri>
  <uri>activemq:message.in.${service}</uri>
</serviceActivator>

(or something similar in Java)


> In order to distinguish different BusProxy
> wrapped provider components the component name is appended to the endpoints
> i.e seda:message.in.payments or seda:message.in.benebank. The problem is to
> get the component name, the spring bean name and the @EndpointInject…
> annotation etc to match up.

Yeah. I think this should be done automatically. e.g. via the
CamelBeanPostProcessor, which can detect say @Service then bind the
component to all the various endpoint URIs in the serviceActivator
configuration.

(We could even support named serviceActivation configuration; so we
could activate different kinds of services on different kinds of
endpoints - such as admin stuff being separate from business objects
etc)

@Service(name="admin") versus @Service etc

I can imagine folks will normally have a single serviceActivation
configuration; maybe 2, one for business objects one for
management/operational stuff. Maybe even more; but the main point is I
see folks having tons of beans, but much fewer serviceActivation
configurations - so using the @Service annotation to refer to the
default configuration, or a named configuration, would save having to
put all those endpoint uris/references in the code.


> Further compounded by the need to be able to
> switch implementations of any endpoint with mocks; both camel mocks and
> Jmock, for testing etc. (it was here I came unstuck with the PollingConsumer
> when trying to get my test class to send a request to the BusProxy wrapped
> component and assert on the return coming from seda:message.out.payments
> endpoint. The PollingConsumer is created in the test's @Before method but
> has to be manually started, not sure why)
>
> In case you're wondering the Bus Proxy also provides standard security,
> validation, error handling and payload mapping infrastructure as well as the
> endpoints.

Ooh that sounds great! So I guess if we did have some standard
serviceActivator feature in the CamelBeanPostProcessor; we'd also need
hooks to apply interceptors for security, validation, error handling
and so forth too. Am less sure how that would look - got any juicy
examples you can share? :)


> Still working on it… any thoughts welcome.

BTW we really welcome patches :)
http://activemq.apache.org/camel/contributing.html

It does sound fantastic stuff though! Am hoping we can add something
like this ASAP! :)

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

Re: PollingConsumer with a seda endpoint

Posted by Nick Outram <ap...@nickoutram.name>.


James.Strachan wrote:
> 
> On 8/15/07, Nick Outram <ap...@nickoutram.name> wrote:
>>
>>
>>
>> Nick Outram wrote:
>> >
>> > I've set up a PollingConsumer against a sesa enpoint:
>> >
>> > Endpoint endpoint =
>> camelContext.getEndpoint("seda:message.out.payments");
>> > try {
>> >   pollingConsumer = endpoint.createPollingConsumer();
>> > } catch (Exception e) {
>> >   ...
>> > }
>> >
>> > and am sending messages to it using CamelTemplate:
>> >
>> > ...
>> > try {
>> >   template.send("seda:message.out.payments", new Processor() {
>> >     public void process(Exchange exchange) {
>> >       Message in = exchange.getIn();
>> >       in.setBody("Wibble);
>> >     }
>> >   });
>> > } catch (Exception e) {
>> > ...
>> > }
>> >
>> > but the messages aren't reaching the PollingConsumer's BlockingQueue
>> > although they are visible on the seda endpoint reference held by the
>> > PollingConsumer.
>> >
>> > Is there some trick to setting this up that I'm missing?
>> >
>> > -N
>> >
>>
>> Silly me... I hadn't started the Consumer (sigh) Working now.:teeth:
> 
> :)
> 
> I wonder if there's a way to log a warning to a user maybe...
> 
> Its a common gotcha with JMS - forgetting to start the connection.
> There's a similar issue with Camel, starting the context / producer /
> consumers. CamelTemplate helps, for a producer side though.
> 
> Maybe using the bean integration can help hide folks from the
> underlying Camel API and so insulate users from forgetting to call the
> lifecycle?
> http://activemq.apache.org/camel/bean-integration.html
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 
The bean-integration can/does help a lot but it hard codes the endpoint url
which is a problem for us. 

In our application we’ve developed a provider component wrapper ‘BusProxy’
that takes any component implementing an iis.provider.Service interface and
exposes it on the Bus with a standard set of endpoints: direct:pojo
(Synchronous), direct:message.in & out, seda:message.in & out,
activemq:message.in & out. In order to distinguish different BusProxy
wrapped provider components the component name is appended to the endpoints
i.e seda:message.in.payments or seda:message.in.benebank. The problem is to
get the component name, the spring bean name and the @EndpointInject…
annotation etc to match up. Further compounded by the need to be able to
switch implementations of any endpoint with mocks; both camel mocks and
Jmock, for testing etc. (it was here I came unstuck with the PollingConsumer
when trying to get my test class to send a request to the BusProxy wrapped
component and assert on the return coming from seda:message.out.payments
endpoint. The PollingConsumer is created in the test's @Before method but
has to be manually started, not sure why)

In case you’re wondering the Bus Proxy also provides standard security,
validation, error handling and payload mapping infrastructure as well as the
endpoints.

Still working on it… any thoughts welcome.

-N

-- 
View this message in context: http://www.nabble.com/PollingConsumer-with-a-seda-endpoint-tf4273057s22882.html#a12176891
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: PollingConsumer with a seda endpoint

Posted by James Strachan <ja...@gmail.com>.
On 8/15/07, Nick Outram <ap...@nickoutram.name> wrote:
>
>
>
> Nick Outram wrote:
> >
> > I've set up a PollingConsumer against a sesa enpoint:
> >
> > Endpoint endpoint = camelContext.getEndpoint("seda:message.out.payments");
> > try {
> >   pollingConsumer = endpoint.createPollingConsumer();
> > } catch (Exception e) {
> >   ...
> > }
> >
> > and am sending messages to it using CamelTemplate:
> >
> > ...
> > try {
> >   template.send("seda:message.out.payments", new Processor() {
> >     public void process(Exchange exchange) {
> >       Message in = exchange.getIn();
> >       in.setBody("Wibble);
> >     }
> >   });
> > } catch (Exception e) {
> > ...
> > }
> >
> > but the messages aren't reaching the PollingConsumer's BlockingQueue
> > although they are visible on the seda endpoint reference held by the
> > PollingConsumer.
> >
> > Is there some trick to setting this up that I'm missing?
> >
> > -N
> >
>
> Silly me... I hadn't started the Consumer (sigh) Working now.:teeth:

:)

I wonder if there's a way to log a warning to a user maybe...

Its a common gotcha with JMS - forgetting to start the connection.
There's a similar issue with Camel, starting the context / producer /
consumers. CamelTemplate helps, for a producer side though.

Maybe using the bean integration can help hide folks from the
underlying Camel API and so insulate users from forgetting to call the
lifecycle?
http://activemq.apache.org/camel/bean-integration.html

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

Re: PollingConsumer with a seda endpoint

Posted by Nick Outram <ap...@nickoutram.name>.


Nick Outram wrote:
> 
> I've set up a PollingConsumer against a sesa enpoint:
> 
> Endpoint endpoint = camelContext.getEndpoint("seda:message.out.payments");
> try {
>   pollingConsumer = endpoint.createPollingConsumer();
> } catch (Exception e) {
>   ...
> }
> 
> and am sending messages to it using CamelTemplate:
> 
> ...
> try {
>   template.send("seda:message.out.payments", new Processor() {
>     public void process(Exchange exchange) {
>       Message in = exchange.getIn();
>       in.setBody("Wibble);
>     }
>   });
> } catch (Exception e) {
> ...
> }
> 
> but the messages aren't reaching the PollingConsumer's BlockingQueue
> although they are visible on the seda endpoint reference held by the
> PollingConsumer.
> 
> Is there some trick to setting this up that I'm missing?
> 
> -N
> 

Silly me... I hadn't started the Consumer (sigh) Working now.:teeth:
-- 
View this message in context: http://www.nabble.com/PollingConsumer-with-a-seda-endpoint-tf4273057s22882.html#a12163848
Sent from the Camel - Users mailing list archive at Nabble.com.