You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by James Strachan <ja...@gmail.com> on 2007/05/01 11:01:01 UTC

Re: [camel] using camel spring container

BTW I've created a little test case for this kinda use case...

https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/routingUsingProcessor.xml

https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/CustomProcessorWithNamespacesTest.java


On 4/30/07, dr.jeff <jl...@systechnologies.com> wrote:
>
> My xml looks like this:
>
> <beans xmlns="http://www.springframework.org/schema/beans"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
>        http://www.springframework.org/schema/beans ./spring-beans-2.0.xsd
>        http://activemq.apache.org/camel/schema/camel-1.0.xsd ./camel-1.0.xsd
> ">
>   <bean id="stringProcessor" class="test.StringProcessor"
> init-method="init"/>
>   <camelContext id="camel"
> xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
>     <routes>
>       <route>
>         <from uri="direct:outgoing"/>
>         <process ref="#stringProcessor"/>
>       </route>
>     </routes>
>   </camelContext>
> </beans>
>
> StringProcessor.java looks like this:
>
> public class StringProcessor implements Processor<Exchange> {
>
>         public StringProcessor() {
>         }
>         public void init() {
>                 System.out.println("new string processor");
>         }
>         public void process(Exchange e) {
>                 System.out.println("process: " + e.getIn());
>         }
> }
>
> I call it like this:
>
>         public TestSimpleXml(String ctxFile) {
>                 ctx = new ClassPathXmlApplicationContext(ctxFile);
>                 try {
>                         container = (CamelContext) ctx.getBean("camel");
>                         Endpoint<Exchange> endpoint = container.getEndpoint("direct:incoming");
>                         Exchange exchange = endpoint.createExchange();
>                 Message m = exchange.getIn();
>                 m.setBody("test message");
>                 Producer<Exchange> producer = endpoint.createProducer();
>                 producer.process(exchange);
>                 Thread.sleep(5000); //let queues clean out
>                 } catch (Exception e) {
>                         e.printStackTrace();
>                 }
>         }
>
> I see that the init() method of StringProcessor is being called. I expect to
> see the message reach the process() method, but I do not.
>
> This seems so simple. Am I still missing something?

You're using 2 different URIs...

* direct:outgoing
* direct:incoming

shouldn't they be the same? :)

(I've started to use direct:start everywhere as the first entry point
to a test case to avoid myself getting confused :)

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

Re: [camel] using camel spring container

Posted by "dr.jeff" <jl...@systechnologies.com>.
I was thinking about referring the other direction. In particular, I was
looking for a way to avoid repeating complicated URIs within the
camelContext.
But if you allow references to endpoints within the camelContext, that would
probabably be good enough.


James.Strachan wrote:
> 
> On 5/2/07, dr.jeff <jl...@systechnologies.com> wrote:
>>
>> Good stuff.
>> It might be useful to be able to refer from the camelContext out into the
>> wider Spring beans context (I would find it useful):
>>
>> <!-- define a URI here -->
>> <bean name="foo" class="java.net.URI">
>>     <constructor-arg value="jms:queue:cheese.bar"/>
>> </bean>
>>
>> <!-- refer to it here -->
>> <bean name=... class=...>
>>     <property name="foo" ref="foo"/>
>> </bean>
>> ...
>> <!-- also refer to it inside here -->
>> <camelContext>
>>   <endpoint id="foo" ref="foo"/>
> 
> Great idea!
> 
> I've just implemented it as follows...
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/endpointReference.xml
> 
> where we inject Endpoint instances into a POJO. i.e. you can define
> them within a <camelContext> then use them by reference anywhere in
> the spring.xml
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/-camel--using-camel-spring-container-tf3663875s2354.html#a10291520
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: [camel] using camel spring container

Posted by James Strachan <ja...@gmail.com>.
On 5/3/07, dr.jeff <jl...@systechnologies.com> wrote:
>
> Very good, excellent even, and nearly working.

:)


>This:
>
>   <camelContext id="camel"
> xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
>     <endpoint id="endpoint1" uri="direct:start"/>
>     <endpoint id="endpoint2" uri="mock:end"/>
>     <route>
>       <from ref="endpoint1"/>
>       <choice>
>         <when>
>           <predicate>
>             <header name="destination"/>
>             <isEqualTo value="firstChoice"/>
>           </predicate>
>           <to ref="endpoint2"/>
>         </when>
>         <otherwise>
>           <to ref="endpoint2"/>
>         </otherwise>
>       </choice>
>     </route>
>   </camelContext>
>
> gives this:
>
> Exception in thread "main"
> org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected
> exception parsing XML document from class path resource
> [endpointReference.xml]; nested exception is
> org.apache.camel.spring.xml.IllegalActionException: Illegal route.The action
> 'to' cannot be used as the starting action.

Great catch! I added your use cases as a test case; it turned out to
be a bug in the @FluentArg annotations on the WhenBuilder. Its now
fixed!

BTW is your name "Jeff Lansing"? I just wanted to check as I've
guessed and mentioned your name on a few commits & just wanted to get
it right :)

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

Re: [camel] using camel spring container

Posted by "dr.jeff" <jl...@systechnologies.com>.
Very good, excellent even, and nearly working. This:

  <camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
    <endpoint id="endpoint1" uri="direct:start"/>
    <endpoint id="endpoint2" uri="mock:end"/>
    <route>
      <from ref="endpoint1"/>
      <choice>
        <when>
          <predicate>
            <header name="destination"/>
            <isEqualTo value="firstChoice"/>
          </predicate>
          <to ref="endpoint2"/>
        </when>
        <otherwise>
          <to ref="endpoint2"/>
        </otherwise>
      </choice>
    </route>
  </camelContext>

gives this:

Exception in thread "main"
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected
exception parsing XML document from class path resource
[endpointReference.xml]; nested exception is
org.apache.camel.spring.xml.IllegalActionException: Illegal route.The action
'to' cannot be used as the starting action.
Caused by: org.apache.camel.spring.xml.IllegalActionException: Illegal
route.The action 'to' cannot be used as the starting action.
	at
org.apache.camel.spring.xml.CamelBeanDefinitionParser.parseAction(CamelBeanDefinitionParser.java:161)
	at
org.apache.camel.spring.xml.CamelBeanDefinitionParser.parseBuilderElement(CamelBeanDefinitionParser.java:87)
	at
org.apache.camel.spring.xml.CamelBeanDefinitionParser.parseBuilderElement(CamelBeanDefinitionParser.java:92)
	at
org.apache.camel.spring.xml.CamelBeanDefinitionParser.parseBuilderElement(CamelBeanDefinitionParser.java:92)
	at
org.apache.camel.spring.xml.CamelBeanDefinitionParser.parseInternal(CamelBeanDefinitionParser.java:65)
	at
org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parse(AbstractBeanDefinitionParser.java:56)
	at
org.apache.camel.spring.xml.CamelNamespaceHandler$1.doParse(CamelNamespaceHandler.java:50)
	at
org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser.parseInternal(AbstractSingleBeanDefinitionParser.java:70)
	at
org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parse(AbstractBeanDefinitionParser.java:56)
	at
org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69)
	at
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1114)
	at
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1104)
	at
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:133)
	at
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:90)
	at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:458)
	at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:353)
	at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
	at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:280)
	at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:131)
	at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:147)
	at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:173)
	at
org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:112)
	at
org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:79)
	at
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:100)
	at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:298)
	at
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:91)
	at
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:75)
	at
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:65)
...



