Skip to content

Commit

Permalink
CAMEL-10792: Allow Registry to bind beans.
Browse files Browse the repository at this point in the history
  • Loading branch information
davsclaus committed Feb 26, 2019
1 parent a050d7c commit 523439c
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 66 deletions.
Expand Up @@ -24,17 +24,19 @@
import org.apache.camel.LoadPropertiesException;
import org.apache.camel.TypeConverter;
import org.apache.camel.blueprint.handler.CamelNamespaceHandler;
import org.apache.camel.core.osgi.OsgiBeanRepository;
import org.apache.camel.core.osgi.OsgiCamelContextHelper;
import org.apache.camel.core.osgi.OsgiCamelContextPublisher;
import org.apache.camel.core.osgi.OsgiFactoryFinderResolver;
import org.apache.camel.core.osgi.OsgiTypeConverter;
import org.apache.camel.core.osgi.utils.BundleContextUtils;
import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.spi.BeanRepository;
import org.apache.camel.spi.EventNotifier;
import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.spi.ModelJAXBContextFactory;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.DefaultRegistry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
Expand All @@ -53,7 +55,6 @@ public class BlueprintCamelContext extends DefaultCamelContext implements Servic
private BundleContext bundleContext;
private BlueprintContainer blueprintContainer;
private ServiceRegistration<?> registration;

private BlueprintCamelStateService bundleStateService;

