You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2007/04/24 19:37:47 UTC

svn commit: r532024 - in /activemq/camel/trunk: camel-core/src/main/java/org/apache/camel/builder/ camel-core/src/main/java/org/apache/camel/component/mock/ camel-jms/ camel-jms/src/main/java/org/apache/camel/component/jms/ camel-jms/src/test/java/org/...

Author: chirino
Date: Tue Apr 24 10:37:42 2007
New Revision: 532024

URL: http://svn.apache.org/viewvc?view=rev&rev=532024
Log:
- Added a TransactedJmsRouteTest.java to test using Spring transactions with JMS cammel endpoints.
- Added a expectedMinimumCount attribute to the Mock endpoint so we can assert that at least a certin number of messages were received.
- Added policy methods to the FromBuilder so that custome Policy objects can be used in the middle of a processing route
- Added trace methods to the FromBuilder so that trace logging can easily be enabled on a route.



Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/PolicyBuilder.java
    activemq/camel/trunk/camel-jms/src/test/java/org/apache/camel/component/jms/TransactedJmsRouteTest.java
    activemq/camel/trunk/camel-jms/src/test/resources/org/
    activemq/camel/trunk/camel-jms/src/test/resources/org/apache/
    activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/
    activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/
    activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/
    activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/spring.xml
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
    activemq/camel/trunk/camel-jms/pom.xml
    activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsComponent.java
    activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
    activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/xml/CamelBeanDefinitionParser.java

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java Tue Apr 24 10:37:42 2007
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.builder;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
@@ -28,15 +32,17 @@
 import org.apache.camel.processor.RecipientList;
 import org.apache.camel.processor.idempotent.IdempotentConsumer;
 import org.apache.camel.processor.idempotent.MessageIdRepository;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import org.apache.camel.spi.Policy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * @version $Revision$
  */
 public class FromBuilder<E extends Exchange> extends BuilderSupport<E> implements ProcessorFactory<E> {
+	
+	public static final String DEFAULT_TRACE_CATEGORY = "org.apache.camel.TRACE";
+
     private RouteBuilder<E> builder;
     private Endpoint<E> from;
     private List<Processor<E>> processors = new ArrayList<Processor<E>>();
@@ -236,6 +242,36 @@
         addProcessBuilder(answer);
         return answer;
     }
+    
+    /**
+     * Trace logs the exchange before it goes to the next processing step using the {@link DEFAULT_TRACE_CATEGORY} logging
+     * category.
+     * 
+     * @return
+     */
+    @Fluent
+	public FromBuilder<E> trace() {
+		return trace(DEFAULT_TRACE_CATEGORY);
+	}
+	
+    /**
+     * Trace logs the exchange before it goes to the next processing step using the specified logging
+     * category.
+     * 
+     * @param category the logging category trace messages will sent to.
+     * @return
+     */
+    @Fluent
+	public FromBuilder<E> trace(@FluentArg("category")String category) {
+		final Log log = LogFactory.getLog(category);
+		return intercept(new DelegateProcessor<E>(){
+			@Override
+			public void process(E exchange) {
+				log.trace(exchange);
+				processNext(exchange);
+			}
+		});
+	}    
 
     @Fluent
     public FromBuilder<E> intercept(@FluentArg("interceptor")DelegateProcessor<E> interceptor) {
@@ -245,6 +281,21 @@
         return answer.target();
     }
 
+    @Fluent(nestedActions = true)
+    public PolicyBuilder<E> policies() {
+    	PolicyBuilder<E> answer = new PolicyBuilder<E>(this);
+        addProcessBuilder(answer);
+        return answer;
+    }
+
+    @Fluent
+    public FromBuilder<E> policy(@FluentArg("policy")Policy<E> policy) {
+        PolicyBuilder<E> answer = new PolicyBuilder<E>(this);
+        answer.add(policy);
+        addProcessBuilder(answer);
+        return answer.target();
+    }
+
     // Transformers
     //-------------------------------------------------------------------------
 
@@ -303,8 +354,6 @@
         return this;
     }
 
