Added new convention to default resolvers
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9d81d1f5 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9d81d1f5 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9d81d1f5 Branch: refs/heads/master Commit: 9d81d1f585eebc73ff6ecd242fad97384e4b150a Parents: 1706d88 Author: Nicola Ferraro <ni.ferr...@gmail.com> Authored: Wed Jul 27 16:02:16 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Jul 28 08:41:34 2016 +0200 ---------------------------------------------------------------------- .../camel/impl/DefaultComponentResolver.java | 31 +++- .../camel/impl/DefaultDataFormatResolver.java | 22 ++- .../impl/DefaultCamelContextResolverTest.java | 166 +++++++++++++++++++ 3 files changed, 205 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9d81d1f5/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentResolver.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentResolver.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentResolver.java index 026e74b..99cb020 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentResolver.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentResolver.java @@ -38,18 +38,17 @@ import org.slf4j.LoggerFactory; public class DefaultComponentResolver implements ComponentResolver { public static final String RESOURCE_PATH = "META-INF/services/org/apache/camel/component/"; + private static final Logger LOG = LoggerFactory.getLogger(DefaultComponentResolver.class); + + private static final String FALLBACK_COMPONENT_BEAN_SUFFIX = "-component"; + private FactoryFinder factoryFinder; public Component resolveComponent(String name, CamelContext context) { // lookup in registry first - Object bean = null; - try { - bean = context.getRegistry().lookupByName(name); - getLog().debug("Found component: {} in registry: {}", name, bean); - } catch (Exception e) { - getLog().debug("Ignored error looking up bean: " + name, e); - } + Object bean = lookupInRegistry(context, name, name + FALLBACK_COMPONENT_BEAN_SUFFIX); + if (bean != null) { if (bean instanceof Component) { return (Component) bean; @@ -90,6 +89,24 @@ public class DefaultComponentResolver implements ComponentResolver { } } + private Object lookupInRegistry(CamelContext context, String... names) { + Object bean = null; + for(String name : names) { + try { + bean = context.getRegistry().lookupByName(name); + getLog().debug("Lookup component with name {} in registry. Found: {}", name, bean); + } catch (Exception e) { + getLog().debug("Ignored error looking up bean: " + name, e); + } + + if(bean!=null) { + break; + } + } + + return bean; + } + private Class<?> findComponent(String name, CamelContext context) throws ClassNotFoundException, IOException { if (factoryFinder == null) { factoryFinder = context.getFactoryFinder(RESOURCE_PATH); http://git-wip-us.apache.org/repos/asf/camel/blob/9d81d1f5/camel-core/src/main/java/org/apache/camel/impl/DefaultDataFormatResolver.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultDataFormatResolver.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultDataFormatResolver.java index 1d04116..353858c 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultDataFormatResolver.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultDataFormatResolver.java @@ -31,10 +31,12 @@ public class DefaultDataFormatResolver implements DataFormatResolver { public static final String DATAFORMAT_RESOURCE_PATH = "META-INF/services/org/apache/camel/dataformat/"; + private static final String FALLBACK_DATA_FORMAT_BEAN_SUFFIX = "-dataformat"; + protected FactoryFinder dataformatFactory; public DataFormat resolveDataFormat(String name, CamelContext context) { - DataFormat dataFormat = lookup(context, name, DataFormat.class); + DataFormat dataFormat = lookup(context, DataFormat.class, name, name + FALLBACK_DATA_FORMAT_BEAN_SUFFIX); if (dataFormat == null) { Class<?> type = null; try { @@ -64,12 +66,18 @@ public class DefaultDataFormatResolver implements DataFormatResolver { return dataFormat; } - private static <T> T lookup(CamelContext context, String ref, Class<T> type) { - try { - return context.getRegistry().lookupByNameAndType(ref, type); - } catch (Exception e) { - // need to ignore not same type and return it as null - return null; + private static <T> T lookup(CamelContext context, Class<T> type, String... names) { + for(String name : names) { + try { + T bean = context.getRegistry().lookupByNameAndType(name, type); + if(bean!=null) { + return bean; + } + } catch (Exception e) { + // need to ignore not same type + } } + // return null if anything goes wrong + return null; } } http://git-wip-us.apache.org/repos/asf/camel/blob/9d81d1f5/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextResolverTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextResolverTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextResolverTest.java new file mode 100644 index 0000000..fb11a19 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultCamelContextResolverTest.java @@ -0,0 +1,166 @@ +/** + * 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.impl; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.Component; +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.spi.DataFormat; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Tests if the default camel context is able to resolve components and data formats using both their real names and/or fallback names. + * Fallback names have been introduced to avoid name clash in some registries (eg. Spring application context) between components and other camel features. + */ +public class DefaultCamelContextResolverTest { + + private CamelContext context; + + @Before + public void createContext() throws Exception { + SimpleRegistry registry = new SimpleRegistry(); + context = new DefaultCamelContext(registry); + + // Add a component using its fallback name + registry.put("green-component", new SampleComponent(true)); + + // Add a data format using its fallback name + registry.put("green-dataformat", new SampleDataFormat(true)); + + // Add a component using both names + registry.put("yellow", new SampleComponent(false)); + registry.put("yellow-component", new SampleComponent(true)); + + // Add a data format using both names + registry.put("red", new SampleDataFormat(false)); + registry.put("red-dataformat", new SampleDataFormat(true)); + + context.start(); + } + + @After + public void destroyContext() throws Exception { + context.stop(); + context = null; + } + + @Test + public void testComponentWithFallbackNames() throws Exception { + Component component = context.getComponent("green"); + assertNotNull("Component not found in registry", component); + assertTrue("Wrong instance type of the Component", component instanceof SampleComponent); + assertTrue("Here we should have the fallback Component", ((SampleComponent) component).isFallback()); + } + + @Test + public void testComponentWithBothNames() throws Exception { + Component component = context.getComponent("yellow"); + assertNotNull("Component not found in registry", component); + assertTrue("Wrong instance type of the Component", component instanceof SampleComponent); + assertFalse("Here we should NOT have the fallback Component", ((SampleComponent) component).isFallback()); + } + + @Test + public void testDataFormatWithFallbackNames() throws Exception { + DataFormat dataFormat = context.resolveDataFormat("green"); + assertNotNull("DataFormat not found in registry", dataFormat); + assertTrue("Wrong instance type of the DataFormat", dataFormat instanceof SampleDataFormat); + assertTrue("Here we should have the fallback DataFormat", ((SampleDataFormat) dataFormat).isFallback()); + } + + @Test + public void testDataformatWithBothNames() throws Exception { + DataFormat dataFormat = context.resolveDataFormat("red"); + assertNotNull("DataFormat not found in registry", dataFormat); + assertTrue("Wrong instance type of the DataFormat", dataFormat instanceof SampleDataFormat); + assertFalse("Here we should NOT have the fallback DataFormat", ((SampleDataFormat) dataFormat).isFallback()); + } + + @Test + public void testNullLookupComponent() throws Exception { + Component component = context.getComponent("xxxxxxxxx"); + assertNull("Non-existent Component should be null", component); + } + + @Test + public void testNullLookupDataFormat() throws Exception { + DataFormat dataFormat = context.resolveDataFormat("xxxxxxxxx"); + assertNull("Non-existent DataFormat should be null", dataFormat); + } + + public static class SampleComponent extends DefaultComponent { + + private boolean fallback; + + public SampleComponent(boolean fallback) { + this.fallback = fallback; + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + throw new UnsupportedOperationException("Should not be called"); + } + + public boolean isFallback() { + return fallback; + } + + public void setFallback(boolean fallback) { + this.fallback = fallback; + } + } + + public static class SampleDataFormat implements DataFormat { + + private boolean fallback; + + public SampleDataFormat(boolean fallback) { + this.fallback = fallback; + } + + @Override + public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception { + throw new UnsupportedOperationException("Should not be called"); + } + + @Override + public Object unmarshal(Exchange exchange, InputStream stream) throws Exception { + throw new UnsupportedOperationException("Should not be called"); + } + + public boolean isFallback() { + return fallback; + } + + public void setFallback(boolean fallback) { + this.fallback = fallback; + } + } + +}