Author: jstrachan
Date: Tue Aug 12 10:20:09 2008
New Revision: 685233
URL: http://svn.apache.org/viewvc?rev=685233&view=rev
Log:
added an initial implementation of CAMEL-816 to support @Produce and @Consume
Added:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
(contents, props changed)
- copied, changed from r685117,
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
(with props)
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
(with props)
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
(with props)
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
(with props)
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
(with props)
Modified:
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
Copied:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
(from r685117,
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java)
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java?p2=activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java&p1=activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java&r1=685117&r2=685233&rev=685233&view=diff
==============================================================================
---
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/MessageDriven.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
Tue Aug 12 10:20:09 2008
@@ -22,19 +22,20 @@
import java.lang.annotation.Target;
/**
- * Used to indicate a method on a POJO which is used as a [EMAIL PROTECTED]
Consumer} of
- * [EMAIL PROTECTED] Exchange} instances to process [EMAIL PROTECTED] Message}
instances.
- *
- * Either a <a href="http://activemq.apache.org/camel/uris.html">URI</a> for an
- * endpoint should be configured, or a name of an endpoint which refers to a
- * Spring bean name in your Spring ApplicationContext.
+ * Subscribes a method to an [EMAIL PROTECTED] Endpoint} either via its
+ * <a href="http://activemq.apache.org/camel/uris.html">URI</a> or via the
name of the endpoint reference
+ * which is then resolved in a registry such as the Spring Application Context.
+ *
+ * When a message [EMAIL PROTECTED] Exchange} is received from the [EMAIL
PROTECTED] Endpoint} then the
+ * <a href="http://activemq.apache.org/camel/bean-integration.html">Bean
Integration</a>
+ * mechanism is used to map the incoming [EMAIL PROTECTED] Message} to the
method parameters.
*
* @version $Revision$
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR })
-public @interface MessageDriven {
+public @interface Consume {
String uri() default "";
- String name() default "";
+ String ref() default "";
}
Propchange:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Consume.java
------------------------------------------------------------------------------
svn:mergeinfo =
Added:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java?rev=685233&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
(added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,43 @@
+/**
+ * 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;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a field or property as being a producer to an [EMAIL PROTECTED]
org.apache.camel.Endpoint} either via its
+ * <a href="http://activemq.apache.org/camel/uris.html">URI</a> or via the
name of the endpoint reference
+ * which is then resolved in a registry such as the Spring Application Context.
+ *
+ * Methods invoked on the producer object are then converted to a message
[EMAIL PROTECTED] org.apache.camel.Exchange} via the
+ * <a href="http://activemq.apache.org/camel/bean-integration.html">Bean
Integration</a>
+ * mechanism.
+ *
+ * @see InOnly
+ *
+ * @version $Revision: 630591 $
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED]({ElementType.FIELD, ElementType.METHOD,
ElementType.CONSTRUCTOR })
+public @interface Produce {
+ public abstract String uri() default "";
+
+ public abstract String ref() default "";
+}
\ No newline at end of file
Propchange:
activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/Produce.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java?rev=685233&r1=685232&r2=685233&view=diff
==============================================================================
---
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
(original)
+++
activemq/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
Tue Aug 12 10:20:09 2008
@@ -24,23 +24,16 @@
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
-import org.apache.camel.CamelContextAware;
-import org.apache.camel.Consumer;
-import org.apache.camel.Endpoint;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.MessageDriven;
-import org.apache.camel.PollingConsumer;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.Service;
+import org.apache.camel.*;
import org.apache.camel.component.bean.BeanProcessor;
+import org.apache.camel.component.bean.ProxyHelper;
import org.apache.camel.impl.DefaultProducerTemplate;
import org.apache.camel.spring.util.ReflectionUtils;
import org.apache.camel.util.ObjectHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
+import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
@@ -115,12 +108,20 @@
public void doWith(Field field) throws IllegalArgumentException,
IllegalAccessException {
EndpointInject annotation =
field.getAnnotation(EndpointInject.class);
if (annotation != null) {
- ReflectionUtils.setField(field, bean,
getEndpointInjectionValue(annotation, field.getType(), field.getName()));
+ injectField(field, annotation.uri(), annotation.name(),
bean);
+ }
+ Produce produce = field.getAnnotation(Produce.class);
+ if (produce != null) {
+ injectField(field, produce.uri(), produce.ref(), bean);
}
}
});
}
+ protected void injectField(Field field, String endpointUri, String
endpointRef, Object bean) {
+ ReflectionUtils.setField(field, bean,
getInjectionValue(field.getType(), endpointUri, endpointRef, field.getName()));
+ }
+
protected void injectMethods(final Object bean) {
ReflectionUtils.doWithMethods(bean.getClass(), new
ReflectionUtils.MethodCallback() {
@SuppressWarnings("unchecked")
@@ -134,15 +135,23 @@
protected void setterInjection(Method method, Object bean) {
EndpointInject annoation = method.getAnnotation(EndpointInject.class);
if (annoation != null) {
- Class<?>[] parameterTypes = method.getParameterTypes();
- if (parameterTypes != null) {
- if (parameterTypes.length != 1) {
- LOG.warn("Ignoring badly annotated method for injection
due to incorrect number of parameters: " + method);
- } else {
- String propertyName = ObjectHelper.getPropertyName(method);
- Object value = getEndpointInjectionValue(annoation,
parameterTypes[0], propertyName);
- ObjectHelper.invokeMethod(method, bean, value);
- }
+ setterInjection(method, bean, annoation.uri(), annoation.name());
+ }
+ Produce produce = method.getAnnotation(Produce.class);
+ if (produce != null) {
+ setterInjection(method, bean, produce.uri(), produce.ref());
+ }
+ }
+
+ protected void setterInjection(Method method, Object bean, String
endpointUri, String endpointRef) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes != null) {
+ if (parameterTypes.length != 1) {
+ LOG.warn("Ignoring badly annotated method for injection due to
incorrect number of parameters: " + method);
+ } else {
+ String propertyName = ObjectHelper.getPropertyName(method);
+ Object value = getInjectionValue(parameterTypes[0],
endpointUri, endpointRef, propertyName);
+ ObjectHelper.invokeMethod(method, bean, value);
}
}
}
@@ -176,20 +185,29 @@
MessageDriven annotation = method.getAnnotation(MessageDriven.class);
if (annotation != null) {
LOG.info("Creating a consumer for: " + annotation);
+ subscribeMethod(method, bean, annotation.uri(), annotation.name());
+ }
- // lets bind this method to a listener
- String injectionPointName = method.getName();
- Endpoint endpoint = getEndpointInjection(annotation.uri(),
annotation.name(), injectionPointName);
- if (endpoint != null) {
- try {
- Processor processor = createConsumerProcessor(bean,
method, endpoint);
- LOG.info("Created processor: " + processor);
- Consumer consumer = endpoint.createConsumer(processor);
- startService(consumer);
- } catch (Exception e) {
- LOG.warn(e);
- throw new RuntimeCamelException(e);
- }
+ Consume consume = method.getAnnotation(Consume.class);
+ if (consume != null) {
+ LOG.info("Creating a consumer for: " + consume);
+ subscribeMethod(method, bean, consume.uri(), consume.ref());
+ }
+ }
+
+ protected void subscribeMethod(Method method, Object bean, String
endpointUri, String endpointName) {
+ // lets bind this method to a listener
+ String injectionPointName = method.getName();
+ Endpoint endpoint = getEndpointInjection(endpointUri, endpointName,
injectionPointName);
+ if (endpoint != null) {
+ try {
+ Processor processor = createConsumerProcessor(bean, method,
endpoint);
+ LOG.info("Created processor: " + processor);
+ Consumer consumer = endpoint.createConsumer(processor);
+ startService(consumer);
+ } catch (Exception e) {
+ LOG.warn(e);
+ throw new RuntimeCamelException(e);
}
}
}
@@ -210,10 +228,10 @@
/**
- * Creates the value for the injection point for the given annotation
+ * Creates the object to be injected for an [EMAIL PROTECTED]
org.apache.camel.EndpointInject} or [EMAIL PROTECTED] Produce} injection point
*/
- protected Object getEndpointInjectionValue(EndpointInject annotation,
Class<?> type, String injectionPointName) {
- Endpoint endpoint = getEndpointInjection(annotation.uri(),
annotation.name(), injectionPointName);
+ protected Object getInjectionValue(Class<?> type, String endpointUri,
String endpointRef, String injectionPointName) {
+ Endpoint endpoint = getEndpointInjection(endpointUri, endpointRef,
injectionPointName);
if (endpoint != null) {
if (type.isInstance(endpoint)) {
return endpoint;
@@ -223,6 +241,13 @@
return new DefaultProducerTemplate(getCamelContext(),
endpoint);
} else if (type.isAssignableFrom(PollingConsumer.class)) {
return createInjectionPollingConsumer(endpoint);
+ } else if (type.isInterface()) {
+ // lets create a proxy
+ try {
+ return ProxyHelper.createProxy(endpoint, type);
+ } catch (Exception e) {
+ throw new BeanInstantiationException(type, "Could not
instantiate proxy of type " + type.getName() + " on endpoint " + endpoint, e);
+ }
} else {
throw new IllegalArgumentException("Invalid type: " +
type.getName() + " which cannot be injected via @EndpointInject for " +
endpoint);
}
Added:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java?rev=685233&view=auto
==============================================================================
---
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
(added)
+++
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,25 @@
+/**
+ *
+ * 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.produce;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public interface MyListener {
+ String sayHello(String name);
+}
Propchange:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java?rev=685233&view=auto
==============================================================================
---
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
(added)
+++
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,38 @@
+/**
+ *
+ * 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.produce;
+
+import org.apache.camel.Consume;
+import org.springframework.stereotype.Service;
+
+/**
+ * @version $Revision: 1.1 $
+ */
[EMAIL PROTECTED]
+public class MyListenerService implements MyListener {
+
+ public MyListenerService() {
+ System.out.println("Instantiated service: " + this);
+ }
+
+ @Consume(uri = "direct:myService")
+ public String sayHello(String name) {
+ System.out.println("Invoked sayHello with: " + name);
+ return "Hello " + name;
+ }
+}
Propchange:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/MyListenerService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java?rev=685233&view=auto
==============================================================================
---
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
(added)
+++
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,50 @@
+/**
+ * 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.produce;
+
+import java.util.List;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Produce;
+import org.apache.camel.spring.remoting.IAsyncService;
+import org.apache.camel.spring.remoting.SpringRemotingWithOneWayTest;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import
org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests;
+
+/**
+ * @version $Revision: 685051 $
+ */
[EMAIL PROTECTED]
+public class ProduceTest extends AbstractJUnit38SpringContextTests {
+ private static final Log LOG = LogFactory.getLog(ProduceTest.class);
+
+ @Produce(uri = "direct:myService")
+ protected MyListener producer;
+
+ public void testInvokeService() throws Exception {
+ // lets send a message
+ String actual = producer.sayHello("James");
+ assertEquals("response", "Hello James", actual);
+
+ }
+}
\ No newline at end of file
Propchange:
activemq/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/produce/ProduceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
URL:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml?rev=685233&view=auto
==============================================================================
---
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
(added)
+++
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
Tue Aug 12 10:20:09 2008
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<!-- START SNIPPET: example -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
+ http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
+ ">
+
+
+ <context:component-scan base-package="org.apache.camel.spring.produce"/>
+
+ <camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
+ </camelContext>
+
+</beans>
+ <!-- END SNIPPET: example -->
Propchange:
activemq/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/produce/ProduceTest-context.xml
------------------------------------------------------------------------------
svn:eol-style = native