You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by krishy <ca...@gmail.com> on 2011/06/15 18:01:07 UTC

Observer Pattern using Camel

I am working on a abstraction library that would allow a bunch of our
web-apps to include that library and
publish and subscribe to JMS destinations (and do other magical things).
Publication works fine (at least on
the POC I have!) but I am having trouble wrapping my head around
subscriptions.

The following method should allow clients to dynamically register for events
from a JMS endpoint. My
current implementation looks like this:

<code>
public void addListener(Event event, Listener listener){
    try {
        camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from(event.from()).bean(listener);
            }
        });
    } catch (Exception exception) {
        exception.printStackTrace();
    }

}
</code>

event.from() above would identify the endpoint from which the message would
be consumed 
("activemq:topic:market.stocks.update.ibm") and listener would be an
implementation of a Listener 
interface.

I had envisaged a typical invocation as:

<code>
notifications.addListener(updateEvent, new Listener(){
    void listen(){
        System.out.println("Hey! Something got updated");
    }
});
</code>

In theory, I like this approach since this frees me from having to worry
about who is subscribed to which 
queue, on what selectors etc, and I can have Camel automagically route these
messages to the interested 
listeners. 

Except, of course, none of the above works since the camel route seems to
expect a concrete bean as the 
recipient and hence camel context fails to start-up. The actual error:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type
[com.example.Listener] found for dependency: expected at least 1 bean which
qualifies as autowire 
candidate for this dependency. Dependency annotations: {}

Am I shoe-horning Camel into something it was not supposed to do? Though,
the Event Message EIP seems 
to suggest this should work (except that the examples don't seem to address
the dynamic nature of the listeners)

http://camel.apache.org/event-message.html

Being a Camel newbie, there is another aspect of this which I don't
understand. This route even though 
part of a method seems to get started when the Camel context starts up. How
does the route get added 
when the method that is supposed to add it to the context has not been
invoked?

Thanks for your help and pointers.

--
View this message in context: http://camel.465427.n5.nabble.com/Observer-Pattern-using-Camel-tp4491726p4491726.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Observer Pattern using Camel

Posted by Ashwin Karpe <ak...@fusesource.com>.
Hi,

Please check out the camel-cache component. It is capable of sending
exchanges along a route when the cache is added to, updated and/or deleted.
It supports the eventing model and could be a way to dynamically propagate
changes in the cache. From that point onwards dispatching to the right route
endpoints, subscribers etc based on the nature of the event...

Cheers,

Ashwin...

-----
---------------------------------------------------------
Ashwin Karpe
Apache Camel Committer & Sr Principal Consultant
FUSESource (a Progress Software Corporation subsidiary)
http://fusesource.com 

Blog: http://opensourceknowledge.blogspot.com 
CamelOne 2011: http://fusesource.com/camel2011 
---------------------------------------------------------
--
View this message in context: http://camel.465427.n5.nabble.com/Observer-Pattern-using-Camel-tp4491726p4492194.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Observer Pattern using Camel

Posted by krishy <ca...@gmail.com>.
Thanks for the inputs.

I was able to get my original example working after tweaking the packageScan
configuration.

The original reason the camel context failed to start was that it complained
that the bean 'Listener' could not 
be found. I removed the class, which had the above addListener method, from
the packageScan of the camel 
context and the context started up just fine. Subsequently, I was able add
routes using implementations of 
the Listener and all is well.

I suppose, since the anonymous class ends up in the classpath as being part
of the package, the scanner 
finds it and tries to inject the bean.

--
View this message in context: http://camel.465427.n5.nabble.com/Observer-Pattern-using-Camel-tp4491726p4495738.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Observer Pattern using Camel

Posted by Claus Ibsen <cl...@gmail.com>.
Try extending some base class for your anonymous listener interface,
so there is a class.

public class MyListener implements Listener {
   ..
}

The class may even be abstract.

And use new MyListener to instantiate the class. This may work then.



On Wed, Jun 15, 2011 at 6:01 PM, krishy <ca...@gmail.com> wrote:
> I am working on a abstraction library that would allow a bunch of our
> web-apps to include that library and
> publish and subscribe to JMS destinations (and do other magical things).
> Publication works fine (at least on
> the POC I have!) but I am having trouble wrapping my head around
> subscriptions.
>
> The following method should allow clients to dynamically register for events
> from a JMS endpoint. My
> current implementation looks like this:
>
> <code>
> public void addListener(Event event, Listener listener){
>    try {
>        camelContext.addRoutes(new RouteBuilder() {
>            @Override
>            public void configure() throws Exception {
>                from(event.from()).bean(listener);
>            }
>        });
>    } catch (Exception exception) {
>        exception.printStackTrace();
>    }
>
> }
> </code>
>
> event.from() above would identify the endpoint from which the message would
> be consumed
> ("activemq:topic:market.stocks.update.ibm") and listener would be an
> implementation of a Listener
> interface.
>
> I had envisaged a typical invocation as:
>
> <code>
> notifications.addListener(updateEvent, new Listener(){
>    void listen(){
>        System.out.println("Hey! Something got updated");
>    }
> });
> </code>
>
> In theory, I like this approach since this frees me from having to worry
> about who is subscribed to which
> queue, on what selectors etc, and I can have Camel automagically route these
> messages to the interested
> listeners.
>
> Except, of course, none of the above works since the camel route seems to
> expect a concrete bean as the
> recipient and hence camel context fails to start-up. The actual error:
>
> Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
> No matching bean of type
> [com.example.Listener] found for dependency: expected at least 1 bean which
> qualifies as autowire
> candidate for this dependency. Dependency annotations: {}
>
> Am I shoe-horning Camel into something it was not supposed to do? Though,
> the Event Message EIP seems
> to suggest this should work (except that the examples don't seem to address
> the dynamic nature of the listeners)
>
> http://camel.apache.org/event-message.html
>
> Being a Camel newbie, there is another aspect of this which I don't
> understand. This route even though
> part of a method seems to get started when the Camel context starts up. How
> does the route get added
> when the method that is supposed to add it to the context has not been
> invoked?
>
> Thanks for your help and pointers.
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Observer-Pattern-using-Camel-tp4491726p4491726.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.blogspot.com/
Author of Camel in Action: http://www.manning.com/ibsen/

Re: Observer Pattern using Camel

Posted by Ashwin Karpe <ak...@fusesource.com>.
Good idea, Claus...

Writing a small custom component with an event listener to deal with event
handlng and sending an exchange down a route will do the trick.

You can look at how the camel-cache accomplishes the same and come up with
your own event listener against a given resource.

Cheers,

Ashwin...

-----
---------------------------------------------------------
Ashwin Karpe
Apache Camel Committer & Sr Principal Consultant
FUSESource (a Progress Software Corporation subsidiary)
http://fusesource.com 

Blog: http://opensourceknowledge.blogspot.com 
CamelOne 2011: http://fusesource.com/camel2011 
---------------------------------------------------------
--
View this message in context: http://camel.465427.n5.nabble.com/Observer-Pattern-using-Camel-tp4491726p4494737.html
Sent from the Camel - Users mailing list archive at Nabble.com.