-
-
     // Properties
     //-------------------------------------------------------------------------
     public RouteBuilder<E> getBuilder() {
@@ -390,4 +439,5 @@
     public List<Processor<E>> getProcessors() {
         return processors;
     }
+
 }

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/PolicyBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/PolicyBuilder.java?view=auto&rev=532024
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/PolicyBuilder.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/PolicyBuilder.java Tue Apr 24 10:37:42 2007
@@ -0,0 +1,66 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.builder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Policy;
+
+/**
+ * @version $Revision: 519943 $
+ */
+public class PolicyBuilder<E extends Exchange> implements ProcessorFactory<E> {
+    private final ArrayList<Policy<E>> policies = new ArrayList<Policy<E>>();
+	private final FromBuilder<E> parent;
+	private FromBuilder<E> target;
+
+	public PolicyBuilder(FromBuilder<E> parent) {
+        this.parent = parent;
+	}
+	
+	@Fluent("policy")
+	public PolicyBuilder<E> add(@FluentArg("ref") Policy<E> interceptor) {
+		policies.add(interceptor);
+		return this;
+	}
+	
+	@Fluent(callOnElementEnd=true)
+    public FromBuilder<E> target() {
+        this.target = new FromBuilder<E>(parent);
+        return target;
+    }
+
+    public Processor<E> createProcessor() throws Exception {
+    	
+    	// The target is required.
+    	if( target == null ) 
+    		throw new RuntimeCamelException("target not provided.");
+    	
+        Processor<E> last = target.createProcessor();
+    	Collections.reverse(policies);
+        for (Policy<E> p : policies) {
+            last = p.wrap(last);
+        }
+        
+        return last;
+    }
+}

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/mock/MockEndpoint.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/mock/MockEndpoint.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/mock/MockEndpoint.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/component/mock/MockEndpoint.java Tue Apr 24 10:37:42 2007
@@ -51,27 +51,11 @@
     private List<Runnable> tests = new ArrayList<Runnable>();
     private CountDownLatch latch;
     private long sleepForEmptyTest = 0L;
+	private int expectedMinimumCount=-1;
 
     public static void assertIsSatisfied(MockEndpoint... endpoints) throws InterruptedException {
-        // lets only wait on the first empty endpoint
-        int count = 0;
         for (MockEndpoint endpoint : endpoints) {
-            if (endpoint.getExpectedCount() != 0) {
-                endpoint.assertIsSatisfied();
-                count++;
-            }
-        }
-
-        for (MockEndpoint endpoint : endpoints) {
-            if (endpoint.getExpectedCount() == 0) {
-                if (count == 0) {
-                    endpoint.assertIsSatisfied();
-                    count++;
-                }
-                else {
-                    endpoint.assertIsSatisfied(0);
-                }
-            }
+            endpoint.assertIsSatisfied();
         }
     }
 
@@ -130,6 +114,12 @@
             int receivedCounter = getReceivedCounter();
             assertEquals("Received message count" , expectedCount, receivedCounter);
         }
+        
+        if( expectedMinimumCount >= 0 ) {
+            int receivedCounter = getReceivedCounter();
+            assertTrue("Received message count "+receivedCounter+", expected at least "+expectedCount, expectedCount <= receivedCounter);
+        	
+        }
 
         for (Runnable test : tests) {
             test.run();
@@ -159,6 +149,21 @@
     }
 
     /**
+     * Specifies the minimum number of expected message exchanges that should be received by this endpoint
+     *
+     * @param expectedCount the number of message exchanges that should be expected by this endpoint
+     */
+    public void expectedMinimumMessageCount(int expectedCount) {
+        this.expectedMinimumCount = expectedCount;
+        if (expectedCount <= 0) {
+            latch = null;
+        }
+        else {
+            latch = new CountDownLatch(expectedMinimumCount);
+        }
+    }
+
+    /**
      * Adds an expectation that the given body values are received by this endpoint
      */
     public void expectedBodiesReceived(final List bodies) {
@@ -313,4 +318,8 @@
     protected void fail(Object message) {
         throw new AssertionError(getEndpointUri() + " " + message);
     }
+
+	public int getExpectedMinimumCount() {
+		return expectedMinimumCount;
+	}
 }

