You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2012/07/16 19:13:16 UTC

svn commit: r1362139 - in /camel/branches/camel-2.10.x/components: camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/ camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/ camel-test-blueprint/src/test/java/org/apache/camel...

Author: gnodet
Date: Mon Jul 16 17:13:16 2012
New Revision: 1362139

URL: http://svn.apache.org/viewvc?rev=1362139&view=rev
Log:
[CAMEL-5451] Camel-Blueprint should wait for camel-core to be started since there is a strong dependency

Added:
    camel/branches/camel-2.10.x/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/BlueprintPropertiesTest.java
Modified:
    camel/branches/camel-2.10.x/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
    camel/branches/camel-2.10.x/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java

Modified: camel/branches/camel-2.10.x/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.10.x/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java?rev=1362139&r1=1362138&r2=1362139&view=diff
==============================================================================
--- camel/branches/camel-2.10.x/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java (original)
+++ camel/branches/camel-2.10.x/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java Mon Jul 16 17:13:16 2012
@@ -181,7 +181,11 @@ public class CamelNamespaceHandler imple
 
         CamelContextFactoryBean ccfb = (CamelContextFactoryBean) value;
         ccfb.setImplicitId(implicitId);
-        
+
+        // The properties component is always used / created by the CamelContextFactoryBean
+        // so we need to ensure that the resolver is ready to use
+        ComponentMetadata propertiesComponentResolver = getComponentResolverReference(context, "properties");
+
         MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
         factory.setId(".camelBlueprint.passThrough." + contextId);
         factory.setObject(new PassThroughCallable<Object>(value));
@@ -194,6 +198,7 @@ public class CamelNamespaceHandler imple
         factory2.setDestroyMethod("destroy");
         factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
         factory2.addProperty("bundleContext", createRef(context, "blueprintBundleContext"));
+        factory2.addDependsOn(propertiesComponentResolver.getId());
         context.getComponentDefinitionRegistry().registerComponentDefinition(factory2);
 
         MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
@@ -514,6 +519,96 @@ public class CamelNamespaceHandler imple
         return r;
     }
 