public BlueprintCamelContext(BundleContext bundleContext, BlueprintContainer blueprintContainer) {
Expand All @@ -65,6 +66,12 @@ public BlueprintCamelContext(BundleContext bundleContext, BlueprintContainer blu
OsgiCamelContextHelper.osgiUpdate(this, bundleContext);

// and these are blueprint specific
BeanRepository repo1 = new BlueprintContainerBeanRepository(getBlueprintContainer());
OsgiBeanRepository repo2 = new OsgiBeanRepository(bundleContext);
setRegistry(new DefaultRegistry(repo1, repo2));
// Need to clean up the OSGi service when camel context is closed.
addLifecycleStrategy(repo2);

setComponentResolver(new BlueprintComponentResolver(bundleContext));
setLanguageResolver(new BlueprintLanguageResolver(bundleContext));
setDataFormatResolver(new BlueprintDataFormatResolver(bundleContext));
Expand Down Expand Up @@ -235,12 +242,6 @@ protected TypeConverter createTypeConverter() {
return new OsgiTypeConverter(ctx, this, getInjector(), finder);
}

@Override
protected Registry createRegistry() {
Registry reg = new BlueprintContainerRegistry(getBlueprintContainer());
return OsgiCamelContextHelper.wrapRegistry(this, reg, bundleContext);
}

@Override
public void start() throws Exception {
final ClassLoader original = Thread.currentThread().getContextClassLoader();
Expand Down
Expand Up @@ -22,6 +22,7 @@
import java.util.Set;

import org.apache.camel.NoSuchBeanException;
import org.apache.camel.spi.BeanRepository;
import org.apache.camel.spi.Registry;
import org.osgi.framework.Bundle;
import org.osgi.service.blueprint.container.BlueprintContainer;
Expand All @@ -30,11 +31,11 @@
import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.ReferenceMetadata;

public class BlueprintContainerRegistry implements Registry {
public class BlueprintContainerBeanRepository implements BeanRepository {

private final BlueprintContainer blueprintContainer;

public BlueprintContainerRegistry(BlueprintContainer blueprintContainer) {
public BlueprintContainerBeanRepository(BlueprintContainer blueprintContainer) {
this.blueprintContainer = blueprintContainer;
}

Expand Down
Expand Up @@ -248,7 +248,7 @@ protected void initCustomRegistry(BlueprintCamelContext context) {

@Override
protected <S> S getBeanForType(Class<S> clazz) {
Collection<S> objects = BlueprintContainerRegistry.lookupByType(blueprintContainer, clazz).values();
Collection<S> objects = BlueprintContainerBeanRepository.lookupByType(blueprintContainer, clazz).values();
if (objects.size() == 1) {
return objects.iterator().next();
}
Expand Down
Expand Up @@ -46,7 +46,7 @@ public ContextScanRouteBuilderFinder(BlueprintCamelContext camelContext, Package
* Appends all the {@link org.apache.camel.builder.RouteBuilder} instances that can be found in the context
*/
public void appendBuilders(List<RoutesBuilder> list) {
Map<String, RoutesBuilder> beans = BlueprintContainerRegistry.lookupByType(blueprintContainer, RoutesBuilder.class, includeNonSingletons);
Map<String, RoutesBuilder> beans = BlueprintContainerBeanRepository.lookupByType(blueprintContainer, RoutesBuilder.class, includeNonSingletons);

for (Entry<String, RoutesBuilder> entry : beans.entrySet()) {
String key = entry.getKey();
Expand Down
Expand Up @@ -20,16 +20,17 @@
import org.apache.camel.Component;
import org.apache.camel.Endpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.SimpleRegistry;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.DefaultRegistry;
import org.apache.camel.test.junit4.TestSupport;
import org.junit.Test;

public class BlueprintComponentResolverTest extends TestSupport {

@Test
public void testOsgiResolverFindComponentFallbackTest() throws Exception {
SimpleRegistry registry = new SimpleRegistry();
registry.put("allstar-component", new SampleComponent(true));
Registry registry = new DefaultRegistry();
registry.bind("allstar-component", new SampleComponent(true));

CamelContext camelContext = new DefaultCamelContext(registry);

Expand All @@ -41,9 +42,9 @@ public void testOsgiResolverFindComponentFallbackTest() throws Exception {

@Test
public void testOsgiResolverFindLanguageDoubleFallbackTest() throws Exception {
SimpleRegistry registry = new SimpleRegistry();
registry.put("allstar", new SampleComponent(false));
registry.put("allstar-component", new SampleComponent(true));
Registry registry = new DefaultRegistry();
registry.bind("allstar", new SampleComponent(false));
registry.bind("allstar-component", new SampleComponent(true));

CamelContext camelContext = new DefaultCamelContext(registry);

Expand Down
Expand Up @@ -17,7 +17,6 @@
package org.apache.camel.core.osgi;

import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.DefaultRegistry;
import org.apache.camel.util.ObjectHelper;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
Expand All @@ -30,11 +29,9 @@ private OsgiCamelContextHelper() {
// helper class
}

public static void osgiUpdate(DefaultCamelContext camelContext, BundleContext bundleContext, OsgiBeanRepository beanRepository) {
public static void osgiUpdate(DefaultCamelContext camelContext, BundleContext bundleContext) {
ObjectHelper.notNull(bundleContext, "BundleContext");

LOG.debug("Using OsgiBeanRepository");
camelContext.setRegistry(new DefaultRegistry(beanRepository));
LOG.debug("Using OsgiCamelContextNameStrategy");
camelContext.setNameStrategy(new OsgiCamelContextNameStrategy(bundleContext));
LOG.debug("Using OsgiManagementNameStrategy");
Expand All @@ -51,9 +48,6 @@ public static void osgiUpdate(DefaultCamelContext camelContext, BundleContext bu
camelContext.setLanguageResolver(new OsgiLanguageResolver(bundleContext));
LOG.debug("Using OsgiDataFormatResolver");
camelContext.setDataFormatResolver(new OsgiDataFormatResolver(bundleContext));

// Need to clean up the OSGi service when camel context is closed.
camelContext.addLifecycleStrategy(beanRepository);
}

}
Expand Up @@ -28,20 +28,25 @@
import org.apache.camel.spi.BeanRepository;
import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.DefaultRegistry;
import org.osgi.framework.BundleContext;

public class OsgiDefaultCamelContext extends DefaultCamelContext {

private final BundleContext bundleContext;

public OsgiDefaultCamelContext(BundleContext bundleContext) {
this(bundleContext, new OsgiBeanRepository(bundleContext));
}

public OsgiDefaultCamelContext(BundleContext bundleContext, OsgiBeanRepository osgiBeanRepository) {
super();
this.bundleContext = bundleContext;
OsgiCamelContextHelper.osgiUpdate(this, bundleContext, osgiBeanRepository);

// inject common osgi
OsgiCamelContextHelper.osgiUpdate(this, bundleContext);

// and these are blueprint specific
OsgiBeanRepository repo1 = new OsgiBeanRepository(bundleContext);
setRegistry(new DefaultRegistry(repo1));
// Need to clean up the OSGi service when camel context is closed.
addLifecycleStrategy(repo1);
// setup the application context classloader with the bundle classloader
setApplicationContextClassLoader(new BundleDelegatingClassLoader(bundleContext.getBundle()));
}
Expand Down
Expand Up @@ -16,11 +16,8 @@
*/
package org.apache.camel.language.spel;

import org.apache.camel.CamelContext;
import org.apache.camel.ExpressionEvaluationException;
import org.apache.camel.LanguageTestSupport;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.SimpleRegistry;
import org.apache.camel.language.spel.bean.Dummy;
import org.junit.Test;

Expand All @@ -29,15 +26,10 @@
*/
public class SpelNonSpringTest extends LanguageTestSupport {

@Override
protected CamelContext createCamelContext() throws Exception {
SimpleRegistry registry = new SimpleRegistry();
registry.put("myDummy", new Dummy());
return new DefaultCamelContext(registry);
}

@Test
public void testSpelBeanExpressions() throws Exception {
context.getRegistry().bind("myDummy", new Dummy());

assertExpression("#{@myDummy.foo == 'xyz'}", true);
assertExpression("#{@myDummy.bar == 789}", true);
assertExpression("#{@myDummy.bar.toString()}", "789");
Expand All @@ -50,6 +42,8 @@ public void testSpelBeanExpressions() throws Exception {

@Test
public void testSpelBeanPredicates() throws Exception {
context.getRegistry().bind("myDummy", new Dummy());

assertPredicate("@myDummy.foo == 'xyz'");
assertPredicate("@myDummy.bar == 789");
assertPredicate("@myDummy.bar instanceof T(Integer)");
Expand Down
Expand Up @@ -16,6 +16,9 @@
*/
package org.apache.camel.support;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -29,7 +32,7 @@
*/
public class DefaultRegistry implements Registry {

private final BeanRepository repository;
private List<BeanRepository> repositories;
private final Registry simple = new SimpleRegistry();

/**
Expand All @@ -44,55 +47,68 @@ public DefaultRegistry() {
* Will fallback and use {@link SimpleRegistry} as internal registry if the beans cannot be found in the first
* choice bean repository.
*
* @param repository the first choice repository such as Spring, JNDI, OSGi etc.
* @param repositories the first choice repositories such as Spring, JNDI, OSGi etc.
*/
public DefaultRegistry(BeanRepository repository) {
this.repository = repository;
public DefaultRegistry(BeanRepository... repositories) {
if (repositories != null) {
this.repositories = new ArrayList<>(Arrays.asList(repositories));
}
}

@Override
public void bind(String id, Object bean) {
// favour use the real repository
if (repository != null && repository instanceof Registry) {
((Registry) repository).bind(id, bean);
} else {
simple.bind(id, bean);
}
simple.bind(id, bean);
}

@Override
public Object lookupByName(String name) {
Object answer = repository != null ? repository.lookupByName(name) : null;
if (answer == null) {
answer = simple.lookupByName(name);
if (repositories != null) {
for (BeanRepository r : repositories) {
Object answer = r.lookupByName(name);
if (answer != null) {
return answer;
}
}
}
return answer;
return simple.lookupByName(name);
}

@Override
public <T> T lookupByNameAndType(String name, Class<T> type) {
T answer = repository != null ? repository.lookupByNameAndType(name, type) : null;
if (answer == null) {
answer = simple.lookupByNameAndType(name, type);
if (repositories != null) {
for (BeanRepository r : repositories) {
T answer = r.lookupByNameAndType(name, type);
if (answer != null) {
return answer;
}
}
}
return answer;
return simple.lookupByNameAndType(name, type);
}

@Override
public <T> Map<String, T> findByTypeWithName(Class<T> type) {
Map<String, T> answer = repository != null ? repository.findByTypeWithName(type) : null;
if (answer == null) {
answer = simple.findByTypeWithName(type);
if (repositories != null) {
for (BeanRepository r : repositories) {
Map<String, T> answer = r.findByTypeWithName(type);
if (answer != null) {
return answer;
}
}
}
return answer;
return simple.findByTypeWithName(type);
}

@Override
public <T> Set<T> findByType(Class<T> type) {
Set<T> answer = repository != null ? repository.findByType(type) : null;
if (answer == null) {
answer = simple.findByType(type);
if (repositories != null) {
for (BeanRepository r : repositories) {
Set<T> answer = r.findByType(type);
if (answer != null) {
return answer;
}
}
}
return answer;
return simple.findByType(type);
}
}

0 comments on commit 523439c

Please sign in to comment.