/**
* 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 java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
import org.apache.camel.BeanInject;
import org.apache.camel.CamelContext;
import org.apache.camel.Consume;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.EndpointInject;
import org.apache.camel.Exchange;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.NoSuchBeanException;
import org.apache.camel.PollingConsumer;
import org.apache.camel.Produce;
import org.apache.camel.Producer;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.PropertyInject;
import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.component.properties.PropertiesComponent;
import org.apache.camel.support.SynchronizationAdapter;
import org.apache.camel.util.ObjectHelper;
/**
* @version
*/
public class CamelPostProcessorHelperTest extends ContextTestSupport {
private MySynchronization mySynchronization = new MySynchronization();
private Properties myProp = new Properties();
@Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry jndi = super.createRegistry();
jndi.bind("myProp", myProp);
jndi.bind("foo", new FooBar());
return jndi;
}
@Override
protected CamelContext createCamelContext() throws Exception {
CamelContext context = super.createCamelContext();
PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class);
pc.setLocation("ref:myProp");
return context;
}
public void testConstructor() {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper();
assertNull(helper.getCamelContext());
helper.setCamelContext(context);
assertNotNull(helper.getCamelContext());
}
public void testConstructorCamelContext() {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
assertNotNull(helper.getCamelContext());
}
public void testMatchContext() {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
assertTrue(helper.matchContext(context.getName()));
assertFalse(helper.matchContext("foo"));
}
public void testConsume() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyConsumeBean my = new MyConsumeBean();
Method method = my.getClass().getMethod("consumeSomething", String.class);
helper.consumerInjection(method, my, "foo");
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
template.sendBody("seda:foo", "Hello World");
assertMockEndpointsSatisfied();
}
public void testConsumePrivate() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyPrivateConsumeBean my = new MyPrivateConsumeBean();
Method method = my.getClass().getDeclaredMethod("consumeSomethingPrivate", String.class);
try {
helper.consumerInjection(method, my, "foo");
fail("Should have thrown exception");
} catch (RuntimeCamelException e) {
IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
assertTrue(iae.getMessage().startsWith("The method private void"));
assertTrue(iae.getMessage().endsWith("(for example the method must be public)"));
}
}
public void testConsumeSynchronization() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyConsumeAndSynchronizationBean my = new MyConsumeAndSynchronizationBean();
Method method = my.getClass().getMethod("consumeSomething", String.class, Exchange.class);
helper.consumerInjection(method, my, "foo");
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
template.sendBody("seda:foo", "Hello World");
assertMockEndpointsSatisfied();
// give UoW a bit of time
Thread.sleep(500);
assertTrue("Should have invoked onDone", mySynchronization.isOnDone());
}
public void testProduceSynchronization() throws Exception {
MyProduceAndSynchronizationBean my = new MyProduceAndSynchronizationBean();
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
Producer producer = helper.createInjectionProducer(context.getEndpoint("mock:result"), my, "foo");
my.setProducer(producer);
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
my.produceSomething("Hello World");
assertMockEndpointsSatisfied();
// give UoW a bit of time
Thread.sleep(500);
assertTrue("Should have invoked onDone", mySynchronization.isOnDone());
}
public void testEndpointInjectProducerTemplate() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectBeanProducerTemplate bean = new MyEndpointInjectBeanProducerTemplate();
Method method = bean.getClass().getMethod("setProducer", ProducerTemplate.class);
EndpointInject endpointInject = method.getAnnotation(EndpointInject.class);
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> type : parameterTypes) {
String propertyName = ObjectHelper.getPropertyName(method);
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
ObjectHelper.invokeMethod(method, bean, value);
}
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
assertNotNull(bean.getProducer());
bean.send("Hello World");
assertMockEndpointsSatisfied();
}
public void testEndpointInjectProducer() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointBeanProducer bean = new MyEndpointBeanProducer();
Method method = bean.getClass().getMethod("setProducer", Producer.class);
EndpointInject endpointInject = method.getAnnotation(EndpointInject.class);
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> type : parameterTypes) {
String propertyName = ObjectHelper.getPropertyName(method);
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
ObjectHelper.invokeMethod(method, bean, value);
}
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
assertNotNull(bean.getProducer());
Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody("Hello World");
bean.send(exchange);
assertMockEndpointsSatisfied();
}
public void testEndpointInjectPollingConsumer() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointBeanPollingConsumer bean = new MyEndpointBeanPollingConsumer();
Method method = bean.getClass().getMethod("setConsumer", PollingConsumer.class);
EndpointInject endpointInject = method.getAnnotation(EndpointInject.class);
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> type : parameterTypes) {
String propertyName = ObjectHelper.getPropertyName(method);
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
ObjectHelper.invokeMethod(method, bean, value);
}
template.sendBody("seda:foo", "Hello World");
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
assertNotNull(bean.getConsumer());
Exchange exchange = bean.consume();
template.send("mock:result", exchange);
assertMockEndpointsSatisfied();
}
public void testEndpointInjectProducerTemplateField() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectProducerTemplate bean = new MyEndpointInjectProducerTemplate();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
field.set(bean, value);
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody("Hello World");
bean.send(exchange);
assertMockEndpointsSatisfied();
}
public void testEndpointInjectFluentProducerTemplateField() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectFluentProducerTemplate bean = new MyEndpointInjectFluentProducerTemplate();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
field.set(bean, value);
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody("Hello World");
bean.send(exchange);
assertMockEndpointsSatisfied();
}
public void testEndpointInjectProducerTemplateFieldNoDefaultEndpoint() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectProducerTemplateNoDefaultEndpoint bean = new MyEndpointInjectProducerTemplateNoDefaultEndpoint();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
Object value = helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
field.set(bean, value);
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("Hello World");
Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody("Hello World");
bean.send(exchange);
assertMockEndpointsSatisfied();
}
public void testEndpointInjectProducerTemplateFieldNameUnknown() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectProducerTemplateNameUnknown bean = new MyEndpointInjectProducerTemplateNameUnknown();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
try {
helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
fail("Should throw exception");
} catch (NoSuchBeanException e) {
assertEquals("No bean could be found in the registry for: unknown of type: org.apache.camel.Endpoint", e.getMessage());
}
}
public void testEndpointInjectProducerTemplateFieldUrlUnknown() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointInjectProducerTemplateUrlUnknown bean = new MyEndpointInjectProducerTemplateUrlUnknown();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
try {
helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
fail("Should throw exception");
} catch (ResolveEndpointFailedException e) {
assertEquals("Failed to resolve endpoint: xxx://foo due to: No component found with scheme: xxx", e.getMessage());
}
}
public void testEndpointInjectBothUriAndRef() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyEndpointBothUriAndRef bean = new MyEndpointBothUriAndRef();
Field field = bean.getClass().getField("producer");
EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
Class<?> type = field.getType();
String propertyName = "producer";
try {
helper.getInjectionValue(type, endpointInject.uri(), endpointInject.ref(), endpointInject.property(), propertyName, bean, "foo");
fail("Should throw exception");
} catch (IllegalArgumentException e) {
assertEquals("Both uri and name is provided, only either one is allowed: uri=seda:foo, ref=myEndpoint", e.getMessage());
}
}
public void testPropertyFieldInject() throws Exception {
myProp.put("myTimeout", "2000");
myProp.put("myApp", "Camel");
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyPropertyFieldBean bean = new MyPropertyFieldBean();
Field field = bean.getClass().getField("timeout");
PropertyInject propertyInject = field.getAnnotation(PropertyInject.class);
Class<?> type = field.getType();
Object value = helper.getInjectionPropertyValue(type, propertyInject.value(), "", "timeout", bean, "foo");
assertEquals(Integer.valueOf("2000"), Integer.valueOf("" + value));
field = bean.getClass().getField("greeting");
propertyInject = field.getAnnotation(PropertyInject.class);
type = field.getType();
value = helper.getInjectionPropertyValue(type, propertyInject.value(), "", "greeting", bean, "foo");
assertEquals("Hello Camel", value);
}
public void testPropertyFieldDefaultValueInject() throws Exception {
myProp.put("myApp", "Camel");
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyPropertyFieldBean bean = new MyPropertyFieldBean();
Field field = bean.getClass().getField("timeout");
PropertyInject propertyInject = field.getAnnotation(PropertyInject.class);
Class<?> type = field.getType();
Object value = helper.getInjectionPropertyValue(type, propertyInject.value(), "5000", "timeout", bean, "foo");
assertEquals(Integer.valueOf("5000"), Integer.valueOf("" + value));
field = bean.getClass().getField("greeting");
propertyInject = field.getAnnotation(PropertyInject.class);
type = field.getType();
value = helper.getInjectionPropertyValue(type, propertyInject.value(), "", "greeting", bean, "foo");
assertEquals("Hello Camel", value);
}
public void testPropertyMethodInject() throws Exception {
myProp.put("myTimeout", "2000");
myProp.put("myApp", "Camel");
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyPropertyMethodBean bean = new MyPropertyMethodBean();
Method method = bean.getClass().getMethod("setTimeout", int.class);
PropertyInject propertyInject = method.getAnnotation(PropertyInject.class);
Class<?> type = method.getParameterTypes()[0];
Object value = helper.getInjectionPropertyValue(type, propertyInject.value(), "", "timeout", bean, "foo");
assertEquals(Integer.valueOf("2000"), Integer.valueOf("" + value));
method = bean.getClass().getMethod("setGreeting", String.class);
propertyInject = method.getAnnotation(PropertyInject.class);
type = method.getParameterTypes()[0];
value = helper.getInjectionPropertyValue(type, propertyInject.value(), "", "greeting", bean, "foo");
assertEquals("Hello Camel", value);
}
public void testBeanInject() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyBeanInjectBean bean = new MyBeanInjectBean();
Field field = bean.getClass().getField("foo");
BeanInject beanInject = field.getAnnotation(BeanInject.class);
Class<?> type = field.getType();
Object value = helper.getInjectionBeanValue(type, beanInject.value());
field.set(bean, value);
String out = bean.doSomething("World");
assertEquals("Hello World", out);
}
public void testBeanInjectNotFound() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyBeanInjectBean bean = new MyBeanInjectBean();
Field field = bean.getClass().getField("foo");
Class<?> type = field.getType();
try {
helper.getInjectionBeanValue(type, "bar");
fail("Should have thrown exception");
} catch (NoSuchBeanException e) {
assertEquals("No bean could be found in the registry for: bar of type: org.apache.camel.impl.FooBar", e.getMessage());
assertEquals("bar", e.getName());
}
}
public void testBeanInjectByType() throws Exception {
CamelPostProcessorHelper helper = new CamelPostProcessorHelper(context);
MyBeanInjectByTypeBean bean = new MyBeanInjectByTypeBean();
Field field = bean.getClass().getField("foo");
BeanInject beanInject = field.getAnnotation(BeanInject.class);
Class<?> type = field.getType();
Object value = helper.getInjectionBeanValue(type, beanInject.value());
field.set(bean, value);
String out = bean.doSomething("Camel");
assertEquals("Hello Camel", out);
}
public class MyConsumeBean {
@Consume(uri = "seda:foo")
public void consumeSomething(String body) {
assertEquals("Hello World", body);
template.sendBody("mock:result", body);
}
}
public class MyConsumeAndSynchronizationBean {
@Consume(uri = "seda:foo")
public void consumeSomething(String body, Exchange exchange) {
exchange.addOnCompletion(mySynchronization);
assertEquals("Hello World", body);
template.sendBody("mock:result", body);
}
}
public class MyProduceAndSynchronizationBean {
@Produce(uri = "mock:result")
Producer producer;
public void produceSomething(String body) throws Exception {
assertEquals("Hello World", body);
Exchange exchange = producer.getEndpoint().createExchange();
exchange.addOnCompletion(mySynchronization);
exchange.getIn().setBody(body);
producer.process(exchange);
}
public void setProducer(Producer producer) {
this.producer = producer;
}
}
private static class MySynchronization extends SynchronizationAdapter {
private boolean onDone;
@Override
public void onDone(Exchange exchange) {
onDone = true;
}
public boolean isOnDone() {
return onDone;
}
}
public class MyEndpointInjectBeanProducerTemplate {
private ProducerTemplate producer;
@EndpointInject(uri = "mock:result")
public void setProducer(ProducerTemplate producer) {
this.producer = producer;
}
public ProducerTemplate getProducer() {
return producer;
}
public void send(String message) {
producer.sendBody(message);
}
}
public class MyEndpointBeanProducer {
private Producer producer;
@EndpointInject(uri = "mock:result")
public void setProducer(Producer producer) {
this.producer = producer;
}
public Producer getProducer() {
return producer;
}
public void send(Exchange exchange) throws Exception {
producer.process(exchange);
}
}
public class MyEndpointBeanPollingConsumer {
private PollingConsumer consumer;
@EndpointInject(uri = "seda:foo")
public void setConsumer(PollingConsumer consumer) {
this.consumer = consumer;
}
public PollingConsumer getConsumer() {
return consumer;
}
public Exchange consume() throws Exception {
return consumer.receive(1000);
}
}
public class MyEndpointInjectProducerTemplate {
@EndpointInject(uri = "mock:result")
public ProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.send(exchange);
}
}
public class MyEndpointInjectFluentProducerTemplate {
@EndpointInject(uri = "mock:result")
public FluentProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.withExchange(exchange).send();
}
}
public class MyEndpointInjectProducerTemplateNoDefaultEndpoint {
@EndpointInject()
public ProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.send("mock:result", exchange);
}
}
public class MyEndpointInjectProducerTemplateNameUnknown {
@EndpointInject(ref = "unknown")
public ProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.send(exchange);
}
}
public class MyEndpointInjectProducerTemplateUrlUnknown {
@EndpointInject(uri = "xxx:foo")
public ProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.send(exchange);
}
}
public class MyEndpointBothUriAndRef {
@EndpointInject(uri = "seda:foo", ref = "myEndpoint")
public ProducerTemplate producer;
public void send(Exchange exchange) throws Exception {
producer.send(exchange);
}
}
public class MyPrivateConsumeBean {
@Consume(uri = "seda:foo")
private void consumeSomethingPrivate(String body) {
assertEquals("Hello World", body);
template.sendBody("mock:result", body);
}
}
public class MyPropertyFieldBean {
@PropertyInject("myTimeout")
public int timeout;
@PropertyInject("Hello {{myApp}}")
public String greeting;
public String doSomething(String body) {
return greeting + " " + body + " with timeout=" + timeout;
}
}
public class MyPropertyFieldDefaultValueBean {
@PropertyInject(value = "myTimeout", defaultValue = "5000")
public int timeout;
@PropertyInject("Hello {{myApp}}")
public String greeting;
public String doSomething(String body) {
return greeting + " " + body + " with timeout=" + timeout;
}
}
public class MyPropertyMethodBean {
private int timeout;
private String greeting;
public String doSomething(String body) {
return greeting + " " + body + " with timeout=" + timeout;
}
public int getTimeout() {
return timeout;
}
@PropertyInject("myTimeout")
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getGreeting() {
return greeting;
}
@PropertyInject("Hello {{myApp}}")
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
public class MyBeanInjectBean {
@BeanInject("foo")
public FooBar foo;
public String doSomething(String body) {
return foo.hello(body);
}
}
public class MyBeanInjectByTypeBean {
@BeanInject
public FooBar foo;
public String doSomething(String body) {
return foo.hello(body);
}
}
}