+    private static ComponentMetadata getDataformatResolverReference(ParserContext context, String dataformat) {
+        ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+        ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.dataformatResolver." + dataformat);
+        if (cm == null) {
+            MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+            svc.setId(".camelBlueprint.dataformatResolver." + dataformat);
+            svc.setFilter("(dataformat=" + dataformat + ")");
+            svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(dataformat) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+            try {
+                // Try to set the runtime interface (only with aries blueprint > 0.1
+                svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, DataFormatResolver.class);
+            } catch (Throwable t) {
+                // Check if the bundle can see the class
+                try {
+                    PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+                    Bundle b = (Bundle) ptm.getObject();
+                    if (b.loadClass(DataFormatResolver.class.getName()) != DataFormatResolver.class) {
+                        throw new UnsupportedOperationException();
+                    }
+                    svc.setInterface(DataFormatResolver.class.getName());
+                } catch (Throwable t2) {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            componentDefinitionRegistry.registerComponentDefinition(svc);
+            cm = svc;
+        }
+        return cm;
+    }
+
+    private static ComponentMetadata getLanguageResolverReference(ParserContext context, String language) {
+        ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+        ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.languageResolver." + language);
+        if (cm == null) {
+            MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+            svc.setId(".camelBlueprint.languageResolver." + language);
+            svc.setFilter("(language=" + language + ")");
+            svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(language) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+            try {
+                // Try to set the runtime interface (only with aries blueprint > 0.1
+                svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, LanguageResolver.class);
+            } catch (Throwable t) {
+                // Check if the bundle can see the class
+                try {
+                    PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+                    Bundle b = (Bundle) ptm.getObject();
+                    if (b.loadClass(LanguageResolver.class.getName()) != LanguageResolver.class) {
+                        throw new UnsupportedOperationException();
+                    }
+                    svc.setInterface(LanguageResolver.class.getName());
+                } catch (Throwable t2) {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            componentDefinitionRegistry.registerComponentDefinition(svc);
+            cm = svc;
+        }
+        return cm;
+    }
+
+    private static ComponentMetadata getComponentResolverReference(ParserContext context, String component) {
+        ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+        ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.componentResolver." + component);
+        if (cm == null) {
+            MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+            svc.setId(".camelBlueprint.componentResolver." + component);
+            svc.setFilter("(component=" + component + ")");
+            svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(component) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+            try {
+                // Try to set the runtime interface (only with aries blueprint > 0.1
+                svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, ComponentResolver.class);
+            } catch (Throwable t) {
+                // Check if the bundle can see the class
+                try {
+                    PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+                    Bundle b = (Bundle) ptm.getObject();
+                    if (b.loadClass(ComponentResolver.class.getName()) != ComponentResolver.class) {
+                        throw new UnsupportedOperationException();
+                    }
+                    svc.setInterface(ComponentResolver.class.getName());
+                } catch (Throwable t2) {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            componentDefinitionRegistry.registerComponentDefinition(svc);
+            cm = svc;
+        }
+        return cm;
+    }
+
     public static class PassThroughCallable<T> implements Callable<T> {
 
         private T value;
@@ -678,92 +773,21 @@ public class CamelNamespaceHandler imple
             Set<String> components = new HashSet<String>();
             Set<String> languages = new HashSet<String>();
             Set<String> dataformats = new HashSet<String>();
-            Set<String> dependsOn = new HashSet<String>();
             for (RouteDefinition rd : camelContext.getRouteDefinitions()) {
                 findInputComponents(rd.getInputs(), components, languages, dataformats);
                 findOutputComponents(rd.getOutputs(), components, languages, dataformats);
             }
+            // We can only add service references to resolvers, but we can't make the factory depends on those
+            // because the factory has already been instantiated
             try {
                 for (String component : components) {
-                    ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.componentResolver." + component);
-                    if (cm == null) {
-                        MutableReferenceMetadata svc = createMetadata(MutableReferenceMetadata.class);
-                        svc.setId(".camelBlueprint.componentResolver." + component);
-                        svc.setFilter("(component=" + component + ")");
-                        svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(component) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
-                        try {
-                            // Try to set the runtime interface (only with aries blueprint > 0.1
-                            svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, ComponentResolver.class);
-                        } catch (Throwable t) {
-                            // Check if the bundle can see the class
-                            try {
-                                PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
-                                Bundle b = (Bundle) ptm.getObject();
-                                if (b.loadClass(ComponentResolver.class.getName()) != ComponentResolver.class) {
-                                    throw new UnsupportedOperationException();
-                                }
-                                svc.setInterface(ComponentResolver.class.getName());
-                            } catch (Throwable t2) {
-                                throw new UnsupportedOperationException();
-                            }
-                        }
-                        componentDefinitionRegistry.registerComponentDefinition(svc);
-                        dependsOn.add(svc.getId());
-                    }
+                    getComponentResolverReference(context, component);
                 }
                 for (String language : languages) {
-                    ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.languageResolver." + language);
-                    if (cm == null) {
-                        MutableReferenceMetadata svc = createMetadata(MutableReferenceMetadata.class);
-                        svc.setId(".camelBlueprint.languageResolver." + language);
-                        svc.setFilter("(language=" + language + ")");
-                        svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(language) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
-                        try {
-                            // Try to set the runtime interface (only with aries blueprint > 0.1
-                            svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, LanguageResolver.class);
-                        } catch (Throwable t) {
-                            // Check if the bundle can see the class
-                            try {
-                                PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
-                                Bundle b = (Bundle) ptm.getObject();
-                                if (b.loadClass(LanguageResolver.class.getName()) != LanguageResolver.class) {
-                                    throw new UnsupportedOperationException();
-                                }
-                                svc.setInterface(LanguageResolver.class.getName());
-                            } catch (Throwable t2) {
-                                throw new UnsupportedOperationException();
-                            }
-                        }
-                        componentDefinitionRegistry.registerComponentDefinition(svc);
-                        dependsOn.add(svc.getId());
-                    }
+                    getLanguageResolverReference(context, language);
                 }
                 for (String dataformat : dataformats) {
-                    ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.dataformatResolver." + dataformat);
-                    if (cm == null) {
-                        MutableReferenceMetadata svc = createMetadata(MutableReferenceMetadata.class);
-                        svc.setId(".camelBlueprint.dataformatResolver." + dataformat);
-                        svc.setFilter("(dataformat=" + dataformat + ")");
-                        svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(dataformat) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
-                        try {
-                            // Try to set the runtime interface (only with aries blueprint > 0.1
-                            svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, DataFormatResolver.class);
-                        } catch (Throwable t) {
-                            // Check if the bundle can see the class
-                            try {
-                                PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
-                                Bundle b = (Bundle) ptm.getObject();
-                                if (b.loadClass(DataFormatResolver.class.getName()) != DataFormatResolver.class) {
-                                    throw new UnsupportedOperationException();
-                                }
-                                svc.setInterface(DataFormatResolver.class.getName());
-                            } catch (Throwable t2) {
-                                throw new UnsupportedOperationException();
-                            }
-                        }
-                        componentDefinitionRegistry.registerComponentDefinition(svc);
-                        dependsOn.add(svc.getId());
-                    }
+                    getDataformatResolverReference(context, dataformat);
                 }
             } catch (UnsupportedOperationException e) {
                 LOG.warn("Unable to add dependencies on to camel components OSGi services.  "
@@ -775,10 +799,6 @@ public class CamelNamespaceHandler imple
 
         }
 
-        public <T extends org.osgi.service.blueprint.reflect.Metadata> T createMetadata(java.lang.Class<T> tClass) {
-            return context.createMetadata(tClass);
-        }
-
         private void findInputComponents(List<FromDefinition> defs, Set<String> components, Set<String> languages, Set<String> dataformats) {
             if (defs != null) {
                 for (FromDefinition def : defs) {

Modified: camel/branches/camel-2.10.x/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.10.x/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java?rev=1362139&r1=1362138&r2=1362139&view=diff
==============================================================================
--- camel/branches/camel-2.10.x/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java (original)
+++ camel/branches/camel-2.10.x/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java Mon Jul 16 17:13:16 2012
@@ -62,6 +62,14 @@ public abstract class CamelBlueprintTest
     }
 
     /**
+     * Return the system bundle context
+     * @return
+     */
+    protected BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    /**
      * Gets the bundle descriptor from the classpath.
      * <p/>
      * Return the location(s) of the bundle descriptors from the classpath.

Added: camel/branches/camel-2.10.x/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/BlueprintPropertiesTest.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.10.x/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/BlueprintPropertiesTest.java?rev=1362139&view=auto
==============================================================================
--- camel/branches/camel-2.10.x/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/BlueprintPropertiesTest.java (added)
+++ camel/branches/camel-2.10.x/components/camel-test-blueprint/src/test/java/org/apache/camel/test/blueprint/BlueprintPropertiesTest.java Mon Jul 16 17:13:16 2012
@@ -0,0 +1,64 @@
+/**
+ * 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.test.blueprint;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ *
+ */
+public class BlueprintPropertiesTest extends CamelBlueprintTestSupport {
+
+    @Override
+    protected String getBlueprintDescriptor() {
+        return "org/apache/camel/test/blueprint/configadmin.xml";
+    }
+
+    @Test
+    public void testProperties() throws Exception {
+        Bundle camelCore = getBundleBySymbolicName("org.apache.camel.camel-core");
+        Bundle test = getBundleBySymbolicName(getClass().getSimpleName());
+
+        camelCore.stop();
+        test.stop();
+
+        Thread.sleep(500);
+
+        test.start();
+        try {
+            getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=" + getClass().getSimpleName() + ")", 500);
+            fail("Expected a timeout");
+        } catch (RuntimeException e) {
+            // Expected timeout
+        }
+
+        camelCore.start();
+        getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=" + getClass().getSimpleName() + ")", 500);
+    }
+
+    private Bundle getBundleBySymbolicName(String name) {
+        for (Bundle bundle : getBundleContext().getBundles()) {
+            if (bundle.getSymbolicName().equals(name)) {
+                return bundle;
+            }
+        }
+        return null;
+    }
+
+}