Author: cschneider Date: Mon Oct 24 14:51:12 2011 New Revision: 1188162 URL: http://svn.apache.org/viewvc?rev=1188162&view=rev Log: CAMEL-4565 Code and tests for sending simple objects from a dynamic proxy
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java (with props) camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java (with props) camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java Mon Oct 24 14:51:12 2011 @@ -0,0 +1,217 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.bean; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelExchangeException; +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePattern; +import org.apache.camel.InvalidPayloadException; +import org.apache.camel.Producer; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.impl.DefaultExchange; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractCamelInvocationHandler implements InvocationHandler { + + private static final transient Logger LOG = LoggerFactory.getLogger(CamelInvocationHandler.class); + private static ExecutorService executorService; + protected final Endpoint endpoint; + protected final Producer producer; + + public AbstractCamelInvocationHandler(Endpoint endpoint, Producer producer) { + super(); + this.endpoint = endpoint; + this.producer = producer; + } + + private static Object getBody(Exchange exchange, Class<?> type) throws InvalidPayloadException { + // get the body from the Exchange from either OUT or IN + if (exchange.hasOut()) { + if (exchange.getOut().getBody() != null) { + return exchange.getOut().getMandatoryBody(type); + } else { + return null; + } + } else { + if (exchange.getIn().getBody() != null) { + return exchange.getIn().getMandatoryBody(type); + } else { + return null; + } + } + } + + protected Object invokeWithbody(final Method method, Object body, final ExchangePattern pattern) throws InterruptedException, Throwable { + final Exchange exchange = new DefaultExchange(endpoint, pattern); + exchange.getIn().setBody(body); + + // is the return type a future + final boolean isFuture = method.getReturnType() == Future.class; + + // create task to execute the proxy and gather the reply + FutureTask<Object> task = new FutureTask<Object>(new Callable<Object>() { + public Object call() throws Exception { + // process the exchange + LOG.trace("Proxied method call {} invoking producer: {}", method.getName(), producer); + producer.process(exchange); + + Object answer = afterInvoke(method, exchange, pattern, isFuture); + LOG.trace("Proxied method call {} returning: {}", method.getName(), answer); + return answer; + } + }); + + if (isFuture) { + // submit task and return future + if (LOG.isTraceEnabled()) { + LOG.trace("Submitting task for exchange id {}", exchange.getExchangeId()); + } + getExecutorService(exchange.getContext()).submit(task); + return task; + } else { + // execute task now + try { + task.run(); + return task.get(); + } catch (ExecutionException e) { + // we don't want the wrapped exception from JDK + throw e.getCause(); + } + } + } + + protected Object afterInvoke(Method method, Exchange exchange, ExchangePattern pattern, boolean isFuture) throws Exception { + // check if we had an exception + Throwable cause = exchange.getException(); + if (cause != null) { + Throwable found = findSuitableException(cause, method); + if (found != null) { + if (found instanceof Exception) { + throw (Exception)found; + } else { + // wrap as exception + throw new CamelExchangeException("Error processing exchange", exchange, cause); + } + } + // special for runtime camel exceptions as they can be nested + if (cause instanceof RuntimeCamelException) { + // if the inner cause is a runtime exception we can throw it + // directly + if (cause.getCause() instanceof RuntimeException) { + throw (RuntimeException)((RuntimeCamelException)cause).getCause(); + } + throw (RuntimeCamelException)cause; + } + // okay just throw the exception as is + if (cause instanceof Exception) { + throw (Exception)cause; + } else { + // wrap as exception + throw new CamelExchangeException("Error processing exchange", exchange, cause); + } + } + + Class<?> to = isFuture ? getGenericType(exchange.getContext(), method.getGenericReturnType()) : method.getReturnType(); + + // do not return a reply if the method is VOID + if (to == Void.TYPE) { + return null; + } + + return getBody(exchange, to); + } + + protected static Class<?> getGenericType(CamelContext context, Type type) throws ClassNotFoundException { + if (type == null) { + // fallback and use object + return Object.class; + } + + // unfortunately java dont provide a nice api for getting the generic + // type of the return type + // due type erasure, so we have to gather it based on a String + // representation + String name = ObjectHelper.between(type.toString(), "<", ">"); + if (name != null) { + if (name.contains("<")) { + // we only need the outer type + name = ObjectHelper.before(name, "<"); + } + return context.getClassResolver().resolveMandatoryClass(name); + } else { + // fallback and use object + return Object.class; + } + } + + protected static synchronized ExecutorService getExecutorService(CamelContext context) { + // CamelContext will shutdown thread pool when it shutdown so we can + // lazy create it on demand + // but in case of hot-deploy or the likes we need to be able to + // re-create it (its a shared static instance) + if (executorService == null || executorService.isTerminated() || executorService.isShutdown()) { + // try to lookup a pool first based on id/profile + executorService = context.getExecutorServiceStrategy().lookup(CamelInvocationHandler.class, "CamelInvocationHandler", "CamelInvocationHandler"); + if (executorService == null) { + executorService = context.getExecutorServiceStrategy().newDefaultThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler"); + } + } + return executorService; + } + + /** + * Tries to find the best suited exception to throw. + * <p/> + * It looks in the exception hierarchy from the caused exception and matches + * this against the declared exceptions being thrown on the method. + * + * @param cause the caused exception + * @param method the method + * @return the exception to throw, or <tt>null</tt> if not possible to find + * a suitable exception + */ + protected Throwable findSuitableException(Throwable cause, Method method) { + if (method.getExceptionTypes() == null || method.getExceptionTypes().length == 0) { + return null; + } + + // see if there is any exception which matches the declared exception on + // the method + for (Class<?> type : method.getExceptionTypes()) { + Object fault = ObjectHelper.getException(type, cause); + if (fault != null) { + return Throwable.class.cast(fault); + } + } + + return null; + } + +} Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java?rev=1188162&r1=1188161&r2=1188162&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java Mon Oct 24 14:51:12 2011 @@ -18,213 +18,30 @@ package org.apache.camel.component.bean; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import org.apache.camel.CamelContext; -import org.apache.camel.CamelExchangeException; import org.apache.camel.Endpoint; -import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; -import org.apache.camel.InvalidPayloadException; import org.apache.camel.Producer; -import org.apache.camel.RuntimeCamelException; -import org.apache.camel.util.ObjectHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * An {@link java.lang.reflect.InvocationHandler} which invokes a - * message exchange on a camel {@link Endpoint} - * - * @version + * An {@link java.lang.reflect.InvocationHandler} which invokes a message + * exchange on a camel {@link Endpoint} + * + * @version */ -public class CamelInvocationHandler implements InvocationHandler { - private static final transient Logger LOG = LoggerFactory.getLogger(CamelInvocationHandler.class); - - // use a static thread pool to not create a new thread pool for each invocation - private static ExecutorService executorService; - - private final Endpoint endpoint; - private final Producer producer; +public class CamelInvocationHandler extends AbstractCamelInvocationHandler implements InvocationHandler { private final MethodInfoCache methodInfoCache; public CamelInvocationHandler(Endpoint endpoint, Producer producer, MethodInfoCache methodInfoCache) { - this.endpoint = endpoint; - this.producer = producer; + super(endpoint, producer); this.methodInfoCache = methodInfoCache; } public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { BeanInvocation invocation = new BeanInvocation(method, args); MethodInfo methodInfo = methodInfoCache.getMethodInfo(method); - final ExchangePattern pattern = methodInfo != null ? methodInfo.getPattern() : ExchangePattern.InOut; - final Exchange exchange = endpoint.createExchange(pattern); - exchange.getIn().setBody(invocation); - - // is the return type a future - final boolean isFuture = method.getReturnType() == Future.class; - - // create task to execute the proxy and gather the reply - FutureTask task = new FutureTask<Object>(new Callable<Object>() { - public Object call() throws Exception { - // process the exchange - LOG.trace("Proxied method call {} invoking producer: {}", method.getName(), producer); - producer.process(exchange); - - Object answer = afterInvoke(method, exchange, pattern, isFuture); - LOG.trace("Proxied method call {} returning: {}", method.getName(), answer); - return answer; - } - }); - - if (isFuture) { - // submit task and return future - if (LOG.isTraceEnabled()) { - LOG.trace("Submitting task for exchange id {}", exchange.getExchangeId()); - } - getExecutorService(exchange.getContext()).submit(task); - return task; - } else { - // execute task now - try { - task.run(); - return task.get(); - } catch (ExecutionException e) { - // we don't want the wrapped exception from JDK - throw e.getCause(); - } - } - } - - protected Object afterInvoke(Method method, Exchange exchange, ExchangePattern pattern, boolean isFuture) throws Exception { - // check if we had an exception - Throwable cause = exchange.getException(); - if (cause != null) { - Throwable found = findSuitableException(cause, method); - if (found != null) { - if (found instanceof Exception) { - throw (Exception) found; - } else { - // wrap as exception - throw new CamelExchangeException("Error processing exchange", exchange, cause); - } - } - // special for runtime camel exceptions as they can be nested - if (cause instanceof RuntimeCamelException) { - // if the inner cause is a runtime exception we can throw it directly - if (cause.getCause() instanceof RuntimeException) { - throw (RuntimeException) ((RuntimeCamelException) cause).getCause(); - } - throw (RuntimeCamelException) cause; - } - // okay just throw the exception as is - if (cause instanceof Exception) { - throw (Exception) cause; - } else { - // wrap as exception - throw new CamelExchangeException("Error processing exchange", exchange, cause); - } - } - - // do not return a reply if the method is VOID - Class<?> to = method.getReturnType(); - if (to == Void.TYPE) { - return null; - } - - // use type converter so we can convert output in the desired type defined by the method - // and let it be mandatory so we know wont return null if we cant convert it to the defined type - Object answer; - if (!isFuture) { - answer = getBody(exchange, to); - } else { - // if its a Future then we need to extract the class from the future type so we know - // which class to return the result as - Class<?> returnTo = getGenericType(exchange.getContext(), method.getGenericReturnType()); - answer = getBody(exchange, returnTo); - } - - return answer; - } - - private static Object getBody(Exchange exchange, Class<?> type) throws InvalidPayloadException { - // get the body from the Exchange from either OUT or IN - if (exchange.hasOut()) { - if (exchange.getOut().getBody() != null) { - return exchange.getOut().getMandatoryBody(type); - } else { - return null; - } - } else { - if (exchange.getIn().getBody() != null) { - return exchange.getIn().getMandatoryBody(type); - } else { - return null; - } - } - } - - protected static Class getGenericType(CamelContext context, Type type) throws ClassNotFoundException { - if (type == null) { - // fallback and use object - return Object.class; - } - - // unfortunately java dont provide a nice api for getting the generic type of the return type - // due type erasure, so we have to gather it based on a String representation - String name = ObjectHelper.between(type.toString(), "<", ">"); - if (name != null) { - if (name.contains("<")) { - // we only need the outer type - name = ObjectHelper.before(name, "<"); - } - return context.getClassResolver().resolveMandatoryClass(name); - } else { - // fallback and use object - return Object.class; - } - } - - /** - * Tries to find the best suited exception to throw. - * <p/> - * It looks in the exception hierarchy from the caused exception and matches this against the declared exceptions - * being thrown on the method. - * - * @param cause the caused exception - * @param method the method - * @return the exception to throw, or <tt>null</tt> if not possible to find a suitable exception - */ - protected Throwable findSuitableException(Throwable cause, Method method) { - if (method.getExceptionTypes() == null || method.getExceptionTypes().length == 0) { - return null; - } - - // see if there is any exception which matches the declared exception on the method - for (Class<?> type : method.getExceptionTypes()) { - Object fault = ObjectHelper.getException(type, cause); - if (fault != null) { - return Throwable.class.cast(fault); - } - } - - return null; - } - - protected static synchronized ExecutorService getExecutorService(CamelContext context) { - // CamelContext will shutdown thread pool when it shutdown so we can lazy create it on demand - // but in case of hot-deploy or the likes we need to be able to re-create it (its a shared static instance) - if (executorService == null || executorService.isTerminated() || executorService.isShutdown()) { - executorService = context.getExecutorServiceManager().newDefaultThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler"); - } - return executorService; + return invokeWithbody(method, invocation, pattern); } } - Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java Mon Oct 24 14:51:12 2011 @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.bean; + +import java.lang.reflect.Method; + +import org.apache.camel.Endpoint; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Producer; +import org.apache.camel.RuntimeCamelException; + +/** + * Special InvocationHandler for methods that have only one parameter. This + * parameter is directly sent to as the body of the message. The idea is to use + * that as a very open message format especially when combined with e.g. JAXB + * serialization. + */ +public class PojoMessageInvocationHandler extends AbstractCamelInvocationHandler { + public PojoMessageInvocationHandler(Endpoint endpoint, Producer producer) { + super(endpoint, producer); + } + + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + int argsLength = (args == null) ? 0 : args.length; + if (argsLength != 1) { + throw new RuntimeCamelException(String.format("Error creating proxy for %s.%s Number of arguments must be 1 but is %d", + method.getDeclaringClass().getName(), + method.getName(), argsLength)); + } + final ExchangePattern pattern = method.getReturnType() != Void.TYPE ? ExchangePattern.InOut : ExchangePattern.InOnly; + return invokeWithbody(method, args[0], pattern); + } + +} Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java Mon Oct 24 14:51:12 2011 @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.bean; + +import java.lang.reflect.Proxy; + +import org.apache.camel.Endpoint; +import org.apache.camel.Producer; +import org.apache.camel.util.ServiceHelper; + +/** + * Create a dynamic proxy for a given interface and endpoint that sends the parameter object to the endpoint and optionally + * receives a reply. Unlike the ProxyHelper this works only with methods that have only one parameter. + */ +public final class PojoProxyHelper { + private PojoProxyHelper() { + } + + @SuppressWarnings("unchecked") + public static <T> T createProxy(Endpoint endpoint, Class<?>... interfaceClasses) throws Exception { + Producer producer = endpoint.createProducer(); + // ensure the producer is started + ServiceHelper.startService(producer); + return (T)Proxy.newProxyInstance(ProxyHelper.getClassLoader(interfaceClasses), interfaceClasses.clone(), new PojoMessageInvocationHandler(endpoint, producer)); + } +} Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoProxyHelper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java Mon Oct 24 14:51:12 2011 @@ -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.component.bean.pojomessage; + +public class Person { + String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} \ No newline at end of file Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/Person.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java Mon Oct 24 14:51:12 2011 @@ -0,0 +1,73 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.bean.pojomessage; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Endpoint; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.bean.PojoProxyHelper; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.Test; + +public class PojoProxyHelperOneWayTest extends ContextTestSupport { + + PersonReceiver receiver = new PersonReceiver(); + + @Test + public void testOneWay() throws Exception { + Endpoint personEndpoint = context.getEndpoint("direct:person"); + MockEndpoint result = (MockEndpoint)context.getEndpoint("mock:result"); + Person person = new Person("Chris"); + result.expectedBodiesReceived(person); + PersonHandler sender = PojoProxyHelper.createProxy(personEndpoint, PersonHandler.class); + + sender.onPerson(person); + + result.assertIsSatisfied(); + Assert.assertEquals(1, receiver.receivedPersons.size()); + Assert.assertEquals(person.getName(), receiver.receivedPersons.get(0).getName()); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + + @Override + public void configure() throws Exception { + from("direct:person").to("mock:result").bean(receiver); + } + }; + } + + public final class PersonReceiver implements PersonHandler { + public List<Person> receivedPersons = new ArrayList<Person>(); + + @Override + public void onPerson(Person person) { + receivedPersons.add(person); + } + } + + public interface PersonHandler { + void onPerson(Person person); + } +} Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperOneWayTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java?rev=1188162&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java Mon Oct 24 14:51:12 2011 @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.bean.pojomessage; + +import junit.framework.Assert; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Endpoint; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.bean.PojoProxyHelper; +import org.junit.Test; + +public class PojoProxyHelperRequestReplyTest extends ContextTestSupport { + + PersonReceiver receiver = new PersonReceiver(); + + @Test + public void testRequestReply() throws Exception { + Endpoint personEndpoint = context.getEndpoint("direct:person"); + Person person = new Person("Chris"); + PersonHandler sender = PojoProxyHelper.createProxy(personEndpoint, PersonHandler.class); + + Person resultPerson = sender.onPerson(person); + Assert.assertEquals(person.getName() + "1", resultPerson.getName()); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("direct:person").bean(receiver); + } + }; + } + + public final class PersonReceiver implements PersonHandler { + @Override + public Person onPerson(Person person) { + return new Person(person.getName() + "1"); + } + } + + public interface PersonHandler { + Person onPerson(Person person); + } + +} Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/pojomessage/PojoProxyHelperRequestReplyTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain