Return-Path: Delivered-To: apmail-activemq-commits-archive@www.apache.org Received: (qmail 94242 invoked from network); 19 Apr 2007 10:41:54 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 Apr 2007 10:41:54 -0000 Received: (qmail 52910 invoked by uid 500); 19 Apr 2007 10:42:00 -0000 Delivered-To: apmail-activemq-commits-archive@activemq.apache.org Received: (qmail 52858 invoked by uid 500); 19 Apr 2007 10:42:00 -0000 Mailing-List: contact commits-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list commits@activemq.apache.org Received: (qmail 52841 invoked by uid 99); 19 Apr 2007 10:41:59 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Apr 2007 03:41:59 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Apr 2007 03:41:51 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 1DE191A983E; Thu, 19 Apr 2007 03:41:31 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r530368 - in /activemq/camel/trunk: camel-core/src/main/java/org/apache/camel/builder/ camel-core/src/main/java/org/apache/camel/impl/ camel-core/src/main/java/org/apache/camel/spi/ camel-core/src/main/java/org/apache/camel/util/ camel-core... Date: Thu, 19 Apr 2007 10:41:29 -0000 To: commits@activemq.apache.org From: jstrachan@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070419104131.1DE191A983E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jstrachan Date: Thu Apr 19 03:41:27 2007 New Revision: 530368 URL: http://svn.apache.org/viewvc?view=rev&rev=530368 Log: added a transaction Interceptor hook to a builder so folks can customize how transactions are auto-created when things are sent to an endpoint/processed by an endpoint by default. When using camel-spring the transaction interceptor is auto-created using the TransactionTemplate in the context (if there is just one available). Also we now have a test case for the JPA based IdempotentConsumer Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java (with props) activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java (with props) activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java (with props) activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java (with props) activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/ activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/ activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java (with props) activemq/camel/trunk/camel-jpa/src/test/resources/org/ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml (with props) activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java (with props) activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java (with props) activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/ activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/ activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/ activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/ activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/TransactionInterceptor 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/builder/RouteBuilder.java activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/FactoryFinder.java activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerTest.java activemq/camel/trunk/camel-jpa/pom.xml activemq/camel/trunk/camel-jpa/src/test/resources/META-INF/persistence.xml activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringComponentResolver.java activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringInjector.java activemq/camel/trunk/camel-spring/src/main/resources/org/apache/camel/spring/camel-1.0.xsd activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/builder/SpringRouteBuilderTest.java activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/builder/spring_route_builder_test.xml 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=530368&r1=530367&r2=530368 ============================================================================== --- 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 Thu Apr 19 03:41:27 2007 @@ -280,12 +280,14 @@ if (answer.size() == 0) { return null; } + Processor processor = null; if (answer.size() == 1) { - return answer.get(0); + processor = answer.get(0); } else { - return new CompositeProcessor(answer); + processor = new CompositeProcessor(answer); } + return wrapInTransactionInterceptor(processor); } /** @@ -304,6 +306,13 @@ */ protected Processor wrapInErrorHandler(Processor processor) throws Exception { return getErrorHandlerBuilder().createErrorHandler(processor); + } + + /** + * A strategy method which allows transaction interceptors to be applied to a processor + */ + protected Processor wrapInTransactionInterceptor(Processor processor) throws Exception { + return getBuilder().getTransactionInterceptor().addIntercetors(processor); } /** Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java (original) +++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java Thu Apr 19 03:41:27 2007 @@ -19,13 +19,21 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.io.IOException; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.Route; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.util.FactoryFinder; +import org.apache.camel.util.NoFactoryAvailableException; +import org.apache.camel.spi.Interceptor; +import org.apache.camel.spi.Injector; import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.impl.ReflectionInjector; +import org.apache.camel.impl.NoInterceptor; /** * A Java DSL @@ -37,6 +45,7 @@ private List> fromBuilders = new ArrayList>(); private AtomicBoolean initalized = new AtomicBoolean(false); private List> routes = new ArrayList>(); + private Interceptor transactionInterceptor; protected RouteBuilder() { this(null); @@ -77,7 +86,7 @@ /** * Configures whether or not the error handler is inherited by every processing node (or just the top most one) * - * @param value the falg as to whether error handlers should be inherited or not + * @param value the flag as to whether error handlers should be inherited or not * @return the current builder */ public RouteBuilder inheritErrorHandler(boolean value) { @@ -85,6 +94,17 @@ return this; } + /** + * Specifies the transaction interceptor to be used for routes created from this builder + * + * @param interceptor the transaction interceptor to use + * @return the current builder + */ + public RouteBuilder transactionInterceptor(Interceptor interceptor) { + setTransactionInterceptor(interceptor); + return this; + } + // Properties //----------------------------------------------------------------------- public CamelContext getContext() { @@ -112,6 +132,20 @@ return fromBuilders; } + public Interceptor getTransactionInterceptor() throws Exception { + if (transactionInterceptor == null) { + transactionInterceptor = createTransactionInterceptor(); + } + return transactionInterceptor; + } + + /** + * Sets the interceptor used wrap processors in a transaction + */ + public void setTransactionInterceptor(Interceptor transactionInterceptor) { + this.transactionInterceptor = transactionInterceptor; + } + // Implementation methods //----------------------------------------------------------------------- protected void checkInitialized() throws Exception { @@ -144,7 +178,25 @@ return builder.createProcessor(); } + /** + * Factory method + */ protected CamelContext createContainer() { return new DefaultCamelContext(); } + + /** + * Factory method + */ + protected Interceptor createTransactionInterceptor() throws Exception { + FactoryFinder finder = new FactoryFinder(); + try { + return (Interceptor) finder.newInstance("TransactionInterceptor", getContext().getInjector()); + } + catch (NoFactoryAvailableException e) { + // lets use the default + return new NoInterceptor(); + } + } + } Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original) +++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Thu Apr 19 03:41:27 2007 @@ -318,7 +318,7 @@ * Lazily create a default implementation */ protected Injector createInjector() { - FactoryFinder finder = new FactoryFinder("META-INF/services/org/apache/camel/"); + FactoryFinder finder = new FactoryFinder(); try { return (Injector) finder.newInstance("Injector"); } Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java (added) +++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,33 @@ +/** + * + * 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.impl; + +import org.apache.camel.spi.Interceptor; +import org.apache.camel.Processor; + +/** + * Represents an {@link Interceptor} which adds no interceptors. + * + * @version $Revision: 1.1 $ + */ +public class NoInterceptor implements Interceptor { + + public Processor addIntercetors(Processor processor) { + return processor; + } +} Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/NoInterceptor.java ------------------------------------------------------------------------------ svn:eol-style = native Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java (added) +++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,37 @@ +/** + * + * 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.spi; + +import org.apache.camel.impl.ServiceSupport; +import org.apache.camel.Processor; + +/** + * A strategy capable of applying interceptors to a processor + * + * @version $Revision: 1.1 $ + */ +public interface Interceptor { + + /** + * Adds any applicable interceptors to the given processor + * + * @param processor the processor to be intercepted + * @return either the original processor or a processor wrapped in one or more interceptors + */ + Processor addIntercetors(Processor processor); +} Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/Interceptor.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/FactoryFinder.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/FactoryFinder.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/FactoryFinder.java (original) +++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/util/FactoryFinder.java Thu Apr 19 03:41:27 2007 @@ -17,6 +17,8 @@ */ package org.apache.camel.util; +import org.apache.camel.spi.Injector; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -24,10 +26,13 @@ import java.util.concurrent.ConcurrentHashMap; public class FactoryFinder { - private final String path; private final ConcurrentHashMap classMap = new ConcurrentHashMap(); + public FactoryFinder() { + this("META-INF/services/org/apache/camel/"); + } + public FactoryFinder(String path) { this.path = path; } @@ -40,25 +45,33 @@ * @return a newly created instance */ public Object newInstance(String key) - throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException - { - return newInstance(key, null); + throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException { + return newInstance(key, (String) null); } public Object newInstance(String key, String propertyPrefix) - throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException - { + throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException { Class clazz = findClass(key, propertyPrefix); return clazz.newInstance(); } + public Object newInstance(String key, Injector injector) throws IOException, ClassNotFoundException { + return newInstance(key, injector, null); + } + + public Object newInstance(String key, Injector injector, String propertyPrefix) throws IOException, ClassNotFoundException { + Class type = findClass(key, propertyPrefix); + return injector.newInstance(type); + } + public Class findClass(String key) throws ClassNotFoundException, IOException { return findClass(key, null); } public Class findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException { - if (propertyPrefix == null) + if (propertyPrefix == null) { propertyPrefix = ""; + } Class clazz = (Class) classMap.get(propertyPrefix + key); if (clazz == null) { @@ -77,7 +90,8 @@ Class clazz; try { clazz = Thread.currentThread().getContextClassLoader().loadClass(className); - } catch (ClassNotFoundException e) { + } + catch (ClassNotFoundException e) { clazz = FactoryFinder.class.getClassLoader().loadClass(className); } @@ -89,7 +103,9 @@ // lets try the thread context class loader first ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) classLoader = getClass().getClassLoader(); + if (classLoader == null) { + classLoader = getClass().getClassLoader(); + } InputStream in = classLoader.getResourceAsStream(uri); if (in == null) { in = FactoryFinder.class.getClassLoader().getResourceAsStream(uri); @@ -105,10 +121,12 @@ Properties properties = new Properties(); properties.load(reader); return properties; - } finally { + } + finally { try { reader.close(); - } catch (Exception e) { + } + catch (Exception e) { } } } Modified: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerTest.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerTest.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerTest.java (original) +++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerTest.java Thu Apr 19 03:41:27 2007 @@ -17,6 +17,7 @@ */ package org.apache.camel.processor; +import static org.apache.camel.processor.idempotent.MemoryMessageIdRepository.memoryMessageIdRepository; import junit.framework.TestCase; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -25,7 +26,6 @@ import org.apache.camel.Processor; import org.apache.camel.Exchange; import org.apache.camel.Message; -import org.apache.camel.processor.idempotent.MemoryMessageIdRepository; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.util.ProducerCache; import org.apache.camel.impl.DefaultCamelContext; @@ -42,7 +42,7 @@ public class IdempotentConsumerTest extends TestCase { private static final transient Log log = LogFactory.getLog(IdempotentConsumerTest.class); - protected CamelContext container = new DefaultCamelContext(); + protected CamelContext context; protected CountDownLatch latch = new CountDownLatch(3); protected Endpoint endpoint; protected ProducerCache client = new ProducerCache(); @@ -80,6 +80,8 @@ @Override protected void setUp() throws Exception { + context = createContext(); + final Processor processor = new Processor() { public void process(Exchange e) { Message in = e.getIn(); @@ -94,17 +96,21 @@ final String endpointUri = "queue:test.a"; // lets add some routes - container.addRoutes(createRouteBuilder(endpointUri, processor)); - endpoint = container.resolveEndpoint(endpointUri); + context.addRoutes(createRouteBuilder(endpointUri, processor)); + endpoint = context.resolveEndpoint(endpointUri); assertNotNull("No endpoint found for URI: " + endpointUri, endpoint); - container.start(); + context.start(); + } + + protected CamelContext createContext() throws Exception { + return new DefaultCamelContext(); } protected RouteBuilder createRouteBuilder(final String endpointUri, final Processor processor) { return new RouteBuilder() { public void configure() { - from(endpointUri).idempotentConsumer(header("messageId"), MemoryMessageIdRepository.memoryMessageIdRepository()).process(processor); + from(endpointUri).idempotentConsumer(header("messageId"), memoryMessageIdRepository()).process(processor); } }; } @@ -112,6 +118,6 @@ @Override protected void tearDown() throws Exception { client.stop(); - container.stop(); + context.stop(); } } Modified: activemq/camel/trunk/camel-jpa/pom.xml URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/pom.xml?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/pom.xml (original) +++ activemq/camel/trunk/camel-jpa/pom.xml Thu Apr 19 03:41:27 2007 @@ -38,6 +38,17 @@ org.apache.camel camel-core + + org.apache.camel + camel-spring + + + org.apache.camel + camel-core + test-jar + true + test + org.springframework @@ -110,15 +121,28 @@ + + + + + + + + + - + + + + + Added: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java (added) +++ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,63 @@ +/** + * + * 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.processor.idempotent.jpa; + +import org.apache.camel.processor.idempotent.MessageIdRepository; +import org.springframework.orm.jpa.JpaTemplate; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.util.List; + +/** + * @version $Revision: 1.1 $ + */ +public class JpaMessageIdRepository implements MessageIdRepository { + protected static final String QUERY_STRING = "select x from " + MessageProcessed.class.getName() + " x where x.processorName = ?1 and x.messageId = ?2"; + private JpaTemplate template; + private String processorName; + + public static JpaMessageIdRepository jpaMessageIdRepository(String persistenceUnit, String processorName) { + EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit); + return jpaMessageIdRepository(new JpaTemplate(entityManagerFactory), processorName); + } + + public static JpaMessageIdRepository jpaMessageIdRepository(JpaTemplate jpaTemplate, String processorName) { + return new JpaMessageIdRepository(jpaTemplate, processorName); + } + + public JpaMessageIdRepository(JpaTemplate template, String processorName) { + this.template = template; + this.processorName = processorName; + } + + public boolean contains(String messageId) { + List list = template.find(QUERY_STRING, processorName, messageId); + if (list.isEmpty()) { + MessageProcessed processed = new MessageProcessed(); + processed.setProcessorName(processorName); + processed.setMessageId(messageId); + template.persist(processed); + template.flush(); + return false; + } + else { + return true; + } + } +} Propchange: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java ------------------------------------------------------------------------------ svn:eol-style = native Added: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java (added) +++ activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java Thu Apr 19 03:41:27 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.processor.idempotent.jpa; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.UniqueConstraint; + +/** + * @version $Revision: 1.1 $ + */ +@Entity +@UniqueConstraint(columnNames = {"processorName", "messageId"}) +public class MessageProcessed { + private Long id; + private String messageId; + private String processorName; + + + @Override + public String toString() { + return "MessageProcessed[processorName: " + getProcessorName() + " messageId: " + getMessageId() + "]"; + } + + @Id + @GeneratedValue + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getProcessorName() { + return processorName; + } + + public void setProcessorName(String processorName) { + this.processorName = processorName; + } +} Propchange: activemq/camel/trunk/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/MessageProcessed.java ------------------------------------------------------------------------------ svn:eol-style = native Added: activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java (added) +++ activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,53 @@ +/** + * + * 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.processor.jpa; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.CamelContext; +import org.apache.camel.spring.SpringCamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.processor.IdempotentConsumerTest; +import static org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository.jpaMessageIdRepository; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.context.ApplicationContext; +import org.springframework.orm.jpa.JpaTemplate; + +/** + * @version $Revision: 1.1 $ + */ +public class JpaIdempotentConsumerTest extends IdempotentConsumerTest { + protected ApplicationContext applicationContext; + + @Override + protected CamelContext createContext() throws Exception { + applicationContext = new ClassPathXmlApplicationContext("org/apache/camel/processor/jpa/spring.xml"); + return SpringCamelContext.springCamelContext(applicationContext); + } + + @Override + protected RouteBuilder createRouteBuilder(final String endpointUri, final Processor processor) { + final JpaTemplate jpaTemplate = (JpaTemplate) applicationContext.getBean("jpaTemplate"); + + return new RouteBuilder() { + public void configure() { + from(endpointUri).idempotentConsumer(header("messageId"), jpaMessageIdRepository(jpaTemplate, "myProcessorName")).process(processor); + } + }; + } +} Propchange: activemq/camel/trunk/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaIdempotentConsumerTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: activemq/camel/trunk/camel-jpa/src/test/resources/META-INF/persistence.xml URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/test/resources/META-INF/persistence.xml?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/src/test/resources/META-INF/persistence.xml (original) +++ activemq/camel/trunk/camel-jpa/src/test/resources/META-INF/persistence.xml Thu Apr 19 03:41:27 2007 @@ -56,4 +56,15 @@ + + + org.apache.camel.processor.idempotent.jpa.MessageProcessed + + + + + + + + Added: activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml (added) +++ activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml Thu Apr 19 03:41:27 2007 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Propchange: activemq/camel/trunk/camel-jpa/src/test/resources/org/apache/camel/processor/jpa/spring.xml ------------------------------------------------------------------------------ svn:eol-style = native Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java (added) +++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,35 @@ +/** + * + * 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.spring; + +import org.springframework.context.ApplicationContext; +import org.springframework.beans.factory.wiring.BeanConfigurerSupport; + +/** + * @version $Revision: 1.1 $ + */ +public class BeanInjector extends BeanConfigurerSupport { + public BeanInjector(ApplicationContext applicationContext) throws Exception { + setBeanFactory(applicationContext); + afterPropertiesSet(); + } + + public void inject(Object bean) { + configureBean(bean); + } +} Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/BeanInjector.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java (original) +++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java Thu Apr 19 03:41:27 2007 @@ -27,6 +27,8 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.context.support.AbstractRefreshableApplicationContext; /** * A Spring aware implementation of {@link CamelContext} which will automatically register itself with Springs lifecycle @@ -39,6 +41,16 @@ public class SpringCamelContext extends DefaultCamelContext implements InitializingBean, DisposableBean, ApplicationContextAware { private ApplicationContext applicationContext; + public static SpringCamelContext springCamelContext(ApplicationContext applicationContext) throws Exception { + SpringCamelContext answer = new SpringCamelContext(); + answer.setApplicationContext(applicationContext); + return answer; + } + + public static SpringCamelContext springCamelContext(String configLocations) throws Exception { + return springCamelContext(new ClassPathXmlApplicationContext(configLocations)); + } + public void afterPropertiesSet() throws Exception { // lets force lazy initialisation getInjector(); @@ -60,7 +72,7 @@ @Override protected Injector createInjector() { - return new SpringInjector(getApplicationContext()); + return new SpringInjector((AbstractRefreshableApplicationContext) getApplicationContext()); } @Override Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringComponentResolver.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringComponentResolver.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringComponentResolver.java (original) +++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringComponentResolver.java Thu Apr 19 03:41:27 2007 @@ -17,15 +17,15 @@ */ package org.apache.camel.spring; -import static org.apache.camel.util.ObjectHelper.notNull; - -import java.net.URI; - import org.apache.camel.CamelContext; import org.apache.camel.Component; import org.apache.camel.spi.ComponentResolver; +import static org.apache.camel.util.ObjectHelper.notNull; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContext; +import java.net.URI; + /** * An implementation of {@link ComponentResolver} which tries to find a Camel {@link Component} * in the Spring {@link ApplicationContext} first; if its not there it defaults to the auto-discovery mechanism. @@ -44,7 +44,13 @@ public Component resolveComponent(String uri, CamelContext context) throws Exception { String scheme = new URI(uri).getScheme(); - Object bean = applicationContext.getBean(scheme); + Object bean = null; + try { + bean = applicationContext.getBean(scheme); + } + catch (NoSuchBeanDefinitionException e) { + // ignore its not an error + } if (bean != null) { if (bean instanceof Component) { return (Component) bean; Modified: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringInjector.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringInjector.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringInjector.java (original) +++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringInjector.java Thu Apr 19 03:41:27 2007 @@ -19,41 +19,49 @@ import org.apache.camel.spi.Injector; import org.apache.camel.impl.ReflectionInjector; +import org.apache.camel.RuntimeCamelException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.AbstractRefreshableApplicationContext; +import org.springframework.beans.factory.wiring.BeanConfigurerSupport; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import java.util.Arrays; /** - * A Spring implementation of {@link Injector} allowing Spring to be used to inject newly constructed type converters + * A Spring implementation of {@link Injector} allowing Spring to be used to dependency inject newly created POJOs * * @version $Revision$ */ public class SpringInjector extends ReflectionInjector { private static final transient Log log = LogFactory.getLog(SpringInjector.class); - private final ApplicationContext applicationContext; - public SpringInjector(ApplicationContext applicationContext) { + private final AbstractRefreshableApplicationContext applicationContext; + private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; + private boolean dependencyCheck = false; + + public SpringInjector(AbstractRefreshableApplicationContext applicationContext) { this.applicationContext = applicationContext; } public Object newInstance(Class type) { - String[] names = applicationContext.getBeanNamesForType(type, true, true); - if (names != null) { - if (names.length == 1) { - // lets instantiate the single bean - return applicationContext.getBean(names[0]); - } - else if (names.length > 1) { - log.warn("Too many beans of type: " + type.getName() + " available: " + Arrays.asList(names) + " so ignoring Spring configuration"); - } - } + return applicationContext.getBeanFactory().createBean(type, autowireMode, dependencyCheck); + } + + public int getAutowireMode() { + return autowireMode; + } - // lets instantiate the bean - Object answer = super.newInstance(type); + public void setAutowireMode(int autowireMode) { + this.autowireMode = autowireMode; + } + + public boolean isDependencyCheck() { + return dependencyCheck; + } - // TODO now lets inject spring... - return answer; + public void setDependencyCheck(boolean dependencyCheck) { + this.dependencyCheck = dependencyCheck; } } Added: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java (added) +++ activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java Thu Apr 19 03:41:27 2007 @@ -0,0 +1,68 @@ +/** + * + * 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.spring; + +import org.apache.camel.Processor; +import org.apache.camel.spi.Interceptor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +/** + * Wraps the processor in a Spring transaction + * + * @version $Revision: 1.1 $ + */ +public class SpringTransactionInterceptor implements Interceptor { + private static final transient Log log = LogFactory.getLog(SpringTransactionInterceptor.class); + + private TransactionTemplate template; + + public Processor addIntercetors(final Processor processor) { + final TransactionTemplate transactionTemplate = getTemplate(); + if (transactionTemplate == null) { + log.warn("No TransactionTemplate available so transactions will not be enabled!"); + return processor; + } + + return new Processor() { + public void process(final E exchange) { + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + protected void doInTransactionWithoutResult(TransactionStatus status) { + processor.process(exchange); + } + }); + } + + @Override + public String toString() { + return "SpringTransaction[" + processor + "]"; + } + }; + } + + public TransactionTemplate getTemplate() { + return template; + } + + public void setTemplate(TransactionTemplate template) { + this.template = template; + } +} Propchange: activemq/camel/trunk/camel-spring/src/main/java/org/apache/camel/spring/SpringTransactionInterceptor.java ------------------------------------------------------------------------------ svn:eol-style = native Added: activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/TransactionInterceptor URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/TransactionInterceptor?view=auto&rev=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/TransactionInterceptor (added) +++ activemq/camel/trunk/camel-spring/src/main/resources/META-INF/services/org/apache/camel/TransactionInterceptor Thu Apr 19 03:41:27 2007 @@ -0,0 +1 @@ +class=org.apache.camel.spring.SpringTransactionInterceptor \ No newline at end of file Modified: activemq/camel/trunk/camel-spring/src/main/resources/org/apache/camel/spring/camel-1.0.xsd URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/main/resources/org/apache/camel/spring/camel-1.0.xsd?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/main/resources/org/apache/camel/spring/camel-1.0.xsd (original) +++ activemq/camel/trunk/camel-spring/src/main/resources/org/apache/camel/spring/camel-1.0.xsd Thu Apr 19 03:41:27 2007 @@ -93,6 +93,13 @@ + + + + + + + Modified: activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/builder/SpringRouteBuilderTest.java URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/builder/SpringRouteBuilderTest.java?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/builder/SpringRouteBuilderTest.java (original) +++ activemq/camel/trunk/camel-spring/src/test/java/org/apache/camel/spring/builder/SpringRouteBuilderTest.java Thu Apr 19 03:41:27 2007 @@ -119,4 +119,16 @@ assertNotNull(builder); return builder; } + + @Override + protected RouteBuilder buildIdempotentConsumer() { + RouteBuilder builder = (RouteBuilder) ctx.getBean("buildIdempotentConsumer"); + assertNotNull(builder); + return builder; + } + + @Override + public void testIdempotentConsumer() throws Exception { + // TODO + } } Modified: activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/builder/spring_route_builder_test.xml URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/builder/spring_route_builder_test.xml?view=diff&rev=530368&r1=530367&r2=530368 ============================================================================== --- activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/builder/spring_route_builder_test.xml (original) +++ activemq/camel/trunk/camel-spring/src/test/resources/org/apache/camel/spring/builder/spring_route_builder_test.xml Thu Apr 19 03:41:27 2007 @@ -209,5 +209,21 @@ + + + + + + + + + + +