You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by cmoulliard <cm...@gmail.com> on 2009/03/13 10:41:22 UTC

Suggestion : Modification of the Camel ActiveMq Component

Hi,

I would like to suggest the following modification for the Camel ActiveMq
Component in order to allow camel (deployed top of an OSGI server like
ServiceMix 4) to call an already installed ActiveMq broker.

To use ActiveMq from Camel, the following bean must be instantiated by
spring :

<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
   <property name="brokerURL" value="vm://localhost:61616" />
</bean> 

This component is a kind of gateway who will proxy communication between the
camel routes and the broker. If the instance of the broker does not exist (=
is not started), then camel will instantiate it

To tell to the component that it should not create an instance of activemq
(because the broker has been started separately from this camel context as
this is possible in SMX4), you must change the property of the url like this
:

<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
   <property name="brokerURL" value="vm://localhost:61616?create=false" />
</bean>

To avoid confusion for the user, I propose that we have a new property that
we will use to inform the component if the broker already runs or not :

<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
   <property name="brokerURL" value="vm://localhost:61616" />
   <property name="runSeparately" value="true" />
</bean>

The second modification that I propose concerns deployment of Camel top of
an osgi server. In this case, I need your help because I'm not sure at 100%
about what I will say

If my camel routes are deployed in an osgi bundle and have reference in the
from or to uri to activemq, How camel will be able to find activemq :
1) through the brokerUrl OR
2) by passing the OSGI reference of the service who has instantiating
activemq

If we adopt the second strategy, the bean can be described like this
...

<bean id="activemq"
class="org.apache.activemq.camel.component.ActiveMQComponent">
   <property name="brokerURL"/> --> it this case, it makes no sense to use
the brokerUrl
   <property name="osgiReference" value="#activemqservice" />
</bean>

...

Maybe, we could simplify the syntax by removing this bean creation from the
camel context in order to pass directly the osgi reference of the service in
the route like

<camel:from uri="osgiref=activemq:queue:in" />

In this case, camel will create the bean
org.apache.activemq.camel.component.ActiveMQComponent and find the activemq
broker using the osgi reference of the service

Regards,





 

-----
Charles Moulliard
SOA Architect

My Blog :  http://cmoulliard.blogspot.com/ http://cmoulliard.blogspot.com/  
-- 
View this message in context: http://www.nabble.com/Suggestion-%3A-Modification-of-the-Camel-ActiveMq-Component-tp22493057p22493057.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Suggestion : Modification of the Camel ActiveMq Component

Posted by cmoulliard <cm...@gmail.com>.
<property name="createBrokerWithVmTransport" value="false" /> 

