Skip to content

Commit

Permalink
Refactor customizer activation #46
Browse files Browse the repository at this point in the history
  • Loading branch information
lburgazzoli committed May 20, 2019
1 parent 6de97a3 commit 7172d2d
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public final class Constants {
public static final String ROUTES_LOADER_RESOURCE_PATH = "META-INF/services/org/apache/camel/k/loader/";
public static final String CONTEXT_CUSTOMIZER_RESOURCE_PATH = "META-INF/services/org/apache/camel/k/customizer/";
public static final String PROPERTY_CAMEL_K_CUSTOMIZER = "camel.k.customizer";
public static final String ENABLE_CUSTOMIZER_PATTERN = "customizer.([\\w][\\w-]*).enabled";

private Constants() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,25 @@
package org.apache.camel.k;

import org.apache.camel.CamelContext;
import org.apache.camel.Ordered;

@FunctionalInterface
public interface ContextCustomizer {
public interface ContextCustomizer extends Ordered, Comparable<ContextCustomizer>{
/**
* Perform CamelContext customization.
*
* @param camelContext the camel context to customize.
* @param registry the runtime registry.
*/
void apply(CamelContext camelContext, Runtime.Registry registry);

@Override
default int getOrder() {
return Ordered.LOWEST;
}

@Override
default int compareTo(ContextCustomizer o) {
return Integer.compare(getOrder(), o.getOrder());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.camel.CamelContext;
import org.apache.camel.NoFactoryAvailableException;
Expand All @@ -46,7 +47,6 @@
import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -60,63 +60,75 @@ private RuntimeSupport() {

public static List<ContextCustomizer> configureContext(CamelContext context, Runtime.Registry registry) {
List<ContextCustomizer> appliedCustomizers = new ArrayList<>();
Set<String> customizers = lookupCustomizerIDs(context);

// this is to initialize all customizers that might be already present in
// the context injected by other means.
for (Map.Entry<String, ContextCustomizer> entry: context.getRegistry().findByTypeWithName(ContextCustomizer.class).entrySet()) {
if (!customizers.remove(entry.getKey())) {
continue;
}

applyCustomizer(context, entry.getKey(), entry.getValue(), registry);
try {
Map<String, ContextCustomizer> customizers = lookupCustomizers(context);

appliedCustomizers.add(entry.getValue());
}
customizers.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.forEach(e -> {
LOGGER.info("Apply ContextCustomizer with id={} and type={}", e.getKey(), e.getValue().getClass().getName());

try {
FactoryFinder finder = context.getFactoryFinder(Constants.CONTEXT_CUSTOMIZER_RESOURCE_PATH);
bindProperties(context, e.getValue(), "customizer." + e.getKey() + ".");
e.getValue().apply(context, registry);

for (String customizerId : customizers) {
ContextCustomizer customizer = (ContextCustomizer) finder.newInstance(customizerId);
applyCustomizer(context, customizerId, customizer, registry);
appliedCustomizers.add(e.getValue());
});

appliedCustomizers.add(customizer);
}
} catch (NoFactoryAvailableException e) {
throw new RuntimeException(e);
}

return appliedCustomizers;
}

public static void applyCustomizer(CamelContext context, String customizerId, ContextCustomizer customizer, Runtime.Registry registry) {
ObjectHelper.notNull(customizer, "customizer");
StringHelper.notEmpty(customizerId, "customizerId");

LOGGER.info("Apply ContextCustomizer with id={} and type={}", customizerId, customizer.getClass().getName());

bindProperties(context, customizer, "customizer." + customizerId + ".");
customizer.apply(context, registry);
}

public static Set<String> lookupCustomizerIDs(CamelContext context) {
Set<String> customizers = new TreeSet<>();
public static Map<String, ContextCustomizer> lookupCustomizers(CamelContext context) throws NoFactoryAvailableException {
Map<String, ContextCustomizer> customizers = new ConcurrentHashMap<>();

String customizerIDs = System.getenv().getOrDefault(Constants.ENV_CAMEL_K_CUSTOMIZERS, "");
if (ObjectHelper.isEmpty(customizerIDs)) {
PropertiesComponent component = context.getComponent("properties", PropertiesComponent.class);
Properties properties = component.getInitialProperties();
PropertiesComponent component = context.getComponent("properties", PropertiesComponent.class);
Properties properties = component.getInitialProperties();

if (properties != null) {
customizerIDs = properties.getProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "");
if (properties != null) {
//
// Filter out customizers available on the registry
// but not enabled
//
for (Map.Entry<String, ContextCustomizer> entry: context.getRegistry().findByTypeWithName(ContextCustomizer.class).entrySet()) {
String enabled = properties.getProperty("customizer." + entry.getKey() + ".enabled");
if (Boolean.valueOf(enabled)) {
customizers.put(entry.getKey(), entry.getValue());
}
}
}

if (ObjectHelper.isNotEmpty(customizerIDs)) {
for (String customizerId : customizerIDs.split(",", -1)) {
customizers.add(customizerId);
}
final FactoryFinder finder = context.getFactoryFinder(Constants.CONTEXT_CUSTOMIZER_RESOURCE_PATH);
final Pattern pattern = Pattern.compile(Constants.ENABLE_CUSTOMIZER_PATTERN);

properties.entrySet().stream()
.filter(entry -> entry.getKey() instanceof String)
.filter(entry -> entry.getValue() != null)
.forEach(entry -> {
final String key = (String)entry.getKey();
final Object val = entry.getValue();
final Matcher matcher = pattern.matcher(key);

if (matcher.matches() && matcher.groupCount() == 1) {
if (Boolean.valueOf(String.valueOf(val))) {
//
// Do not override customizers eventually found
// in the registry
//
customizers.computeIfAbsent(matcher.group(1), customizerId -> {
try {
return (ContextCustomizer) finder.newInstance(customizerId);
} catch (NoFactoryAvailableException e) {
throw new RuntimeException(e);
}
});
}
}
}
);
}

return customizers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.camel.k.support;

import org.apache.camel.CamelContext;
import org.apache.camel.Ordered;
import org.apache.camel.impl.ExplicitCamelContextNameStrategy;
import org.apache.camel.k.ContextCustomizer;
import org.apache.camel.k.Runtime;
Expand All @@ -32,6 +33,11 @@ public NameCustomizer(String name) {
this.name = name;
}

@Override
public int getOrder() {
return Ordered.HIGHEST;
}

@Override
public void apply(CamelContext camelContext, Runtime.Registry registry) {
camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.apache.camel.CamelContext;
import org.apache.camel.component.properties.PropertiesComponent;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.k.Constants;
import org.apache.camel.k.ContextCustomizer;
import org.apache.camel.k.InMemoryRegistry;
import org.apache.camel.k.Runtime;
Expand All @@ -48,7 +47,7 @@ public void testLoadCustomizers() {
assertThat(customizers).hasSize(0);

Properties properties = new Properties();
properties.setProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "name");
properties.setProperty("customizer.name.enabled", "true");
pc.setInitialProperties(properties);

customizers = RuntimeSupport.configureContext(context, registry);
Expand All @@ -64,7 +63,7 @@ public void testLoadCustomizersOrdering() {
context.addComponent("properties", pc);

Properties properties = new Properties();
properties.setProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "name");
properties.setProperty("customizer.name.enabled", "true");
pc.setInitialProperties(properties);

List<ContextCustomizer> customizers = RuntimeSupport.configureContext(context, registry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import org.apache.camel.CamelContext;
import org.apache.camel.component.seda.SedaComponent;
import org.apache.camel.k.Constants;
import org.apache.camel.k.ContextCustomizer;
import org.apache.camel.k.Runtime;
import org.apache.camel.k.listener.ContextConfigurer;
Expand Down Expand Up @@ -130,11 +129,12 @@ public void testContextConfiguration() throws Exception {

@Test
public void testContextCustomizerFromProperty() throws Exception {
System.setProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "test");
System.setProperty("customizer.test.messageHistory", "false");
Properties properties = new Properties();
properties.setProperty("customizer.test.enabled", "true");
properties.setProperty("customizer.test.messageHistory", "false");

ApplicationRuntime runtime = new ApplicationRuntime();
runtime.setProperties(System.getProperties());
runtime.setProperties(properties);
runtime.addListener(new ContextConfigurer());
runtime.addListener(new ContextLifecycleConfigurer());
runtime.addListener(Runtime.Phase.Started, r -> {
Expand All @@ -149,8 +149,11 @@ public void testContextCustomizerFromProperty() throws Exception {

@Test
public void testContextCustomizerFromRegistry() throws Exception {
Properties properties = new Properties();
properties.setProperty("customizer.c1.enabled", "true");

ApplicationRuntime runtime = new ApplicationRuntime();
runtime.setProperties(System.getProperties());
runtime.setProperties(properties);
runtime.addListener(new ContextConfigurer());
runtime.addListener(new ContextLifecycleConfigurer());
runtime.getRegistry().bind("c1", (ContextCustomizer) (camelContext, registry) -> {
Expand Down

0 comments on commit 7172d2d

Please sign in to comment.