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; + } + +}