Modified: activemq/camel/trunk/camel-jms/pom.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jms/pom.xml?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-jms/pom.xml (original)
+++ activemq/camel/trunk/camel-jms/pom.xml Tue Apr 24 10:37:42 2007
@@ -38,6 +38,19 @@
       <groupId>org.apache.camel</groupId>
       <artifactId>camel-core</artifactId>
     </dependency>
+    
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core</artifactId>
+      <type>test-jar</type>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring</artifactId>
+      <optional>true</optional>
+      <scope>test</scope>
+    </dependency>
 
     <dependency>
       <groupId>org.springframework</groupId>

Modified: activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsComponent.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsComponent.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsComponent.java (original)
+++ activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsComponent.java Tue Apr 24 10:37:42 2007
@@ -19,10 +19,12 @@
 
 import static org.apache.camel.util.ObjectHelper.removeStartingCharacters;
 import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.util.IntrospectionSupport;
 import org.apache.camel.util.ObjectHelper;
+import org.springframework.transaction.PlatformTransactionManager;
 
 import javax.jms.ConnectionFactory;
 import java.util.Map;
@@ -61,10 +63,25 @@
      */
     public static JmsComponent jmsComponentClientAcknowledge(ConnectionFactory connectionFactory) {
         JmsConfiguration template = new JmsConfiguration(connectionFactory);
-        template.setProducerAcknowledgementMode("CLIENT_ACKNOWLEDGE");
-        template.setConsumerAcknowledgementMode("CLIENT_ACKNOWLEDGE");
+        template.setProducerAcknowledgementMode(JmsConfiguration.CLIENT_ACKNOWLEDGE);
+        template.setConsumerAcknowledgementMode(JmsConfiguration.CLIENT_ACKNOWLEDGE);
         return jmsComponent(template);
     }
