Hi Nice refactor
Just a few suggestion for polishing - the logger in the abstract class is using the other class name - possible add a bit javadoc to the abstract class - a method has xxxbody where body is with a little b, and not Body. On Mon, Oct 24, 2011 at 4:51 PM, <cschnei...@apache.org> wrote: > 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 > > > -- Claus Ibsen ----------------- FuseSource Email: cib...@fusesource.com Web: http://fusesource.com Twitter: davsclaus, fusenews Blog: http://davsclaus.blogspot.com/ Author of Camel in Action: http://www.manning.com/ibsen/