You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2013/09/10 17:16:20 UTC

[1/6] git commit: CAMEL-6724: RegistryBean should avoid synchronization in getBean

Updated Branches:
  refs/heads/camel-2.12.x e166ab638 -> 7002c750d
  refs/heads/master 6a71168ce -> 33e4d7e47


CAMEL-6724: RegistryBean should avoid synchronization in getBean


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f25ee35c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f25ee35c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f25ee35c

Branch: refs/heads/master
Commit: f25ee35cb86ba42d8bc965d5234324dddaf5f59a
Parents: 6a71168
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:13:20 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:13:20 2013 +0200

----------------------------------------------------------------------
 .../apache/camel/component/bean/BeanHolder.java | 24 ++++++++
 .../camel/component/bean/BeanProcessor.java     |  7 ++-
 .../component/bean/ConstantBeanHolder.java      |  4 ++
 .../component/bean/ConstantTypeBeanHolder.java  |  4 ++
 .../camel/component/bean/RegistryBean.java      | 61 +++++++++++++-------
 5 files changed, 78 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f25ee35c/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
index dc52026..7f26df3 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
@@ -26,9 +26,33 @@ import org.apache.camel.Processor;
  */
 public interface BeanHolder {
 
+    /**
+     * Gets the bean.
+     *
+     * @throws NoSuchBeanException is thrown if the bean cannot be found.
+     */
     Object getBean() throws NoSuchBeanException;
 
+    /**
+     * Gets a {@link Processor} for this bean, if supported.
+     *
+     * @return the {@link Processor}, or <tt>null</tt> if not supported.
+     */
     Processor getProcessor();
 
+    /**
+     * Gets bean info for the bean.
+     */
     BeanInfo getBeanInfo();
+
+    /**
+     * Gets bean info for the given bean.
+     * <p/>
+     * This implementation allows a thread safe usage for {@link BeanHolder} implementations
+     * such as the {@link RegistryBean}.
+     *
+     * @param bean the bean
+     * @return <tt>null</tt> if not supported, then use {@link #getBeanInfo()} instead.
+     */
+    BeanInfo getBeanInfo(Object bean);
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f25ee35c/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
index 4534173..dc91566 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
@@ -75,7 +75,12 @@ public class BeanProcessor extends ServiceSupport implements AsyncProcessor {
         BeanInfo beanInfo;
         try {
             bean = beanHolder.getBean();
-            beanInfo = beanHolder.getBeanInfo();
+            // get bean info for this bean instance (to avoid thread issue)
+            beanInfo = beanHolder.getBeanInfo(bean);
+            if (beanInfo == null) {
+                // fallback and use old way
+                beanInfo = beanHolder.getBeanInfo();
+            }
         } catch (Throwable e) {
             exchange.setException(e);
             callback.done(true);

http://git-wip-us.apache.org/repos/asf/camel/blob/f25ee35c/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
index ddaa966..2cac840 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
@@ -65,4 +65,8 @@ public class ConstantBeanHolder implements BeanHolder {
     public BeanInfo getBeanInfo() {
         return beanInfo;
     }
+
+    public BeanInfo getBeanInfo(Object bean) {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f25ee35c/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
index 9fcb44e..515272b 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
@@ -62,6 +62,10 @@ public class ConstantTypeBeanHolder implements BeanTypeHolder {
         return beanInfo;
     }
 
+    public BeanInfo getBeanInfo(Object bean) {
+        return null;
+    }
+
     public Class<?> getType() {
         return type;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/f25ee35c/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
index ef5ce88..0c6e774 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
@@ -21,7 +21,6 @@ import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.Processor;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.util.CamelContextHelper;
-import org.apache.camel.util.ObjectHelper;
 
 /**
  * An implementation of a {@link BeanHolder} which will look up a bean from the registry and act as a cache of its metadata
@@ -29,12 +28,13 @@ import org.apache.camel.util.ObjectHelper;
  * @version 
  */
 public class RegistryBean implements BeanHolder {
+    private final Object lock = new Object();
     private final CamelContext context;
     private final String name;
     private final Registry registry;
-    private Processor processor;
-    private BeanInfo beanInfo;
-    private Object bean;
+    private volatile Processor processor;
+    private volatile BeanInfo beanInfo;
+    private volatile Object bean;
     private ParameterMappingStrategy parameterMappingStrategy;
 
     public RegistryBean(CamelContext context, String name) {
@@ -55,34 +55,45 @@ public class RegistryBean implements BeanHolder {
     }
 
     public ConstantBeanHolder createCacheHolder() throws Exception {
-        return new ConstantBeanHolder(getBean(), getBeanInfo());
+        Object bean = getBean();
+        BeanInfo info = createBeanInfo(bean);
+        return new ConstantBeanHolder(bean, info);
     }
 
-    public synchronized Object getBean() throws NoSuchBeanException {
+    public Object getBean() throws NoSuchBeanException {
+        // must always lookup bean first
         Object value = lookupBean();
-        if (value == null) {
-            // maybe its a class
-            value = context.getClassResolver().resolveClass(name);
-            if (value == null) {
-                // no its not a class then we cannot find the bean
-                throw new NoSuchBeanException(name);
+
+        if (value != null) {
+            // could be a class then create an instance of it
+            if (value instanceof Class) {
+                // bean is a class so create an instance of it
+                value = context.getInjector().newInstance((Class<?>)value);
             }
+            bean = value;
+            return value;
         }
-        if (value != bean) {
-            if (!ObjectHelper.equal(ObjectHelper.type(bean), ObjectHelper.type(value))) {
-                beanInfo = null;
+
+        // okay bean is not in registry, so try to resolve if its a class name and create a shared instance
+        synchronized (lock) {
+            if (bean != null) {
+                return bean;
             }
-            bean = value;
-            processor = null;
 
+            // maybe its a class
+            bean = context.getClassResolver().resolveClass(name);
+            if (bean == null) {
+                // no its not a class then we cannot find the bean
+                throw new NoSuchBeanException(name);
+            }
             // could be a class then create an instance of it
             if (bean instanceof Class) {
                 // bean is a class so create an instance of it
                 bean = context.getInjector().newInstance((Class<?>)bean);
-                value = bean;
             }
         }
-        return value;
+
+        return bean;
     }
 
     public Processor getProcessor() {
@@ -94,11 +105,19 @@ public class RegistryBean implements BeanHolder {
 
     public BeanInfo getBeanInfo() {
         if (beanInfo == null && bean != null) {
-            this.beanInfo = createBeanInfo();
+            this.beanInfo = createBeanInfo(bean);
         }
         return beanInfo;
     }
 
+    public BeanInfo getBeanInfo(Object bean) {
+        if (this.bean == bean) {
+            return getBeanInfo();
+        } else {
+            return createBeanInfo(bean);
+        }
+    }
+
     public String getName() {
         return name;
     }
@@ -124,7 +143,7 @@ public class RegistryBean implements BeanHolder {
 
     // Implementation methods
     //-------------------------------------------------------------------------
-    protected BeanInfo createBeanInfo() {
+    protected BeanInfo createBeanInfo(Object bean) {
         return new BeanInfo(context, bean.getClass(), getParameterMappingStrategy());
     }
 


[4/6] git commit: CAMEL-6725: Added cache option to beanRef / in the DSL

Posted by da...@apache.org.
CAMEL-6725: Added cache option to beanRef / <bean> in the DSL


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cf3f1604
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cf3f1604
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cf3f1604

Branch: refs/heads/camel-2.12.x
Commit: cf3f1604168b2f855a9018ae3187b1cd1c311aba
Parents: 3870340
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:13:37 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:14:15 2013 +0200

----------------------------------------------------------------------
 .../org/apache/camel/model/BeanDefinition.java  | 30 +++++++++++++++--
 .../apache/camel/model/ProcessorDefinition.java | 35 ++++++++++++++++++++
 .../bean/BeanExplicitMethodAmbiguousTest.java   |  6 ++--
 3 files changed, 66 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cf3f1604/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
index 22bd468..0211bbc 100644
--- a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
@@ -48,6 +48,8 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
     private String method;
     @XmlAttribute
     private String beanType;
+    @XmlAttribute
+    private Boolean cache;
     @XmlTransient
     private Class<?> beanClass;
     @XmlTransient
@@ -130,6 +132,14 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
         this.beanClass = beanType;
     }
 
+    public Boolean getCache() {
+        return cache;
+    }
+
+    public void setCache(Boolean cache) {
+        this.cache = cache;
+    }
+
     // Fluent API
     //-------------------------------------------------------------------------
     /**
@@ -184,14 +194,30 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
         return this;
     }
 
+    /**
+     * Caches the bean lookup, to avoid lookup up bean on every usage.
+     *
+     * @return the builder
+     */
+    @Deprecated
+    public BeanDefinition cache() {
+        setCache(true);
+        return this;
+    }
+
     @Override
-    public Processor createProcessor(RouteContext routeContext) {
+    public Processor createProcessor(RouteContext routeContext) throws Exception {
         BeanProcessor answer;
         Class<?> clazz = bean != null ? bean.getClass() : null;
         BeanHolder beanHolder;
 
         if (ObjectHelper.isNotEmpty(ref)) {
-            beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
+            if (cache != null && cache) {
+                // cache the registry lookup which avoids repeat lookup in the registry
+                beanHolder = new RegistryBean(routeContext.getCamelContext(), ref).createCacheHolder();
+            } else {
+                beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
+            }
             // bean holder will check if the bean exists
             bean = beanHolder.getBean();
             answer = new BeanProcessor(beanHolder);

http://git-wip-us.apache.org/repos/asf/camel/blob/cf3f1604/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index 9998e51..7d5699c 100644
--- a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -2580,6 +2580,41 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
 
     /**
      * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
+     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
+     *
+     * @param ref  reference to a bean to lookup in the registry
+     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
+     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type beanRef(String ref, boolean cache) {
+        BeanDefinition answer = new BeanDefinition(ref);
+        answer.setCache(cache);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
+     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
+     *
+     * @param ref  reference to a bean to lookup in the registry
+     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
+     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
+     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type beanRef(String ref, String method, boolean cache) {
+        BeanDefinition answer = new BeanDefinition(ref, method);
+        answer.setCache(cache);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
      * Adds a processor which sets the body on the IN message
      *
      * @return a expression builder clause to set the body

http://git-wip-us.apache.org/repos/asf/camel/blob/cf3f1604/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
index 15c8778..ae0f9cf 100644
--- a/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
@@ -64,11 +64,11 @@ public class BeanExplicitMethodAmbiguousTest extends ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:hello").beanRef("dummy", "hello");
+                from("direct:hello").beanRef("dummy", "hello", true);
 
-                from("direct:bye").beanRef("dummy");
+                from("direct:bye").beanRef("dummy", true);
                 
-                from("direct:foo").beanRef("dummy", "bar");
+                from("direct:foo").beanRef("dummy", "bar", true);
             }
         };
     }


[3/6] git commit: CAMEL-6724: RegistryBean should avoid synchronization in getBean

Posted by da...@apache.org.
CAMEL-6724: RegistryBean should avoid synchronization in getBean


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3870340f
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3870340f
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3870340f

Branch: refs/heads/camel-2.12.x
Commit: 3870340f82ff09ccc2fa264bce15a3b87bf3f7e3
Parents: e166ab6
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:13:20 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:14:09 2013 +0200

----------------------------------------------------------------------
 .../apache/camel/component/bean/BeanHolder.java | 24 ++++++++
 .../camel/component/bean/BeanProcessor.java     |  7 ++-
 .../component/bean/ConstantBeanHolder.java      |  4 ++
 .../component/bean/ConstantTypeBeanHolder.java  |  4 ++
 .../camel/component/bean/RegistryBean.java      | 61 +++++++++++++-------
 5 files changed, 78 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/3870340f/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
index dc52026..7f26df3 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanHolder.java
@@ -26,9 +26,33 @@ import org.apache.camel.Processor;
  */
 public interface BeanHolder {
 
+    /**
+     * Gets the bean.
+     *
+     * @throws NoSuchBeanException is thrown if the bean cannot be found.
+     */
     Object getBean() throws NoSuchBeanException;
 
+    /**
+     * Gets a {@link Processor} for this bean, if supported.
+     *
+     * @return the {@link Processor}, or <tt>null</tt> if not supported.
+     */
     Processor getProcessor();
 
+    /**
+     * Gets bean info for the bean.
+     */
     BeanInfo getBeanInfo();
+
+    /**
+     * Gets bean info for the given bean.
+     * <p/>
+     * This implementation allows a thread safe usage for {@link BeanHolder} implementations
+     * such as the {@link RegistryBean}.
+     *
+     * @param bean the bean
+     * @return <tt>null</tt> if not supported, then use {@link #getBeanInfo()} instead.
+     */
+    BeanInfo getBeanInfo(Object bean);
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/3870340f/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
index 4534173..dc91566 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanProcessor.java
@@ -75,7 +75,12 @@ public class BeanProcessor extends ServiceSupport implements AsyncProcessor {
         BeanInfo beanInfo;
         try {
             bean = beanHolder.getBean();
-            beanInfo = beanHolder.getBeanInfo();
+            // get bean info for this bean instance (to avoid thread issue)
+            beanInfo = beanHolder.getBeanInfo(bean);
+            if (beanInfo == null) {
+                // fallback and use old way
+                beanInfo = beanHolder.getBeanInfo();
+            }
         } catch (Throwable e) {
             exchange.setException(e);
             callback.done(true);

http://git-wip-us.apache.org/repos/asf/camel/blob/3870340f/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
index ddaa966..2cac840 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantBeanHolder.java
@@ -65,4 +65,8 @@ public class ConstantBeanHolder implements BeanHolder {
     public BeanInfo getBeanInfo() {
         return beanInfo;
     }
+
+    public BeanInfo getBeanInfo(Object bean) {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/3870340f/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
index 9fcb44e..515272b 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ConstantTypeBeanHolder.java
@@ -62,6 +62,10 @@ public class ConstantTypeBeanHolder implements BeanTypeHolder {
         return beanInfo;
     }
 
+    public BeanInfo getBeanInfo(Object bean) {
+        return null;
+    }
+
     public Class<?> getType() {
         return type;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/3870340f/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
index ef5ce88..0c6e774 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/RegistryBean.java
@@ -21,7 +21,6 @@ import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.Processor;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.util.CamelContextHelper;
-import org.apache.camel.util.ObjectHelper;
 
 /**
  * An implementation of a {@link BeanHolder} which will look up a bean from the registry and act as a cache of its metadata
@@ -29,12 +28,13 @@ import org.apache.camel.util.ObjectHelper;
  * @version 
  */
 public class RegistryBean implements BeanHolder {
+    private final Object lock = new Object();
     private final CamelContext context;
     private final String name;
     private final Registry registry;
-    private Processor processor;
-    private BeanInfo beanInfo;
-    private Object bean;
+    private volatile Processor processor;
+    private volatile BeanInfo beanInfo;
+    private volatile Object bean;
     private ParameterMappingStrategy parameterMappingStrategy;
 
     public RegistryBean(CamelContext context, String name) {
@@ -55,34 +55,45 @@ public class RegistryBean implements BeanHolder {
     }
 
     public ConstantBeanHolder createCacheHolder() throws Exception {
-        return new ConstantBeanHolder(getBean(), getBeanInfo());
+        Object bean = getBean();
+        BeanInfo info = createBeanInfo(bean);
+        return new ConstantBeanHolder(bean, info);
     }
 
-    public synchronized Object getBean() throws NoSuchBeanException {
+    public Object getBean() throws NoSuchBeanException {
+        // must always lookup bean first
         Object value = lookupBean();
-        if (value == null) {
-            // maybe its a class
-            value = context.getClassResolver().resolveClass(name);
-            if (value == null) {
-                // no its not a class then we cannot find the bean
-                throw new NoSuchBeanException(name);
+
+        if (value != null) {
+            // could be a class then create an instance of it
+            if (value instanceof Class) {
+                // bean is a class so create an instance of it
+                value = context.getInjector().newInstance((Class<?>)value);
             }
+            bean = value;
+            return value;
         }
-        if (value != bean) {
-            if (!ObjectHelper.equal(ObjectHelper.type(bean), ObjectHelper.type(value))) {
-                beanInfo = null;
+
+        // okay bean is not in registry, so try to resolve if its a class name and create a shared instance
+        synchronized (lock) {
+            if (bean != null) {
+                return bean;
             }
-            bean = value;
-            processor = null;
 
+            // maybe its a class
+            bean = context.getClassResolver().resolveClass(name);
+            if (bean == null) {
+                // no its not a class then we cannot find the bean
+                throw new NoSuchBeanException(name);
+            }
             // could be a class then create an instance of it
             if (bean instanceof Class) {
                 // bean is a class so create an instance of it
                 bean = context.getInjector().newInstance((Class<?>)bean);
-                value = bean;
             }
         }
-        return value;
+
+        return bean;
     }
 
     public Processor getProcessor() {
@@ -94,11 +105,19 @@ public class RegistryBean implements BeanHolder {
 
     public BeanInfo getBeanInfo() {
         if (beanInfo == null && bean != null) {
-            this.beanInfo = createBeanInfo();
+            this.beanInfo = createBeanInfo(bean);
         }
         return beanInfo;
     }
 
+    public BeanInfo getBeanInfo(Object bean) {
+        if (this.bean == bean) {
+            return getBeanInfo();
+        } else {
+            return createBeanInfo(bean);
+        }
+    }
+
     public String getName() {
         return name;
     }
@@ -124,7 +143,7 @@ public class RegistryBean implements BeanHolder {
 
     // Implementation methods
     //-------------------------------------------------------------------------
-    protected BeanInfo createBeanInfo() {
+    protected BeanInfo createBeanInfo(Object bean) {
         return new BeanInfo(context, bean.getClass(), getParameterMappingStrategy());
     }
 


[5/6] git commit: CAMEL-6718: Marshal should leverage stream caching if enabled. Thanks to Franz Forsthofer for patch.

Posted by da...@apache.org.
CAMEL-6718: Marshal should leverage stream caching if enabled. Thanks to Franz Forsthofer for patch.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/33e4d7e4
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/33e4d7e4
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/33e4d7e4

Branch: refs/heads/master
Commit: 33e4d7e47cf1fc6b3f00af706faa74adaa23fac0
Parents: c3078ad
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:15:43 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:15:43 2013 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/camel/processor/MarshalProcessor.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/33e4d7e4/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
index c26d00a..efa2b8e 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
@@ -74,11 +74,11 @@ public class MarshalProcessor extends ServiceSupport implements AsyncProcessor,
         out.copyFrom(in);
 
         try {
-            dataFormat.marshal(exchange, body, os);
-
             if (cos != null) {
+                dataFormat.marshal(exchange, body, cos);
                 out.setBody(cos.newStreamCache());
             } else {
+                dataFormat.marshal(exchange, body, os);
                 byte[] data = os.toByteArray();
                 out.setBody(data);
             }


[2/6] git commit: CAMEL-6725: Added cache option to beanRef / in the DSL

Posted by da...@apache.org.
CAMEL-6725: Added cache option to beanRef / <bean> in the DSL


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/c3078ad7
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/c3078ad7
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/c3078ad7

Branch: refs/heads/master
Commit: c3078ad79d6fbd36427a3eaa4b3aafcc63914fd2
Parents: f25ee35
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:13:37 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:13:37 2013 +0200

----------------------------------------------------------------------
 .../org/apache/camel/model/BeanDefinition.java  | 30 +++++++++++++++--
 .../apache/camel/model/ProcessorDefinition.java | 35 ++++++++++++++++++++
 .../bean/BeanExplicitMethodAmbiguousTest.java   |  6 ++--
 3 files changed, 66 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/c3078ad7/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
index 22bd468..0211bbc 100644
--- a/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
@@ -48,6 +48,8 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
     private String method;
     @XmlAttribute
     private String beanType;
+    @XmlAttribute
+    private Boolean cache;
     @XmlTransient
     private Class<?> beanClass;
     @XmlTransient
@@ -130,6 +132,14 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
         this.beanClass = beanType;
     }
 
+    public Boolean getCache() {
+        return cache;
+    }
+
+    public void setCache(Boolean cache) {
+        this.cache = cache;
+    }
+
     // Fluent API
     //-------------------------------------------------------------------------
     /**
@@ -184,14 +194,30 @@ public class BeanDefinition extends NoOutputDefinition<BeanDefinition> {
         return this;
     }
 
+    /**
+     * Caches the bean lookup, to avoid lookup up bean on every usage.
+     *
+     * @return the builder
+     */
+    @Deprecated
+    public BeanDefinition cache() {
+        setCache(true);
+        return this;
+    }
+
     @Override
-    public Processor createProcessor(RouteContext routeContext) {
+    public Processor createProcessor(RouteContext routeContext) throws Exception {
         BeanProcessor answer;
         Class<?> clazz = bean != null ? bean.getClass() : null;
         BeanHolder beanHolder;
 
         if (ObjectHelper.isNotEmpty(ref)) {
-            beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
+            if (cache != null && cache) {
+                // cache the registry lookup which avoids repeat lookup in the registry
+                beanHolder = new RegistryBean(routeContext.getCamelContext(), ref).createCacheHolder();
+            } else {
+                beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
+            }
             // bean holder will check if the bean exists
             bean = beanHolder.getBean();
             answer = new BeanProcessor(beanHolder);

http://git-wip-us.apache.org/repos/asf/camel/blob/c3078ad7/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index 9998e51..7d5699c 100644
--- a/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -2580,6 +2580,41 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
 
     /**
      * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
+     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
+     *
+     * @param ref  reference to a bean to lookup in the registry
+     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
+     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type beanRef(String ref, boolean cache) {
+        BeanDefinition answer = new BeanDefinition(ref);
+        answer.setCache(cache);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
+     * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline
+     *
+     * @param ref  reference to a bean to lookup in the registry
+     * @param method  the method name to invoke on the bean (can be used to avoid ambiguity)
+     * @param cache  if enabled, Camel will cache the result of the first Registry look-up.
+     *               Cache can be enabled if the bean in the Registry is defined as a singleton scope.
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type beanRef(String ref, String method, boolean cache) {
+        BeanDefinition answer = new BeanDefinition(ref, method);
+        answer.setCache(cache);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
+     * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a>
      * Adds a processor which sets the body on the IN message
      *
      * @return a expression builder clause to set the body

http://git-wip-us.apache.org/repos/asf/camel/blob/c3078ad7/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
index 15c8778..ae0f9cf 100644
--- a/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/bean/BeanExplicitMethodAmbiguousTest.java
@@ -64,11 +64,11 @@ public class BeanExplicitMethodAmbiguousTest extends ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:hello").beanRef("dummy", "hello");
+                from("direct:hello").beanRef("dummy", "hello", true);
 
-                from("direct:bye").beanRef("dummy");
+                from("direct:bye").beanRef("dummy", true);
                 
-                from("direct:foo").beanRef("dummy", "bar");
+                from("direct:foo").beanRef("dummy", "bar", true);
             }
         };
     }


[6/6] git commit: CAMEL-6718: Marshal should leverage stream caching if enabled. Thanks to Franz Forsthofer for patch.

Posted by da...@apache.org.
CAMEL-6718: Marshal should leverage stream caching if enabled. Thanks to Franz Forsthofer for patch.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7002c750
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7002c750
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7002c750

Branch: refs/heads/camel-2.12.x
Commit: 7002c750db31cdc00e453b76c4b8bcf15da11d31
Parents: cf3f160
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 10 17:15:43 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Sep 10 17:16:06 2013 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/camel/processor/MarshalProcessor.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/7002c750/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
index c26d00a..efa2b8e 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
@@ -74,11 +74,11 @@ public class MarshalProcessor extends ServiceSupport implements AsyncProcessor,
         out.copyFrom(in);
 
         try {
-            dataFormat.marshal(exchange, body, os);
-
             if (cos != null) {
+                dataFormat.marshal(exchange, body, cos);
                 out.setBody(cos.newStreamCache());
             } else {
+                dataFormat.marshal(exchange, body, os);
                 byte[] data = os.toByteArray();
                 out.setBody(data);
             }