+
+    public static JmsComponent jmsComponentTransacted(ConnectionFactory connectionFactory) {
+        JmsConfiguration template = new JmsConfiguration(connectionFactory);
+        template.setProducerAcknowledgementMode(JmsConfiguration.TRANSACTED);
+        template.setConsumerAcknowledgementMode(JmsConfiguration.TRANSACTED);
+        return jmsComponent(template);
+    }
+
+	public static JmsComponent jmsComponentTransacted(ConnectionFactory connectionFactory, PlatformTransactionManager transactionManager) {
+        JmsConfiguration template = new JmsConfiguration(connectionFactory);
+        template.setProducerAcknowledgementMode(JmsConfiguration.TRANSACTED);
+        template.setConsumerAcknowledgementMode(JmsConfiguration.TRANSACTED);
+        template.setTransactionManager(transactionManager);
+        return jmsComponent(template);
+	}
 
     public JmsComponent() {
         this.configuration = new JmsConfiguration();

Modified: activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java (original)
+++ activemq/camel/trunk/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java Tue Apr 24 10:37:42 2007
@@ -41,6 +41,8 @@
  */
 public class JmsConfiguration implements Cloneable {
     protected static final String TRANSACTED = "TRANSACTED";
+    protected static final String CLIENT_ACKNOWLEDGE = "CLIENT_ACKNOWLEDGE";
+    
     private ConnectionFactory connectionFactory;
     private ConnectionFactory producerConnectionFactory;
     private ConsumerType consumerType = ConsumerType.Default;

Added: activemq/camel/trunk/camel-jms/src/test/java/org/apache/camel/component/jms/TransactedJmsRouteTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jms/src/test/java/org/apache/camel/component/jms/TransactedJmsRouteTest.java?view=auto&rev=532024
==============================================================================
--- activemq/camel/trunk/camel-jms/src/test/java/org/apache/camel/component/jms/TransactedJmsRouteTest.java (added)
+++ activemq/camel/trunk/camel-jms/src/test/java/org/apache/camel/component/jms/TransactedJmsRouteTest.java Tue Apr 24 10:37:42 2007
@@ -0,0 +1,134 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jms;
+
+import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.DelegateProcessor;
+import org.apache.camel.spi.Policy;
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.camel.spring.SpringRouteBuilder;
+import org.apache.camel.spring.spi.SpringTransactionPolicy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.support.TransactionTemplate;
+
+/**
+ * @version $Revision: 529902 $
+ */
+public class TransactedJmsRouteTest extends ContextTestSupport {
+	
+	private static final transient Log log = LogFactory.getLog(TransactedJmsRouteTest.class);
+	private MockEndpoint mockEndpointA;
+	private MockEndpoint mockEndpointB;
+	private ClassPathXmlApplicationContext spring;
+
+	@Override
+	protected RouteBuilder createRouteBuilder() {
+		return new SpringRouteBuilder<Exchange>() {
+			public void configure() {
+				
+		        Policy requried = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_REQUIRED"));
+		        Policy notsupported = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_NOT_SUPPORTED"));
+		        Policy requirenew = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_REQUIRES_NEW"));
+
+		        DelegateProcessor rollback = new DelegateProcessor() {
+		        	@Override
+		        	public void process(Object exchange) {
+		        		processNext(exchange);
+		        		throw new RuntimeException("rollback");
+		        	}
+		        };
+		        				
+		        // Used to verify that transacted sends will succeed.
+				from("activemq:queue:mock.a").trace().to("mock:a");      // Used to validate messages are sent to the target.
+		        
+				// Receive from a and send to target in 1 tx.
+		        transactionPolicy("PROPAGATION_REQUIRED");
+				from("activemq:queue:a").trace().to("activemq:queue:mock.a");
+				
+				// Cause an error after processing the send.  The send to activemq:queue:mock.a should rollback 
+				// since it is participating in the inbound transaction, but mock:b does not participate so we should see the message get
+				// there.  Also, expect multiple inbound retries as the message is rolled back.
+				from("activemq:queue:b").inheritErrorHandler(false).trace().intercept(rollback).to("activemq:queue:mock.a", "mock:b"); 
+
+			}
+		};
+	}
+	
+    protected CamelContext createCamelContext() throws Exception {
+        spring = new ClassPathXmlApplicationContext("org/apache/camel/component/jms/spring.xml");
+        SpringCamelContext ctx =  SpringCamelContext.springCamelContext(spring);
+        PlatformTransactionManager transactionManager = (PlatformTransactionManager) spring.getBean("jmsTransactionManager");
+        ConnectionFactory connectionFactory = (ConnectionFactory) spring.getBean("jmsConnectionFactory");
+        JmsComponent component = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
+        component.getConfiguration().setConcurrentConsumers(1);
+		ctx.addComponent("activemq", component);
+        return ctx;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mockEndpointA = (MockEndpoint) resolveMandatoryEndpoint("mock:a");
+        mockEndpointB = (MockEndpoint) resolveMandatoryEndpoint("mock:b");
+    }
+
+	public void testReuqiredSend() throws Exception {
+		String expected = getName()+": "+System.currentTimeMillis();
+        mockEndpointA.expectedBodiesReceived(expected);
+        send("activemq:queue:a", expected);
+        assertIsSatisfied(mockEndpointA);
+	}
+
+	public void testRequiredSendAndRollback() throws Exception {
+		String expected = getName()+": "+System.currentTimeMillis();
+        mockEndpointA.expectedMessageCount(0);
+        mockEndpointB.expectedMinimumMessageCount(5); // May be more since spring seems to go into tight loop redelivering.
+        send("activemq:queue:b", expected);
+        assertIsSatisfied(mockEndpointA,mockEndpointB);
+        int t = mockEndpointB.getReceivedCounter();
+        System.out.println("Actual Deliveries: "+t);
+	}
+
+	/** 
+	 * Validates that the send was done in a new transaction.  Message should be consumed from A,
+	 * But
+	 * 
+	 * @throws Exception
+	 */
+	public void xtestSendRequireNewAndRollack() throws Exception {
+		String expected = getName()+": "+System.currentTimeMillis();
+        mockEndpointA.expectedMessageCount(0);
+
+        send("activemq:queue:a", expected);
+
+        assertIsSatisfied(mockEndpointA);
+	}
+
+}

Added: activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/spring.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/spring.xml?view=auto&rev=532024
==============================================================================
--- activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/spring.xml (added)
+++ activemq/camel/trunk/camel-jms/src/test/resources/org/apache/camel/component/jms/spring.xml Tue Apr 24 10:37:42 2007
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+  <bean id="PROPAGATION_REQUIRED" class="org.springframework.transaction.support.TransactionTemplate">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+  </bean>
+  
+  <bean id="PROPAGATION_NOT_SUPPORTED" class="org.springframework.transaction.support.TransactionTemplate">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+    <property name="propagationBehaviorName" value="PROPAGATION_NOT_SUPPORTED"/>
+  </bean>
+
+  <bean id="PROPAGATION_REQUIRES_NEW" class="org.springframework.transaction.support.TransactionTemplate">
+    <property name="transactionManager" ref="jmsTransactionManager"/>
+    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
+  </bean>
+
+  <bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
+    <property name="connectionFactory" ref="jmsConnectionFactory" />
+  </bean>
+  
+  <bean id="jpsTemplate" class="org.springframework.jms.core.JmsTemplate">
+    <property name="connectionFactory" ref="jmsConnectionFactory"/>
+  </bean>
+
+  <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
+    <property name="brokerURL" value="vm://localhost?broker.persistent=false&amp;broker.useJmx=false"/>
+  </bean>
+
+</beans>
\ No newline at end of file

Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java (original)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java Tue Apr 24 10:37:42 2007
@@ -19,8 +19,8 @@
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
-import org.apache.camel.spring.spi.SpringTransactionPolicy;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spring.spi.SpringTransactionPolicy;
 import org.springframework.context.ApplicationContext;
 import org.springframework.transaction.support.TransactionTemplate;
 
@@ -40,7 +40,7 @@
      *                                {@link TransactionTemplate} to use
      * @return this builder
      */
-    public SpringRouteBuilder<E> transactionInterceptor(String transactionTemplateName) {
+    public SpringRouteBuilder<E> transactionPolicy(String transactionTemplateName) {
         TransactionTemplate template = bean(TransactionTemplate.class, transactionTemplateName);
         setTransactionPolicy(new SpringTransactionPolicy(template));
         return this;

Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java (original)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java Tue Apr 24 10:37:42 2007
@@ -62,7 +62,7 @@
 
             @Override
             public String toString() {
-                return "SpringTransaction[" + getNext() + "]";
+                return "SpringTransactionPolicy[" + getNext() + "]";
             }
         };
     }

Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/xml/CamelBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/xml/CamelBeanDefinitionParser.java?view=diff&rev=532024&r1=532023&r2=532024
==============================================================================
--- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/xml/CamelBeanDefinitionParser.java (original)
+++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/xml/CamelBeanDefinitionParser.java Tue Apr 24 10:37:42 2007
@@ -29,9 +29,11 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.camel.Expression;
 import org.apache.camel.builder.Fluent;
 import org.apache.camel.builder.FluentArg;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.ValueBuilder;
 import org.springframework.beans.SimpleTypeConverter;
 import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -200,12 +202,25 @@
 				
 				ArrayList<BuilderAction> actions = new ArrayList<BuilderAction>();
 				Class type = parseBuilderElement(element, RouteBuilder.class, actions);
+
+				if ( type == ValueBuilder.class && clazz==Expression.class ) {					
+					Method method;
+					try {
+						method = ValueBuilder.class.getMethod("getExpression", new Class[]{});
+					} catch (Throwable e) {
+						throw new RuntimeException(ValueBuilder.class.getName()+" does not have the getExpression() method.");
+					}
+					MethodInfo methodInfo = new MethodInfo(method, null, new LinkedHashMap<String, Class>(), new LinkedHashMap<String, FluentArg>());
+					actions.add(new BuilderAction(methodInfo, new HashMap<String, Object>()));
+					type = Expression.class;
+				} 
+				
 				BuilderStatement statement = new BuilderStatement();
 				statement.setReturnType(type);
 				statement.setActions(actions);
 				
-				if( !clazz.isAssignableFrom( statement.getReturnType() ) ) {
-					throw new IllegalStateException("Builder does not produce object of expected type: "+clazz.getName());
+				if( !clazz.isAssignableFrom( statement.getReturnType() ) ) {					
+					throw new IllegalStateException("Builder does not produce object of expected type: "+clazz.getName()+", it produced: "+statement.getReturnType());
 				}
 				
 				return statement;