You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/01/11 08:56:54 UTC
[camel] branch main updated: CAMEL-15724 light rework of CDI module to make it using CDI 2 API and have jta an… (#6705)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fe1975d CAMEL-15724 light rework of CDI module to make it using CDI 2 API and have jta an… (#6705)
fe1975d is described below
commit fe1975dda8eb8b7cdc70f89901af73f46115e695
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Tue Jan 11 09:54:44 2022 +0100
CAMEL-15724 light rework of CDI module to make it using CDI 2 API and have jta an… (#6705)
* rebase
* CdiCamelFactory checkstyle fix
* typo for txmgr lookup
* review comment about catch
* fixing com.arjuna.ats.jta.TransactionManager.transactionManager name
---
.../java/org/apache/camel/cdi/CdiRouteBuilder.java | 18 +++-
.../TransactionalJtaTransactionPolicy.java | 40 +++++++++
components/camel-cdi-main/pom.xml | 7 --
.../src/main/java/org/apache/camel/cdi/Main.java | 63 ++++++++++----
components/camel-cdi/pom.xml | 8 ++
.../org/apache/camel/cdi/CamelContextProducer.java | 8 +-
.../apache/camel/cdi/CdiCamelBeanRepository.java | 6 +-
.../org/apache/camel/cdi/CdiCamelExtension.java | 96 ++++++++++++++++++----
.../java/org/apache/camel/cdi/CdiCamelFactory.java | 48 ++---------
.../java/org/apache/camel/cdi/CdiSpiHelper.java | 8 +-
.../main/java/org/apache/camel/cdi/Startup.java | 3 +
.../src/main/java/org/apache/camel/cdi/Uri.java | 1 -
.../org/apache/camel/cdi/XmlCdiBeanFactory.java | 24 +++---
.../CdiJtaTransactionErrorHandlerBuilder.java} | 16 +---
.../CdiTransactionalErrorHandlerBuilder.java} | 22 +++--
15 files changed, 243 insertions(+), 125 deletions(-)
diff --git a/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/CdiRouteBuilder.java b/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/CdiRouteBuilder.java
index f5d7322..a695b0d 100644
--- a/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/CdiRouteBuilder.java
+++ b/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/CdiRouteBuilder.java
@@ -16,11 +16,15 @@
*/
package org.apache.camel.cdi;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.jta.JtaTransactionErrorHandlerBuilder;
+import org.apache.camel.cdi.transaction.CdiTransactionalErrorHandlerBuilder;
/**
- * An extension of the {@link RouteBuilder} to provide some additional helper methods.
+ * An extension of the {@link RouteBuilder} to provide some additional JTA helper methods.
+ *
+ * You never really need it since {@code transactionErrorHandler()} can be replaced by
+ * {@code new JtaTransactionErrorHandlerBuilder()}.
*/
public abstract class CdiRouteBuilder extends RouteBuilder {
@@ -29,7 +33,13 @@ public abstract class CdiRouteBuilder extends RouteBuilder {
*
* @return the created error handler
*/
- public JtaTransactionErrorHandlerBuilder transactionErrorHandler() {
- return new JtaTransactionErrorHandlerBuilder();
+ // IMPORTANT: don't leak CdiJtaTransactionErrorHandlerBuilder in the signature,
+ // only things not depending on camel-jta
+ public <T extends DefaultErrorHandlerBuilder & CdiTransactionalErrorHandlerBuilder> T transactionErrorHandler() {
+ try {
+ return (T) new org.apache.camel.cdi.transaction.CdiJtaTransactionErrorHandlerBuilder();
+ } catch (final NoClassDefFoundError e) {
+ throw new IllegalStateException("JTA not available");
+ }
}
}
diff --git a/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/transaction/TransactionalJtaTransactionPolicy.java b/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/transaction/TransactionalJtaTransactionPolicy.java
index 680cc3a..2f57135 100644
--- a/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/transaction/TransactionalJtaTransactionPolicy.java
+++ b/components/camel-cdi-jta/src/main/java/org/apache/camel/cdi/transaction/TransactionalJtaTransactionPolicy.java
@@ -16,6 +16,9 @@
*/
package org.apache.camel.cdi.transaction;
+import java.util.Objects;
+import java.util.stream.Stream;
+
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.HeuristicMixedException;
@@ -31,6 +34,8 @@ import org.apache.camel.jta.JtaTransactionPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static java.util.stream.Collectors.toList;
+
/**
* Helper methods for transaction handling
*
@@ -47,6 +52,13 @@ public abstract class TransactionalJtaTransactionPolicy extends JtaTransactionPo
"java:pm/TransactionManager",
"java:/TransactionManager"
};
+ private static final String[] METHODS = new String[] {
+ "org.openejb.OpenEJB.getTransactionManager",
+ "com.arjuna.ats.jta.TransactionManager.transactionManager",
+ "com.bluestone.jta.SaTransactionManagerFactory.SaGetTransactionManager",
+ "com.sun.jts.jta.TransactionManagerImpl.getTransactionManagerImpl",
+ "com.inprise.visitransact.jta.TransactionManagerImpl.getTransactionManagerImpl",
+ };
protected TransactionManager transactionManager;
@@ -69,6 +81,7 @@ public abstract class TransactionalJtaTransactionPolicy extends JtaTransactionPo
}
}
+ // todo: see @openjpa:openjpa-kernel/src/main/java/org/apache/openjpa/ee/AutomaticManagedRuntime.java
private TransactionManager lookupTransactionManager() {
TransactionManager tm;
for (String jndiName : TRANSACTION_MANAGER_JNDI_NAMES) {
@@ -81,6 +94,33 @@ public abstract class TransactionalJtaTransactionPolicy extends JtaTransactionPo
LOG.debug("No JTA TransactionManager found at JNDI location [{}]", jndiName, ex);
}
}
+ var loaders = Stream.of(Thread.currentThread().getContextClassLoader(), getClass().getClassLoader())
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(toList());
+ for (String method : METHODS) {
+ final int sep = method.lastIndexOf('.');
+ try {
+ Class<?> clazz = null;
+ for (final var loader : loaders) {
+ try {
+ clazz = loader.loadClass(method.substring(0, sep));
+ } catch (final NoClassDefFoundError | ClassNotFoundException cnfe) {
+ // continue
+ }
+ }
+ if (clazz != null) {
+ final var getter = clazz.getDeclaredMethod(method.substring(sep + 1));
+ getter.setAccessible(true);
+ final var txMgr = (TransactionManager) getter.invoke(null);
+ if (txMgr != null) {
+ return txMgr;
+ }
+ }
+ } catch (final RuntimeException | ReflectiveOperationException | NoClassDefFoundError t) {
+ // no-op
+ }
+ }
LOG.warn("Could not find the transaction manager through any of following locations: {}",
String.join(",", TRANSACTION_MANAGER_JNDI_NAMES));
return null;
diff --git a/components/camel-cdi-main/pom.xml b/components/camel-cdi-main/pom.xml
index ef49c25..d9f8742 100644
--- a/components/camel-cdi-main/pom.xml
+++ b/components/camel-cdi-main/pom.xml
@@ -49,16 +49,9 @@
</dependency>
<dependency>
- <groupId>org.apache.deltaspike.cdictrl</groupId>
- <artifactId>deltaspike-cdictrl-api</artifactId>
- <version>${deltaspike-version}</version>
- </dependency>
- <dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>${cdi-api-2.0-version}</version>
</dependency>
-
</dependencies>
-
</project>
diff --git a/components/camel-cdi-main/src/main/java/org/apache/camel/cdi/Main.java b/components/camel-cdi-main/src/main/java/org/apache/camel/cdi/Main.java
index aed8e28..bfb8b21 100644
--- a/components/camel-cdi-main/src/main/java/org/apache/camel/cdi/Main.java
+++ b/components/camel-cdi-main/src/main/java/org/apache/camel/cdi/Main.java
@@ -19,21 +19,23 @@ package org.apache.camel.cdi;
import java.util.Map;
import java.util.Set;
+import javax.enterprise.context.control.RequestContextController;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.UnsatisfiedResolutionException;
+import javax.enterprise.inject.se.SeContainer;
+import javax.enterprise.inject.se.SeContainerInitializer;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.main.MainCommandLineSupport;
-import org.apache.deltaspike.cdise.api.CdiContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
import static org.apache.camel.cdi.BeanManagerHelper.getReference;
-import static org.apache.deltaspike.cdise.api.CdiContainerLoader.getCdiContainer;
/**
* Camel CDI boot integration. Allows Camel and CDI to be booted up on the command line as a JVM process.
@@ -45,19 +47,27 @@ public class Main extends MainCommandLineSupport {
// Since version 2.3.0.Final and WELD-1915, Weld SE registers a shutdown hook that conflicts
// with Camel main support. See WELD-2051. The system property above is available starting
// Weld 2.3.1.Final to deactivate the registration of the shutdown hook.
- System.setProperty("org.jboss.weld.se.shutdownHook", String.valueOf(Boolean.FALSE));
+ System.setProperty(
+ "org.jboss.weld.se.shutdownHook",
+ System.getProperty("org.jboss.weld.se.shutdownHook", String.valueOf(Boolean.FALSE)));
}
private static final Logger LOG = LoggerFactory.getLogger(Main.class);
private static Main instance;
- private CdiContainer cdiContainer;
+ private boolean startContexts = true;
+ private SeContainer cdiContainer;
+ private Runnable stopHook;
public static void main(String... args) throws Exception {
Main main = new Main();
instance = main;
- main.run(args);
+ try {
+ main.run(args);
+ } finally {
+ instance = null; // ensure main can be reused even if unlikely
+ }
}
/**
@@ -69,6 +79,11 @@ public class Main extends MainCommandLineSupport {
return instance;
}
+ public Main setStartContexts(final boolean startContexts) {
+ this.startContexts = startContexts;
+ return this;
+ }
+
@Override
protected ProducerTemplate findOrCreateCamelTemplate() {
if (getCamelContext() == null) {
@@ -80,7 +95,7 @@ public class Main extends MainCommandLineSupport {
@Override
protected CamelContext createCamelContext() {
BeanManager manager = cdiContainer.getBeanManager();
- Map<String, CamelContext> camels = manager.getBeans(CamelContext.class, ANY).stream()
+ Map<String, CamelContext> camels = manager.getBeans(CamelContext.class, Any.Literal.INSTANCE).stream()
.map(bean -> getReference(manager, CamelContext.class, bean))
.collect(toMap(CamelContext::getName, identity()));
if (camels.size() > 1) {
@@ -94,11 +109,9 @@ public class Main extends MainCommandLineSupport {
@Override
protected void doStart() throws Exception {
- // TODO: Use standard CDI Java SE support when CDI 2.0 becomes a prerequisite
- CdiContainer container = getCdiContainer();
- container.boot();
- container.getContextControl().startContexts();
- cdiContainer = container;
+ final var container = SeContainerInitializer.newInstance();
+ cdiContainer = container.initialize();
+ startContexts();
super.doStart();
initCamelContext();
warnIfNoCamelFound();
@@ -109,9 +122,28 @@ public class Main extends MainCommandLineSupport {
// camel-cdi has already initialized and start CamelContext so we should not do this again
}
+ protected void startContexts() {
+ if (!startContexts) {
+ LOG.debug("Context are not automatically started");
+ return;
+ }
+ try {
+ final var requestContextController = cdiContainer.select(RequestContextController.class).get();
+ if (requestContextController.activate()) {
+ LOG.debug("Request context started");
+ stopHook = requestContextController::deactivate;
+ } else {
+ LOG.debug("Request context already started");
+ }
+ } catch (final UnsatisfiedResolutionException e) {
+ // ignore, start without starting the contexts, will not impact much camel normally
+ LOG.debug("Didn't start request scope", e);
+ }
+ }
+
private void warnIfNoCamelFound() {
BeanManager manager = cdiContainer.getBeanManager();
- Set<Bean<?>> contexts = manager.getBeans(CamelContext.class, ANY);
+ Set<Bean<?>> contexts = manager.getBeans(CamelContext.class, Any.Literal.INSTANCE);
// Warn if there is no CDI Camel contexts
if (contexts.isEmpty()) {
LOG.warn("Camel CDI main has started with no Camel context!");
@@ -121,8 +153,11 @@ public class Main extends MainCommandLineSupport {
@Override
protected void doStop() throws Exception {
super.doStop();
+ if (stopHook != null) {
+ stopHook.run();
+ }
if (cdiContainer != null) {
- cdiContainer.shutdown();
+ cdiContainer.close();
}
}
}
diff --git a/components/camel-cdi/pom.xml b/components/camel-cdi/pom.xml
index d9722d3..8afad4d 100644
--- a/components/camel-cdi/pom.xml
+++ b/components/camel-cdi/pom.xml
@@ -73,7 +73,15 @@
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
+ <artifactId>camel-jta</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
<artifactId>camel-mock</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
</dependency>
<!-- deprecated xml -->
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextProducer.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextProducer.java
index 553a68d..68b1958 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextProducer.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextProducer.java
@@ -20,6 +20,8 @@ import java.lang.annotation.Annotation;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Default;
import javax.enterprise.inject.InjectionException;
import javax.enterprise.inject.Vetoed;
import javax.enterprise.inject.spi.Annotated;
@@ -41,11 +43,9 @@ import org.slf4j.LoggerFactory;
import static java.beans.Introspector.decapitalize;
import static java.util.stream.Collectors.toSet;
import static org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
import static org.apache.camel.cdi.CdiSpiHelper.createCamelContextWithTCCL;
import static org.apache.camel.cdi.CdiSpiHelper.getRawType;
import static org.apache.camel.cdi.CdiSpiHelper.isAnnotationType;
-import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
@Vetoed
final class CamelContextProducer<T extends CamelContext> extends DelegateProducer<T> {
@@ -90,9 +90,9 @@ final class CamelContextProducer<T extends CamelContext> extends DelegateProduce
.filter(isAnnotationType(Named.class).negate()
.and(q -> manager.isQualifier(q.annotationType())))
.collect(toSet());
- qualifiers.add(ANY);
+ qualifiers.add(Any.Literal.INSTANCE);
if (qualifiers.size() == 1) {
- qualifiers.add(DEFAULT);
+ qualifiers.add(Default.Literal.INSTANCE);
}
qualifiers.retainAll(extension.getObserverEvents());
if (!qualifiers.isEmpty()) {
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelBeanRepository.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelBeanRepository.java
index cac01f5..8fc7cc0 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelBeanRepository.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelBeanRepository.java
@@ -19,6 +19,7 @@ package org.apache.camel.cdi;
import java.util.Map;
import java.util.Set;
+import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
@@ -28,7 +29,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.stream.Collectors.toMap;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
import static org.apache.camel.cdi.BeanManagerHelper.getReference;
import static org.apache.camel.cdi.BeanManagerHelper.getReferenceByName;
import static org.apache.camel.cdi.BeanManagerHelper.getReferencesByType;
@@ -72,7 +72,7 @@ final class CdiCamelBeanRepository implements BeanRepository {
public <T> Map<String, T> findByTypeWithName(Class<T> type) {
notNull(type, "type");
logger.trace("Looking up named beans of type [{}]", type);
- return manager.getBeans(type, ANY).stream()
+ return manager.getBeans(type, Any.Literal.INSTANCE).stream()
.filter(bean -> bean.getName() != null)
.collect(toMap(Bean::getName, bean -> getReference(manager, type, bean)));
}
@@ -81,7 +81,7 @@ final class CdiCamelBeanRepository implements BeanRepository {
public <T> Set<T> findByType(Class<T> type) {
notNull(type, "type");
logger.trace("Looking up beans of type [{}]", type);
- return getReferencesByType(manager, type, ANY);
+ return getReferencesByType(manager, type, Any.Literal.INSTANCE);
}
}
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
index f766053..af84376 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
@@ -26,11 +26,15 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
import java.util.stream.Stream;
+import javax.enterprise.context.Dependent;
import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.InjectionException;
+import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
@@ -47,6 +51,7 @@ import javax.enterprise.inject.spi.ProcessObserverMethod;
import javax.enterprise.inject.spi.ProcessProducer;
import javax.enterprise.inject.spi.ProcessProducerField;
import javax.enterprise.inject.spi.ProcessProducerMethod;
+import javax.enterprise.inject.spi.configurator.BeanConfigurator;
import javax.inject.Named;
import org.apache.camel.BeanInject;
@@ -72,22 +77,23 @@ import org.apache.camel.spi.CamelEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static java.lang.ClassLoader.getSystemClassLoader;
import static java.util.Collections.newSetFromMap;
import static java.util.function.Predicate.isEqual;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toSet;
import static java.util.stream.Stream.concat;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
import static org.apache.camel.cdi.ApplicationScopedLiteral.APPLICATION_SCOPED;
import static org.apache.camel.cdi.BeanManagerHelper.getReference;
import static org.apache.camel.cdi.BeanManagerHelper.getReferencesByType;
+import static org.apache.camel.cdi.CdiCamelFactory.getQualifierByType;
+import static org.apache.camel.cdi.CdiCamelFactory.selectContext;
import static org.apache.camel.cdi.CdiEventEndpoint.eventEndpointUri;
import static org.apache.camel.cdi.CdiSpiHelper.getQualifiers;
import static org.apache.camel.cdi.CdiSpiHelper.getRawType;
import static org.apache.camel.cdi.CdiSpiHelper.hasAnnotation;
import static org.apache.camel.cdi.CdiSpiHelper.hasType;
import static org.apache.camel.cdi.CdiSpiHelper.isAnnotationType;
-import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
import static org.apache.camel.cdi.Excluded.EXCLUDED;
import static org.apache.camel.cdi.ResourceHelper.getResource;
import static org.apache.camel.cdi.Startup.Literal.STARTUP;
@@ -210,10 +216,10 @@ public class CdiCamelExtension implements Extension {
if (type instanceof Class && CamelEvent.class.isAssignableFrom(Class.class.cast(type))) {
Set<Annotation> qualifiers = pom.getObserverMethod().getObservedQualifiers();
if (qualifiers.isEmpty()) {
- eventQualifiers.add(ANY);
+ eventQualifiers.add(Any.Literal.INSTANCE);
} else if (qualifiers.size() == 1 && qualifiers.stream()
.anyMatch(isAnnotationType(Named.class))) {
- eventQualifiers.add(DEFAULT);
+ eventQualifiers.add(Default.Literal.INSTANCE);
} else {
eventQualifiers.addAll(qualifiers);
}
@@ -283,14 +289,15 @@ public class CdiCamelExtension implements Extension {
if (contexts.isEmpty() && shouldDeployDefaultCamelContext(allBeans)) {
// Add @Default Camel context bean if any
- extraBeans.add(camelContextBean(manager, null, ANY, DEFAULT, APPLICATION_SCOPED));
+ extraBeans.add(camelContextBean(
+ manager, null, Any.Literal.INSTANCE, Default.Literal.INSTANCE, APPLICATION_SCOPED));
} else if (contexts.size() == 1) {
// Add the @Default qualifier if there is only one Camel context bean
Bean<?> context = contexts.iterator().next();
- if (!context.getQualifiers().contains(DEFAULT)) {
+ if (!context.getQualifiers().contains(Default.Literal.INSTANCE)) {
// Only decorate if that's a programmatic bean
if (context instanceof SyntheticBean) {
- ((SyntheticBean<?>) context).addQualifier(DEFAULT);
+ ((SyntheticBean<?>) context).addQualifier(Default.Literal.INSTANCE);
}
}
}
@@ -316,12 +323,71 @@ public class CdiCamelExtension implements Extension {
: templateQualifiers))
.forEach(abd::addBean);
+ // optional mock support if camel-mock is there
+ try {
+ var loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = getClass().getClassLoader();
+ if (loader == null) {
+ loader = getSystemClassLoader();
+ }
+ }
+ final Class<? extends Endpoint> endpointType = loader
+ .loadClass("org.apache.camel.component.mock.MockEndpoint")
+ .asSubclass(Endpoint.class);
+ addCamelMockBeans(abd, endpointType, templateQualifiers);
+ } catch (final ClassNotFoundException | NoClassDefFoundError e) {
+ // not needed
+ }
+
// Add CDI event endpoint observer methods
cdiEventEndpoints.values().stream()
.map(ForwardingObserverMethod::new)
.forEach(abd::addObserverMethod);
}
+ private <T extends Endpoint> void addCamelMockBeans(
+ final AfterBeanDiscovery afterBeanDiscovery, final Class<T> type,
+ final Set<Annotation> templateQualifiers) {
+ addBean(afterBeanDiscovery, type)
+ .id(getClass().getName() + "#mockEndpoint")
+ .qualifiers(Default.Literal.INSTANCE, Uri.Literal.of(""), Any.Literal.INSTANCE)
+ .addQualifiers(templateQualifiers)
+ .produceWith(instance -> newEndpoint(type, instance, ip -> getQualifierByType(ip, Uri.class)
+ .map(Uri::value)
+ .orElseGet(() -> "mock:" + ip.getMember().getName())));
+ }
+
+ private <T extends Endpoint> BeanConfigurator<T> addBean(
+ final AfterBeanDiscovery afterBeanDiscovery, final Class<T> type) {
+ return afterBeanDiscovery
+ .<T> addBean()
+ .scope(Dependent.class)
+ .beanClass(type)
+ .types(type, Object.class);
+ }
+
+ private <T extends Endpoint> T newEndpoint(
+ final Class<T> type,
+ final Instance<Object> instance,
+ final Function<InjectionPoint, String> uriFactory) {
+ final var ip = instance.select(InjectionPoint.class).get();
+ final var contexts = instance.select(CamelContext.class, Any.Literal.INSTANCE);
+ return lookupEndpoint(type, ip, contexts, uriFactory.apply(ip));
+ }
+
+ private <T extends Endpoint> T lookupEndpoint(
+ final Class<T> type,
+ final InjectionPoint ip,
+ final Instance<CamelContext> contexts,
+ final String uri) {
+ try {
+ return selectContext(ip, contexts, this).getEndpoint(uri, type);
+ } catch (Exception cause) {
+ throw new InjectionException("Error injecting mock endpoint into " + ip, cause);
+ }
+ }
+
private boolean shouldDeployDefaultCamelContext(Set<Bean<?>> beans) {
return beans.stream()
// Is there a Camel bean with the @Default qualifier?
@@ -331,7 +397,7 @@ public class CdiCamelExtension implements Extension {
.or(hasType(RouteContainer.class).or(hasType(RoutesBuilder.class))))
.map(Bean::getQualifiers)
.flatMap(Set::stream)
- .anyMatch(isEqual(DEFAULT))
+ .anyMatch(isEqual(Default.Literal.INSTANCE))
// Or a bean with Camel annotations?
|| concat(camelBeans.stream().map(AnnotatedType::getFields),
camelBeans.stream().map(AnnotatedType::getMethods))
@@ -352,7 +418,7 @@ public class CdiCamelExtension implements Extension {
.filter(ip -> getRawType(ip.getType()).getName().startsWith("org.apache.camel"))
.map(InjectionPoint::getQualifiers)
.flatMap(Set::stream)
- .anyMatch(isAnnotationType(Uri.class).or(isEqual(DEFAULT)));
+ .anyMatch(isAnnotationType(Uri.class).or(isEqual(Default.Literal.INSTANCE)));
}
private SyntheticBean<?> camelContextBean(BeanManager manager, Class<?> beanClass, Annotation... qualifiers) {
@@ -372,7 +438,7 @@ public class CdiCamelExtension implements Extension {
configuration.unmodifiable();
Collection<CamelContext> contexts = new ArrayList<>();
- for (Bean<?> context : manager.getBeans(CamelContext.class, ANY)) {
+ for (Bean<?> context : manager.getBeans(CamelContext.class, Any.Literal.INSTANCE)) {
contexts.add(getReference(manager, CamelContext.class, context));
}
@@ -387,9 +453,9 @@ public class CdiCamelExtension implements Extension {
// Add routes to Camel contexts
if (configuration.autoConfigureRoutes()) {
boolean deploymentException = false;
- Set<Bean<?>> routes = new HashSet<>(manager.getBeans(RoutesBuilder.class, ANY));
- routes.addAll(manager.getBeans(RouteContainer.class, ANY));
- for (Bean<?> context : manager.getBeans(CamelContext.class, ANY)) {
+ Set<Bean<?>> routes = new HashSet<>(manager.getBeans(RoutesBuilder.class, Any.Literal.INSTANCE));
+ routes.addAll(manager.getBeans(RouteContainer.class, Any.Literal.INSTANCE));
+ for (Bean<?> context : manager.getBeans(CamelContext.class, Any.Literal.INSTANCE)) {
for (Bean<?> route : routes) {
Set<Annotation> qualifiers = new HashSet<>(context.getQualifiers());
qualifiers.retainAll(route.getQualifiers());
@@ -408,8 +474,8 @@ public class CdiCamelExtension implements Extension {
// the initialization of normal-scoped beans).
// FIXME: This does not work with OpenWebBeans for bean whose bean type is an
// interface as the Object methods does not get forwarded to the bean instances!
- eagerBeans.forEach(type -> getReferencesByType(manager, type.getJavaClass(), ANY).toString());
- manager.getBeans(Object.class, ANY, STARTUP)
+ eagerBeans.forEach(type -> getReferencesByType(manager, type.getJavaClass(), Any.Literal.INSTANCE).toString());
+ manager.getBeans(Object.class, Any.Literal.INSTANCE, STARTUP)
.forEach(bean -> getReference(manager, bean.getBeanClass(), bean).toString());
// Start Camel contexts
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java
index c4cf75f..1abad39 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java
@@ -29,7 +29,6 @@ import javax.enterprise.inject.Default;
import javax.enterprise.inject.InjectionException;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.Typed;
import javax.enterprise.inject.spi.InjectionPoint;
import org.apache.camel.CamelContext;
@@ -38,13 +37,14 @@ import org.apache.camel.Endpoint;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.TypeConverter;
-import org.apache.camel.component.mock.MockEndpoint;
import static org.apache.camel.cdi.CdiEventEndpoint.eventEndpointUri;
import static org.apache.camel.cdi.CdiSpiHelper.isAnnotationType;
-import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
-final class CdiCamelFactory {
+class CdiCamelFactory {
+ protected CdiCamelFactory() {
+ // no-op
+ }
@Produces
private static TypeConverter typeConverter(
@@ -128,37 +128,6 @@ final class CdiCamelFactory {
}
}
- @Produces
- @Typed(MockEndpoint.class)
- // Qualifiers are dynamically added in CdiCamelExtension
- private static MockEndpoint mockEndpointFromMember(
- InjectionPoint ip, @Any Instance<CamelContext> instance, CdiCamelExtension extension) {
- String uri = "mock:" + ip.getMember().getName();
- try {
- return selectContext(ip, instance, extension).getEndpoint(uri, MockEndpoint.class);
- } catch (Exception cause) {
- throw new InjectionException("Error injecting mock endpoint into " + ip, cause);
- }
- }
-
- @Uri("")
- @Produces
- @Typed(MockEndpoint.class)
- // Qualifiers are dynamically added in CdiCamelExtension
- private static MockEndpoint mockEndpointFromUri(
- InjectionPoint ip, @Any Instance<CamelContext> instance, CdiCamelExtension extension) {
- Uri uri = getQualifierByType(ip, Uri.class).get();
- try {
- CamelContext context = selectContext(ip, instance, extension);
- return context.getEndpoint(uri.value(), MockEndpoint.class);
- } catch (Exception cause) {
- throw new InjectionException(
- "Error injecting mock endpoint annotated with " + uri
- + " into " + ip,
- cause);
- }
- }
-
@Uri("")
@Produces
// Qualifiers are dynamically added in CdiCamelExtension
@@ -190,17 +159,16 @@ final class CdiCamelFactory {
return context.getEndpoint(uri, CdiEventEndpoint.class);
}
- private static <
- T extends CamelContext> T selectContext(InjectionPoint ip, Instance<T> instance, CdiCamelExtension extension) {
+ static CamelContext selectContext(InjectionPoint ip, Instance<CamelContext> instance, CdiCamelExtension extension) {
Collection<Annotation> qualifiers = new HashSet<>(ip.getQualifiers());
qualifiers.retainAll(extension.getContextQualifiers());
- if (qualifiers.isEmpty() && !instance.select(DEFAULT).isUnsatisfied()) {
- return instance.select(DEFAULT).get();
+ if (qualifiers.isEmpty() && !instance.select(Default.Literal.INSTANCE).isUnsatisfied()) {
+ return instance.select(Default.Literal.INSTANCE).get();
}
return instance.select(qualifiers.toArray(new Annotation[0])).get();
}
- private static <T extends Annotation> Optional<T> getQualifierByType(InjectionPoint ip, Class<T> type) {
+ static <T extends Annotation> Optional<T> getQualifierByType(InjectionPoint ip, Class<T> type) {
return ip.getQualifiers().stream()
.filter(isAnnotationType(type))
.findAny()
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
index cda4e85..0ebaf86 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
@@ -34,6 +34,8 @@ import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Default;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedField;
@@ -53,8 +55,6 @@ import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
-import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
@Vetoed
final class CdiSpiHelper {
@@ -132,9 +132,9 @@ final class CdiSpiHelper {
.collect(collectingAndThen(toSet(),
qualifiers -> {
if (qualifiers.isEmpty()) {
- qualifiers.add(DEFAULT);
+ qualifiers.add(Default.Literal.INSTANCE);
}
- qualifiers.add(ANY);
+ qualifiers.add(Any.Literal.INSTANCE);
return qualifiers;
}));
}
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
index d49e3a6..7c7564d 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
@@ -24,6 +24,9 @@ import java.lang.annotation.Target;
import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Qualifier;
+/**
+ * Can be replaced by an observer: {@code void onStart(@Observes @Initialized(ApplicationScoped) Object start)}.
+ */
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/Uri.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Uri.java
index c38b459..9cb5494 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/Uri.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Uri.java
@@ -71,6 +71,5 @@ public @interface Uri {
public String value() {
return uri;
}
-
}
}
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
index 4c7c515..705429e 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
@@ -25,7 +25,9 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+import javax.enterprise.inject.Any;
import javax.enterprise.inject.CreationException;
+import javax.enterprise.inject.Default;
import javax.enterprise.inject.Vetoed;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
@@ -59,10 +61,8 @@ import static java.lang.String.format;
import static java.util.Collections.*;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toSet;
-import static org.apache.camel.cdi.AnyLiteral.ANY;
import static org.apache.camel.cdi.ApplicationScopedLiteral.APPLICATION_SCOPED;
import static org.apache.camel.cdi.CdiSpiHelper.createCamelContextWithTCCL;
-import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
import static org.apache.camel.cdi.ResourceHelper.getResource;
import static org.apache.camel.util.ObjectHelper.isNotEmpty;
@@ -163,11 +163,11 @@ final class XmlCdiBeanFactory {
private SyntheticBean<?> camelContextBean(CamelContextFactoryBean factory, URL url, AnnotatedType annotatedType) {
Set<Annotation> annotations = new HashSet<>();
- annotations.add(ANY);
+ annotations.add(Any.Literal.INSTANCE);
if (hasId(factory)) {
addAll(annotations, NamedLiteral.of(factory.getId()));
} else {
- annotations.add(DEFAULT);
+ annotations.add(Default.Literal.INSTANCE);
factory.setImplicitId(true);
factory.setId(new CdiCamelContextNameStrategy().getNextName());
}
@@ -245,8 +245,8 @@ final class XmlCdiBeanFactory {
}
Set<Annotation> annotations = new HashSet<>();
- annotations.add(ANY);
- annotations.add(hasId(factory) ? NamedLiteral.of(factory.getId()) : DEFAULT);
+ annotations.add(Any.Literal.INSTANCE);
+ annotations.add(hasId(factory) ? NamedLiteral.of(factory.getId()) : Default.Literal.INSTANCE);
// TODO: should that be @Singleton to enable injection points with bean instance type?
if (factory.isSingleton()) {
@@ -277,7 +277,7 @@ final class XmlCdiBeanFactory {
List.class,
Stream.of(List.class, new ListParameterizedType(RestDefinition.class))
.collect(toSet()),
- ANY, NamedLiteral.of(definition.getId())),
+ Any.Literal.INSTANCE, NamedLiteral.of(definition.getId())),
List.class,
new SyntheticInjectionTarget<>(definition::getRests), bean -> "imported rest context with "
+ "id [" + definition.getId() + "] "
@@ -296,7 +296,7 @@ final class XmlCdiBeanFactory {
List.class,
Stream.of(List.class, new ListParameterizedType(RouteTemplateDefinition.class))
.collect(toSet()),
- ANY, NamedLiteral.of(definition.getId())),
+ Any.Literal.INSTANCE, NamedLiteral.of(definition.getId())),
List.class,
new SyntheticInjectionTarget<>(definition::getRouteTemplates), bean -> "imported route template context with "
+ "id [" + definition.getId() + "] "
@@ -316,7 +316,7 @@ final class XmlCdiBeanFactory {
List.class,
Stream.of(List.class, new ListParameterizedType(RouteConfigurationDefinition.class))
.collect(toSet()),
- ANY, NamedLiteral.of(definition.getId())),
+ Any.Literal.INSTANCE, NamedLiteral.of(definition.getId())),
List.class,
new SyntheticInjectionTarget<>(definition::getRouteConfigurations),
bean -> "imported route configuration context with "
@@ -337,7 +337,7 @@ final class XmlCdiBeanFactory {
List.class,
Stream.of(List.class, new ListParameterizedType(RouteDefinition.class))
.collect(toSet()),
- ANY, NamedLiteral.of(definition.getId())),
+ Any.Literal.INSTANCE, NamedLiteral.of(definition.getId())),
List.class,
new SyntheticInjectionTarget<>(definition::getRoutes), bean -> "imported route context with "
+ "id [" + definition.getId() + "] "
@@ -352,7 +352,7 @@ final class XmlCdiBeanFactory {
new SyntheticAnnotated(
RoutesDefinition.class,
manager.createAnnotatedType(RoutesDefinition.class).getTypeClosure(),
- ANY, DEFAULT),
+ Any.Literal.INSTANCE, Default.Literal.INSTANCE),
RoutesDefinition.class,
new SyntheticInjectionTarget<>(() -> definition), bean -> "imported routes definition "
+ (hasId(definition)
@@ -438,7 +438,7 @@ final class XmlCdiBeanFactory {
new SyntheticAnnotated(
clazz,
manager.createAnnotatedType(clazz).getTypeClosure(),
- ANY, NamedLiteral.of(definition.getId())),
+ Any.Literal.INSTANCE, NamedLiteral.of(definition.getId())),
clazz, bean -> "imported error handler with "
+ "id [" + definition.getId() + "] "
+ "from resource [" + url + "] "
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/AnyLiteral.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiJtaTransactionErrorHandlerBuilder.java
similarity index 71%
rename from components/camel-cdi/src/main/java/org/apache/camel/cdi/AnyLiteral.java
rename to components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiJtaTransactionErrorHandlerBuilder.java
index 2e0d6d3..6b0e7e2 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/AnyLiteral.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiJtaTransactionErrorHandlerBuilder.java
@@ -14,18 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.cdi;
+package org.apache.camel.cdi.transaction;
-import javax.enterprise.inject.Any;
-import javax.enterprise.util.AnnotationLiteral;
+import org.apache.camel.jta.JtaTransactionErrorHandlerBuilder;
-@Vetoed
-final class AnyLiteral extends AnnotationLiteral<Any> implements Any {
-
- static final Any ANY = new AnyLiteral();
-
- private static final long serialVersionUID = 1L;
-
- private AnyLiteral() {
- }
+public class CdiJtaTransactionErrorHandlerBuilder extends JtaTransactionErrorHandlerBuilder
+ implements CdiTransactionalErrorHandlerBuilder {
}
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/DefaultLiteral.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiTransactionalErrorHandlerBuilder.java
similarity index 55%
rename from components/camel-cdi/src/main/java/org/apache/camel/cdi/DefaultLiteral.java
rename to components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiTransactionalErrorHandlerBuilder.java
index e701a89..5b8a8ee 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/DefaultLiteral.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/CdiTransactionalErrorHandlerBuilder.java
@@ -14,18 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.cdi;
+package org.apache.camel.cdi.transaction;
-import javax.enterprise.inject.Default;
-import javax.enterprise.util.AnnotationLiteral;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.jta.JtaTransactionErrorHandlerBuilder;
+import org.apache.camel.jta.JtaTransactionPolicy;
-@Vetoed
-final class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
+public interface CdiTransactionalErrorHandlerBuilder {
+ String getPolicyRef();
- static final Default DEFAULT = new DefaultLiteral();
+ JtaTransactionErrorHandlerBuilder setTransactionPolicy(String ref);
- private static final long serialVersionUID = 1L;
+ JtaTransactionPolicy getTransactionPolicy();
- private DefaultLiteral() {
- }
+ JtaTransactionErrorHandlerBuilder setTransactionPolicy(JtaTransactionPolicy transactionPolicy);
+
+ LoggingLevel getRollbackLoggingLevel();
+
+ JtaTransactionErrorHandlerBuilder setRollbackLoggingLevel(LoggingLevel rollbackLoggingLevel);
}