James.Strachan wrote:
> 
> On 5/3/07, dr.jeff <jl...@systechnologies.com> wrote:
>>
>>
>>   <camelContext id="camel"
>> xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
>>     <endpoint id="endpoint1" uri="mock:endpoint1"/>
>>     <routes>
>>     </routes>
>>   </camelContext>
>>
>> This looks good, but how do I use it?
>>
>> I've tried things like:
>>
>> <from uri="endpoint1"/> and <from uri="#endpoint1"/> and <from
>> endpoint="endpoint1"/> and <from endpoint="#endpoint1/>, but all of them
>> fail, mostly for different reasons (eg. #endpoint1 is not an NMTOKEN).
>>
>> Surely it's obvious, but I'm missing it?
> 
> Ah I'd not done that bit yet :) I'd done it so that you can refer to
> Endpoint instances as bean references inside a spring <property
> name="foo" ref="someName"/>.
> 
> I've just implemented this so that now the <from> and <to> can be used
> with the references
> 
> <from uri="theURI"/> or <from ref="theReference"/>
> 
> I've added a test case to show it in action...
> 
> http://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/endpointReference.xml
> 
> Along the way I also removed the unnecesary <routes> element, so a
> context can look like
> 
> <camelContext>
>   <endpoint ... />
>   <endpoint ... />
> 
>   <route ... />
>   <route ... />
> </camelContext>
> 
> So you'll wanna so an 'svn up' of all of camel and try the new xsd etc.
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/-camel--using-camel-spring-container-tf3663875s2354.html#a10306522
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: [camel] using camel spring container

Posted by James Strachan <ja...@gmail.com>.
On 5/3/07, dr.jeff <jl...@systechnologies.com> wrote:
>
>
>   <camelContext id="camel"
> xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
>     <endpoint id="endpoint1" uri="mock:endpoint1"/>
>     <routes>
>     </routes>
>   </camelContext>
>
> This looks good, but how do I use it?
>
> I've tried things like:
>
> <from uri="endpoint1"/> and <from uri="#endpoint1"/> and <from
> endpoint="endpoint1"/> and <from endpoint="#endpoint1/>, but all of them
> fail, mostly for different reasons (eg. #endpoint1 is not an NMTOKEN).
>
> Surely it's obvious, but I'm missing it?

Ah I'd not done that bit yet :) I'd done it so that you can refer to
Endpoint instances as bean references inside a spring <property
name="foo" ref="someName"/>.

I've just implemented this so that now the <from> and <to> can be used
with the references

<from uri="theURI"/> or <from ref="theReference"/>

I've added a test case to show it in action...

http://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/endpointReference.xml

Along the way I also removed the unnecesary <routes> element, so a
context can look like

<camelContext>
  <endpoint ... />
  <endpoint ... />

  <route ... />
  <route ... />
</camelContext>

So you'll wanna so an 'svn up' of all of camel and try the new xsd etc.

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

Re: [camel] using camel spring container

Posted by "dr.jeff" <jl...@systechnologies.com>.

  <camelContext id="camel"
xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
    <endpoint id="endpoint1" uri="mock:endpoint1"/>
    <routes>
    </routes>
  </camelContext>

This looks good, but how do I use it?

I've tried things like:

<from uri="endpoint1"/> and <from uri="#endpoint1"/> and <from
endpoint="endpoint1"/> and <from endpoint="#endpoint1/>, but all of them
fail, mostly for different reasons (eg. #endpoint1 is not an NMTOKEN).

Surely it's obvious, but I'm missing it?


James.Strachan wrote:
> 
> 
> I've just implemented it as follows...
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/endpointReference.xml
> 
> where we inject Endpoint instances into a POJO. i.e. you can define
> them within a <camelContext> then use them by reference anywhere in
> the spring.xml
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/-camel--using-camel-spring-container-tf3663875s2354.html#a10297397
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: [camel] using camel spring container

Posted by James Strachan <ja...@gmail.com>.
On 5/2/07, dr.jeff <jl...@systechnologies.com> wrote:
>
> Good stuff.
> It might be useful to be able to refer from the camelContext out into the
> wider Spring beans context (I would find it useful):
>
> <!-- define a URI here -->
> <bean name="foo" class="java.net.URI">
>     <constructor-arg value="jms:queue:cheese.bar"/>
> </bean>
>
> <!-- refer to it here -->
> <bean name=... class=...>
>     <property name="foo" ref="foo"/>
> </bean>
> ...
> <!-- also refer to it inside here -->
> <camelContext>
>   <endpoint id="foo" ref="foo"/>

Great idea!

I've just implemented it as follows...
https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/endpointReference.xml

where we inject Endpoint instances into a POJO. i.e. you can define
them within a <camelContext> then use them by reference anywhere in
the spring.xml
-- 
James
-------
http://macstrac.blogspot.com/

Re: [camel] using camel spring container

Posted by "dr.jeff" <jl...@systechnologies.com>.
Good stuff. 
It might be useful to be able to refer from the camelContext out into the
wider Spring beans context (I would find it useful):

<!-- define a URI here -->
<bean name="foo" class="java.net.URI">
    <constructor-arg value="jms:queue:cheese.bar"/>
</bean>

<!-- refer to it here -->
<bean name=... class=...>
    <property name="foo" ref="foo"/>
</bean>
...
<!-- also refer to it inside here -->
<camelContext> 
  <endpoint id="foo" ref="foo"/>
...


James.Strachan wrote:
> 
> Yeah, we could definitely have some kinda mechanism like that. Maybe
> 
> <camelContext>
>   <endpoint id="foo" uri="jms:queue:cheese.bar"/>
>   <endpoint id="bar" uri="jms:queue:cheese.bar"/>
> 
>   ....
> 
>   <from ref="foo"/>
>   <to ref="bar"/>
> 
> etc
> 
> Another option is to allow URIs themselves to be references. e.g. we
> could have some kinda way of making an alias to a URI (using some
> kinda syntax as above), then we could use a uri of the form
> 
> ref:referenceName to refer to it?
> 
> <camelContext>
>   <endpoint id="foo" uri="jms:queue:cheese.bar"/>
>   <endpoint id="bar" uri="jms:queue:cheese.bar"/>
> 
>   ....
> 
>   <from uri="ref:foo"
>   <to uri="ref:bar"/>
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/-camel--using-camel-spring-container-tf3663875s2354.html#a10289533
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: [camel] using camel spring container

Posted by James Strachan <ja...@gmail.com>.
On 5/1/07, dr.jeff <jl...@systechnologies.com> wrote:
>
> It would help to avoid these kind of errors if there was some mechanism in
> place to refer to URIs by reference, somewhat in the way that Spring refs
> work. If I have:
>
>   <!-- constants -->
>   <bean name="xslt" class="java.lang.String">
>     <constructor-arg value="./xslt/InputToOutput.xslt"/>
>   </bean>
>
> then I can do:
>
>   <bean id="transformBrook" class="com.syys.camel.interceptor.Transformer"
> init-method="init">
>     <property name="xslt" ref="xslt"/>
>   </bean>
>   <bean id="transformTini" class="com.syys.camel.interceptor.Transformer"
> init-method="init">
>     <property name="xslt" ref="xslt"/>
>   </bean>
>   ...
> because I have more than one flow using transformers.
>
> My suggestion is to extend this to the camel-spring.

Yeah, we could definitely have some kinda mechanism like that. Maybe

<camelContext>
  <endpoint id="foo" uri="jms:queue:cheese.bar"/>
  <endpoint id="bar" uri="jms:queue:cheese.bar"/>

  ....

  <from ref="foo"/>
  <to ref="bar"/>

etc

This does complicate the grammar a little in that every uri can be
specified by a "uri" or a "ref" parameter - but this could maybe help
the XML tooling (as hopefully the IDE will understand the type of
'ref' so do smart completion?).

Another option is to allow URIs themselves to be references. e.g. we
could have some kinda way of making an alias to a URI (using some
kinda syntax as above), then we could use a uri of the form

ref:referenceName to refer to it?

<camelContext>
  <endpoint id="foo" uri="jms:queue:cheese.bar"/>
  <endpoint id="bar" uri="jms:queue:cheese.bar"/>

  ....

  <from uri="ref:foo"
  <to uri="ref:bar"/>

The latter is cleaner from the implementation perspective (as we just
need to write a RefComponent to deal with aliases and there's no need
to litter the schema with optional "uri or ref" logic), but maybe the
former is better on the tooling front?


BTW in Java code its easy to do this today

Endpoint foo = endpoint("jms:queue:foo.bar.whanot");
Endpoint bar = endpoint("file:cheese/bar");

from(foo).to(bar);

etc

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

Re: [camel] using camel spring container

Posted by "dr.jeff" <jl...@systechnologies.com>.
It would help to avoid these kind of errors if there was some mechanism in
place to refer to URIs by reference, somewhat in the way that Spring refs
work. If I have:

  <!-- constants -->
  <bean name="xslt" class="java.lang.String">
    <constructor-arg value="./xslt/InputToOutput.xslt"/>
  </bean>

then I can do:

  <bean id="transformBrook" class="com.syys.camel.interceptor.Transformer"
init-method="init">
    <property name="xslt" ref="xslt"/>
  </bean>
  <bean id="transformTini" class="com.syys.camel.interceptor.Transformer"
init-method="init">
    <property name="xslt" ref="xslt"/>
  </bean>
  ...
because I have more than one flow using transformers.

My suggestion is to extend this to the camel-spring.


James.Strachan wrote:
> 
> 
> You're using 2 different URIs...
> 
> * direct:outgoing
> * direct:incoming
> 
> shouldn't they be the same? :)
> 
> (I've started to use direct:start everywhere as the first entry point
> to a test case to avoid myself getting confused :)
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/-camel--using-camel-spring-container-tf3663875s2354.html#a10277041
Sent from the ActiveMQ - User mailing list archive at Nabble.com.