Good name except that when we would like to use an activemq server not
running in the same virtual machine, then this name is not relevant. As
activemq proposes different kind of transport
(http://cwiki.apache.org/ACTIVEMQ/configuring-transports.html), we could add
a new property :

<property name="createBroker" value="false" />
<property name="transportType" value="" /> --> where value can be vm, tcp.
For the other I'm not sure that we can use them ?

Nevertheless, I think that all the activemq parameters like those
configurated in the activemq broker of servicemix 4 must not be defined in
our Apache ActiveMq Component. Thinks must be separated for clarity to our
users.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
- <!--  Allows us to use system properties as variables in this
configuration file 
  --> 
  <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
/> 
- <broker xmlns="http://activemq.apache.org/schema/core"
brokerName="default"
dataDirectory="${servicemix.base}/data/activemq/default"
useShutdownHook="false">
- <!--  Destination specific policies using destination names or wildcards 
  --> 
- <destinationPolicy>
- <policyMap>
- <policyEntries>
  <policyEntry queue=">" memoryLimit="5mb" /> 
- <policyEntry topic=">" memoryLimit="5mb">
- <subscriptionRecoveryPolicy>
  <lastImageSubscriptionRecoveryPolicy /> 
  </subscriptionRecoveryPolicy>
  </policyEntry>
  </policyEntries>
  </policyMap>
  </destinationPolicy>
- <!--  Use the following to configure how ActiveMQ is exposed in JMX 
  --> 
- <managementContext>
  <managementContext createConnector="false" /> 
  </managementContext>
- <!--  The store and forward broker networks ActiveMQ will listen to 
  --> 
- <networkConnectors>
- <!--  by default just auto discover the other brokers 
  --> 
  <networkConnector name="default-nc" uri="multicast://default" /> 
- <!--  Example of a static configuration:
            <networkConnector name="host1 and host2"
uri="static://(tcp://host1:61616,tcp://host2:61616)"/>
            
  --> 
  </networkConnectors>
- <persistenceAdapter>
  <amqPersistenceAdapter syncOnWrite="false"
directory="${servicemix.base}/data/activemq/default" maxFileLength="20 mb"
/> 
  </persistenceAdapter>
- <!--  Use the following if you wish to configure the journal with JDBC 
  --> 
- <!--         <persistenceAdapter>
            <journaledJDBC dataDirectory="${activemq.base}/data"
dataSource="#postgres-ds"/>
        </persistenceAdapter>
        
  --> 
- <!--  Or if you want to use pure JDBC without a journal 
  --> 
- <!--         <persistenceAdapter>
            <jdbcPersistenceAdapter dataSource="#postgres-ds"/>
        </persistenceAdapter>
        
  --> 
- <!--   The maximum about of space the broker will use before slowing down
producers 
  --> 
- <systemUsage>
- <systemUsage>
- <memoryUsage>
  <memoryUsage limit="20 mb" /> 
  </memoryUsage>
- <storeUsage>
  <storeUsage limit="1 gb" name="foo" /> 
  </storeUsage>
- <tempUsage>
  <tempUsage limit="100 mb" /> 
  </tempUsage>
  </systemUsage>
  </systemUsage>
- <!--  The transport connectors ActiveMQ will listen to 
  --> 
- <transportConnectors>
  <transportConnector name="openwire" uri="tcp://localhost:61616"
discoveryUri="multicast://default" /> 
  <transportConnector name="stomp" uri="stomp://localhost:61613" /> 
  </transportConnectors>
  </broker>
- <bean id="activemqConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
  <property name="brokerURL" value="tcp://localhost:61616" /> 
  </bean>
- <bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactoryBean">
  <property name="maxConnections" value="8" /> 
  <property name="maximumActive" value="500" /> 
  <property name="transactionManager" ref="transactionManager" /> 
  <property name="connectionFactory" ref="activemqConnectionFactory" /> 
  <property name="resourceName" value="activemq.default" /> 
  </bean>
- <bean id="resourceManager"
class="org.apache.activemq.pool.ActiveMQResourceManager"
init-method="recoverResource">
  <property name="transactionManager" ref="transactionManager" /> 
  <property name="connectionFactory" ref="activemqConnectionFactory" /> 
  <property name="resourceName" value="activemq.default" /> 
  </bean>
  <osgi:reference id="transactionManager"
interface="javax.transaction.TransactionManager" /> 
- <osgi:service ref="pooledConnectionFactory">
- <osgi:interfaces>
  <value>javax.jms.ConnectionFactory</value> 
  </osgi:interfaces>
- <osgi:service-properties>
  <entry key="name" value="default" /> 
  </osgi:service-properties>
  </osgi:service>
  </beans>

My favorite approach is that the activeMq broker is configured apart of our
camel activemq bean component allowing to the user to define parameters like
pooling, persistence, transaction, ...  in one place. The fact that we
design the solution like this is required for administration purposes.
Otherwise, imagine the heads of the servers administrators when you will
inform them that the configuration of the queuing engine (polling, ...) is
embedded in the camel routes code. They will be very happy :-(

But, if the activemq broker is configured apart, does it make sense to
request to spring to instantiate a spring bean for
org.apache.camel.component.ActiveMQComponent with only one parameter "create
broker - true/false" ?



James.Strachan wrote:
> 
> 2009/3/13 cmoulliard <cm...@gmail.com>:
>>
>> Hi,
>>
>> I would like to suggest the following modification for the Camel ActiveMq
>> Component in order to allow camel (deployed top of an OSGI server like
>> ServiceMix 4) to call an already installed ActiveMq broker.
>>
>> To use ActiveMq from Camel, the following bean must be instantiated by
>> spring :
>>
>> <bean id="activemq"
>> class="org.apache.activemq.camel.component.ActiveMQComponent">
>>   <property name="brokerURL" value="vm://localhost:61616" />
>> </bean>
>>
>> This component is a kind of gateway who will proxy communication between
>> the
>> camel routes and the broker. If the instance of the broker does not exist
>> (=
>> is not started), then camel will instantiate it
>>
>> To tell to the component that it should not create an instance of
>> activemq
>> (because the broker has been started separately from this camel context
>> as
>> this is possible in SMX4), you must change the property of the url like
>> this
>> :
>>
>> <bean id="activemq"
>> class="org.apache.activemq.camel.component.ActiveMQComponent">
>>   <property name="brokerURL" value="vm://localhost:61616?create=false" />
>> </bean>
>>
>> To avoid confusion for the user, I propose that we have a new property
>> that
>> we will use to inform the component if the broker already runs or not :
>>
>> <bean id="activemq"
>> class="org.apache.activemq.camel.component.ActiveMQComponent">
>>   <property name="brokerURL" value="vm://localhost:61616" />
>>   <property name="runSeparately" value="true" />
>> </bean>
> 
> Good idea. I'd maybe call it something like
> 
> <property name="createBrokerWithVmTransport" value="false" />
> 
> as runSeparately is kinda vague and applies to different transports.
> 
> 
>> The second modification that I propose concerns deployment of Camel top
>> of
>> an osgi server. In this case, I need your help because I'm not sure at
>> 100%
>> about what I will say
>>
>> If my camel routes are deployed in an osgi bundle and have reference in
>> the
>> from or to uri to activemq, How camel will be able to find activemq :
>> 1) through the brokerUrl OR
>> 2) by passing the OSGI reference of the service who has instantiating
>> activemq
>>
>> If we adopt the second strategy, the bean can be described like this
>> ...
>>
>> <bean id="activemq"
>> class="org.apache.activemq.camel.component.ActiveMQComponent">
>>   <property name="brokerURL"/> --> it this case, it makes no sense to use
>> the brokerUrl
>>   <property name="osgiReference" value="#activemqservice" />
>> </bean>
>>
>> ...
>>
>> Maybe, we could simplify the syntax by removing this bean creation from
>> the
>> camel context in order to pass directly the osgi reference of the service
>> in
>> the route like
>>
>> <camel:from uri="osgiref=activemq:queue:in" />
>>
>> In this case, camel will create the bean
>> org.apache.activemq.camel.component.ActiveMQComponent and find the
>> activemq
>> broker using the osgi reference of the service
> 
> I guess it depends how much decoupling you want. You could expose
> individual camel endpoints into OSGi and then just refer to them via
> an OSGi URI that queries the OSGi registry for the endpoint. Using
> this approach the entire URI can be an OSGi registry name & filter
> etc.
> 
> We can also do this today using the spring-dm XML to expose any
> endpoint created in a Camel XML into OSGi - then in the routing bundle
> by looking up the endpoint by OSGi query and associating it to a local
> ID we refer to in the camel route..
> 
> Or we could refer to a component in OSGi using some prefix then let
> the remainder of the URI be the URI resolved on the component to get
> the endpoint. This latter approach is gonna mean a more noisy URI (as
> there's the OSGi lookup URI and the endpoint URI) so we might want to
> wrap that up as a bean with a few properties (the OSGI service name we
> look up, the OSGi query filter and the endpoint URI on the component
> once its resolved).
> 
> 
> Having said all that - I've often found the exact JMS configuration is
> kinda relevant to a route (e.g. is it using transactions?) so I'd
> recommend keeping the camel components with the routes just so its
> easier to understand if nothing else. However you might wanna share
> properties across bundles - such as the connection URL to activemq?
> 
> --
> James
> -------
> http://macstrac.blogspot.com/
> 
> Open Source Integration
> http://fusesource.com/
> 
> 


-----
Charles Moulliard
SOA Architect

My Blog :  http://cmoulliard.blogspot.com/ http://cmoulliard.blogspot.com/  
-- 
View this message in context: http://www.nabble.com/Suggestion-%3A-Modification-of-the-Camel-ActiveMq-Component-tp22493057p22495348.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Suggestion : Modification of the Camel ActiveMq Component

Posted by James Strachan <ja...@gmail.com>.
2009/3/13 cmoulliard <cm...@gmail.com>:
>
> Hi,
>
> I would like to suggest the following modification for the Camel ActiveMq
> Component in order to allow camel (deployed top of an OSGI server like
> ServiceMix 4) to call an already installed ActiveMq broker.
>
> To use ActiveMq from Camel, the following bean must be instantiated by
> spring :
>
> <bean id="activemq"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>   <property name="brokerURL" value="vm://localhost:61616" />
> </bean>
>
> This component is a kind of gateway who will proxy communication between the
> camel routes and the broker. If the instance of the broker does not exist (=
> is not started), then camel will instantiate it
>
> To tell to the component that it should not create an instance of activemq
> (because the broker has been started separately from this camel context as
> this is possible in SMX4), you must change the property of the url like this
> :
>
> <bean id="activemq"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>   <property name="brokerURL" value="vm://localhost:61616?create=false" />
> </bean>
>
> To avoid confusion for the user, I propose that we have a new property that
> we will use to inform the component if the broker already runs or not :
>
> <bean id="activemq"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>   <property name="brokerURL" value="vm://localhost:61616" />
>   <property name="runSeparately" value="true" />
> </bean>

Good idea. I'd maybe call it something like

<property name="createBrokerWithVmTransport" value="false" />

as runSeparately is kinda vague and applies to different transports.


> The second modification that I propose concerns deployment of Camel top of
> an osgi server. In this case, I need your help because I'm not sure at 100%
> about what I will say
>
> If my camel routes are deployed in an osgi bundle and have reference in the
> from or to uri to activemq, How camel will be able to find activemq :
> 1) through the brokerUrl OR
> 2) by passing the OSGI reference of the service who has instantiating
> activemq
>
> If we adopt the second strategy, the bean can be described like this
> ...
>
> <bean id="activemq"
> class="org.apache.activemq.camel.component.ActiveMQComponent">
>   <property name="brokerURL"/> --> it this case, it makes no sense to use
> the brokerUrl
>   <property name="osgiReference" value="#activemqservice" />
> </bean>
>
> ...
>
> Maybe, we could simplify the syntax by removing this bean creation from the
> camel context in order to pass directly the osgi reference of the service in
> the route like
>
> <camel:from uri="osgiref=activemq:queue:in" />
>
> In this case, camel will create the bean
> org.apache.activemq.camel.component.ActiveMQComponent and find the activemq
> broker using the osgi reference of the service

I guess it depends how much decoupling you want. You could expose
individual camel endpoints into OSGi and then just refer to them via
an OSGi URI that queries the OSGi registry for the endpoint. Using
this approach the entire URI can be an OSGi registry name & filter
etc.

We can also do this today using the spring-dm XML to expose any
endpoint created in a Camel XML into OSGi - then in the routing bundle
by looking up the endpoint by OSGi query and associating it to a local
ID we refer to in the camel route..

Or we could refer to a component in OSGi using some prefix then let
the remainder of the URI be the URI resolved on the component to get
the endpoint. This latter approach is gonna mean a more noisy URI (as
there's the OSGi lookup URI and the endpoint URI) so we might want to
wrap that up as a bean with a few properties (the OSGI service name we
look up, the OSGi query filter and the endpoint URI on the component
once its resolved).


Having said all that - I've often found the exact JMS configuration is
kinda relevant to a route (e.g. is it using transactions?) so I'd
recommend keeping the camel components with the routes just so its
easier to understand if nothing else. However you might wanna share
properties across bundles - such as the connection URL to activemq?

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

Open Source Integration
http://fusesource.com/