This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit d99c53bf6ebe6d2e07265d5d211c0891dc4041d1 Author: JB Onofré <[email protected]> AuthorDate: Tue Jun 6 17:57:39 2023 +0200 Re-add camel-activemq component using activemq-client-jakarta with JMS 2.x support. --- components/camel-activemq/pom.xml | 58 +++++ .../src/main/docs/activemq-component.adoc | 89 +++++++ .../component/activemq/ActiveMQComponent.java | 283 +++++++++++++++++++++ .../component/activemq/ActiveMQConfiguration.java | 220 ++++++++++++++++ .../camel/component/activemq/ActiveMQEndpoint.java | 73 ++++++ .../component/activemq/ActiveMQQueueEndpoint.java | 101 ++++++++ .../activemq/ActiveMQSendDynamicAware.java | 25 ++ .../activemq/ActiveMQTemporaryQueueEndpoint.java | 39 +++ .../activemq/ActiveMQTemporaryTopicEndpoint.java | 33 +++ .../OriginalDestinationPropagateStrategy.java | 56 ++++ .../activemq/converter/ActiveMQConverter.java | 38 +++ .../converter/ActiveMQMessageConverter.java | 97 +++++++ .../component/activemq/converter/package.html | 30 +++ .../apache/camel/component/activemq/package.html | 31 +++ .../src/test/resources/log4j2-test.properties | 28 ++ components/pom.xml | 1 + parent/pom.xml | 1 + 17 files changed, 1203 insertions(+) diff --git a/components/camel-activemq/pom.xml b/components/camel-activemq/pom.xml new file mode 100644 index 00000000000..43c3654bd57 --- /dev/null +++ b/components/camel-activemq/pom.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel</groupId> + <artifactId>components</artifactId> + <version>4.0.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-activemq</artifactId> + <packaging>jar</packaging> + + <name>Camel :: ActiveMQ</name> + <description>ActiveMQ component for Camel</description> + + <properties> + <camel.surefire.parallel>true</camel.surefire.parallel> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-jms</artifactId> + </dependency> + <dependency> + <groupId>org.apache.activemq</groupId> + <artifactId>activemq-client-jakarta</artifactId> + <version>${activemq-version}</version> + </dependency> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-junit5</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project> \ No newline at end of file diff --git a/components/camel-activemq/src/main/docs/activemq-component.adoc b/components/camel-activemq/src/main/docs/activemq-component.adoc new file mode 100644 index 00000000000..fbf591dbc65 --- /dev/null +++ b/components/camel-activemq/src/main/docs/activemq-component.adoc @@ -0,0 +1,89 @@ += ActiveMQ Component +:doctitle: ActiveMQ +:shortname: activemq +:artifactid: camel-activemq +:description: Send messages to (or consume from) Apache ActiveMQ. This component extends the Camel JMS component. +:since: 1.0 +:supportlevel: Stable +:component-header: Both producer and consumer are supported +//Manually maintained attributes +:camel-spring-boot-name: activemq + +*Since Camel {since}* + +*{component-header}* + +The ActiveMQ component is an extension to the JMS component and has been pre-configured for using Apache ActiveMQ 5.x (not Artemis). +Users of Apache ActiveMQ Artemis should use the JMS component. + +[TIP] +==== +*More documentation* + +See the JMS component for more documentation and examples +==== + +Maven users will need to add the following dependency to their `pom.xml` +for this component: + +[source,xml] +------------------------------------------------------------ +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-activemq</artifactId> + <version>x.x.x</version> + <!-- use the same version as your Camel core version --> +</dependency> +------------------------------------------------------------ + +== URI format + +-------------------------------------------- +activemq:[queue:|topic:]destinationName[?options] +-------------------------------------------- + +Where `destinationName` is a JMS queue or topic name. By default, the +`destinationName` is interpreted as a queue name. For example, to +connect to the queue, `foo` use: + +----------- +activemq:foo +----------- + +// component-configure options: START + +// component-configure options: END + +// component options: START +include::partial$component-configure-options.adoc[] +include::partial$component-endpoint-options.adoc[] +// component options: END + +// endpoint options: START + +// endpoint options: END + +== Examples + +You'll need to provide a connectionFactory to the ActiveMQ Component, to have the following examples working. + +=== Producer Example + +[source,java] +-------------------------------------------------------------------------------- +from("timer:mytimer?period=5000") + .setBody(constant("HELLO from Camel!")) + .to("activemq:queue:HELLO.WORLD"); +-------------------------------------------------------------------------------- + +=== Consumer Example + +[source,java] +-------------------------------------------------------------------------------- +from("activemq:queue:HELLO.WORLD") + .log("Received a message - ${body}"); +-------------------------------------------------------------------------------- + + + +include::spring-boot:partial$starter.adoc[] \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQComponent.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQComponent.java new file mode 100644 index 00000000000..996b20a8886 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQComponent.java @@ -0,0 +1,283 @@ +/* + * 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.component.activemq; + +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.activemq.Service; +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsConfiguration; +import org.apache.camel.component.jms.JmsEndpoint; +import org.apache.camel.component.jms.QueueBrowseStrategy; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.annotations.Component; +import org.apache.camel.support.component.PropertyConfigurerSupport; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.PropertiesHelper; +import org.apache.camel.util.URISupport; +import org.springframework.jms.connection.SingleConnectionFactory; +import org.springframework.jms.core.JmsTemplate; + +/** + * The ActiveMQ Component. + */ +@Component("activemq") +public class ActiveMQComponent extends JmsComponent { + private final CopyOnWriteArrayList<SingleConnectionFactory> singleConnectionFactoryList = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList<Service> pooledConnectionFactoryServiceList = new CopyOnWriteArrayList<>(); + + public ActiveMQComponent() { + } + + public ActiveMQComponent(CamelContext context) { + super(context); + } + + public ActiveMQComponent(ActiveMQConfiguration configuration) { + setConfiguration(configuration); + } + + /** + * Creates an <a href="http://camel.apache.org/activemq.html">ActiveMQ Component</a> + * + * @return the created component + */ + public static ActiveMQComponent activeMQComponent() { + return new ActiveMQComponent(); + } + + /** + * Creates an <a href="http://camel.apache.org/activemq.html">ActiveMQ Component</a> connecting to the given + * <a href="http://activemq.apache.org/configuring-transports.html">broker URL</a> + * + * @param brokerURL the URL to connect to + * @return the created component + */ + public static ActiveMQComponent activeMQComponent(String brokerURL) { + ActiveMQComponent answer = new ActiveMQComponent(); + if (answer.getConfiguration() instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) answer.getConfiguration()).setBrokerURL(brokerURL); + } + + return answer; + } + + public String getBrokerURL() { + if (getConfiguration() instanceof ActiveMQConfiguration) { + return ((ActiveMQConfiguration) getConfiguration()).getBrokerURL(); + } + return null; + } + + /** + * Sets the broker URL to use to connect to ActiveMQ. If none configured then localhost:61616 is used by default + * (however can be overridden by configuration from environment variables) + */ + @Metadata(label = "common") + public void setBrokerURL(String brokerURL) { + if (getConfiguration() instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) getConfiguration()).setBrokerURL(brokerURL); + } + } + + /** + * Define if all Java packages are trusted or not (for Java object JMS message types). Notice its not recommended + * practice to send Java serialized objects over network. Setting this to true can expose security risks, so use + * this with care. + */ + @Metadata(defaultValue = "false", label = "advanced") + public void setTrustAllPackages(boolean trustAllPackages) { + if (getConfiguration() instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) getConfiguration()).setTrustAllPackages(trustAllPackages); + } + } + + public boolean isTrustAllPackages() { + if (getConfiguration() instanceof ActiveMQConfiguration) { + return ((ActiveMQConfiguration) getConfiguration()).isTrustAllPackages(); + } + return false; + } + + /** + * Enables or disables whether a PooledConnectionFactory will be used so that when messages are sent to ActiveMQ + * from outside of a message consuming thread, pooling will be used rather than the default with the Spring + * {@link JmsTemplate} which will create a new connection, session, producer for each message then close them all + * down again. + * <p/> + * The default value is true. + */ + @Metadata(defaultValue = "true", label = "common") + public void setUsePooledConnection(boolean usePooledConnection) { + if (getConfiguration() instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) getConfiguration()).setUsePooledConnection(usePooledConnection); + } + } + + public boolean isUsePooledConnection() { + if (getConfiguration() instanceof ActiveMQConfiguration) { + return ((ActiveMQConfiguration) getConfiguration()).isUsePooledConnection(); + } + return true; + } + + /** + * Enables or disables whether a Spring {@link SingleConnectionFactory} will be used so that when messages are sent + * to ActiveMQ from outside of a message consuming thread, pooling will be used rather than the default with the + * Spring {@link JmsTemplate} which will create a new connection, session, producer for each message then close them + * all down again. + * <p/> + * The default value is false and a pooled connection is used by default. + */ + @Metadata(defaultValue = "false", label = "common") + public void setUseSingleConnection(boolean useSingleConnection) { + if (getConfiguration() instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) getConfiguration()).setUseSingleConnection(useSingleConnection); + } + } + + public boolean isUseSingleConnection() { + if (getConfiguration() instanceof ActiveMQConfiguration) { + return ((ActiveMQConfiguration) getConfiguration()).isUseSingleConnection(); + } + return false; + } + + @Override + protected void setProperties(Endpoint bean, Map<String, Object> parameters) throws Exception { + Object useSingleConnection = parameters.remove("useSingleConnection"); + if (useSingleConnection != null) { + ((ActiveMQConfiguration) ((JmsEndpoint) bean).getConfiguration()) + .setUseSingleConnection( + PropertyConfigurerSupport.property(getCamelContext(), boolean.class, useSingleConnection)); + } + Object usePooledConnection = parameters.remove("usePooledConnection"); + if (usePooledConnection != null) { + ((ActiveMQConfiguration) ((JmsEndpoint) bean).getConfiguration()) + .setUsePooledConnection( + PropertyConfigurerSupport.property(getCamelContext(), boolean.class, usePooledConnection)); + } + super.setProperties(bean, parameters); + } + + protected void addPooledConnectionFactoryService(Service pooledConnectionFactoryService) { + pooledConnectionFactoryServiceList.add(pooledConnectionFactoryService); + } + + protected void addSingleConnectionFactory(SingleConnectionFactory singleConnectionFactory) { + singleConnectionFactoryList.add(singleConnectionFactory); + } + + @Override + @SuppressWarnings("unchecked") + protected String convertPathToActualDestination(String path, Map<String, Object> parameters) { + // support ActiveMQ destination options using the destination. prefix + // http://activemq.apache.org/destination-options.html + Map options = PropertiesHelper.extractProperties(parameters, "destination."); + + String query = URISupport.createQueryString(options); + + // if we have destination options then append them to the destination + // name + if (ObjectHelper.isNotEmpty(query)) { + return path + "?" + query; + } else { + return path; + } + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + + // use OriginalDestinationPropagateStrategy by default if no custom + // strategy has been set + if (getMessageCreatedStrategy() == null) { + setMessageCreatedStrategy(new OriginalDestinationPropagateStrategy()); + } + } + + @Override + protected void doStop() throws Exception { + for (Service s : pooledConnectionFactoryServiceList) { + try { + s.stop(); + } catch (Exception e) { + // ignore + } + } + pooledConnectionFactoryServiceList.clear(); + + for (SingleConnectionFactory s : singleConnectionFactoryList) { + try { + s.destroy(); + } catch (Exception e) { + // ignore + } + } + singleConnectionFactoryList.clear(); + + super.doStop(); + } + + /** + * Configuration of ActiveMQ + */ + @Override + public void setConfiguration(JmsConfiguration configuration) { + if (configuration instanceof ActiveMQConfiguration) { + ((ActiveMQConfiguration) configuration).setActiveMQComponent(this); + } + super.setConfiguration(configuration); + } + + @Override + protected JmsConfiguration createConfiguration() { + ActiveMQConfiguration answer = new ActiveMQConfiguration(); + answer.setActiveMQComponent(this); + return answer; + } + + @Override + protected JmsEndpoint createTemporaryTopicEndpoint( + String uri, JmsComponent component, String subject, JmsConfiguration configuration) { + return new ActiveMQTemporaryTopicEndpoint(uri, component, subject, configuration); + } + + @Override + protected JmsEndpoint createTopicEndpoint( + String uri, JmsComponent component, String subject, JmsConfiguration configuration) { + return new ActiveMQEndpoint(uri, component, subject, true, configuration); + } + + @Override + protected JmsEndpoint createTemporaryQueueEndpoint( + String uri, JmsComponent component, String subject, JmsConfiguration configuration, + QueueBrowseStrategy queueBrowseStrategy) { + return new ActiveMQTemporaryQueueEndpoint(uri, component, subject, configuration, queueBrowseStrategy); + } + + @Override + protected JmsEndpoint createQueueEndpoint( + String uri, JmsComponent component, String subject, JmsConfiguration configuration, + QueueBrowseStrategy queueBrowseStrategy) { + return new ActiveMQQueueEndpoint(uri, component, subject, configuration, queueBrowseStrategy); + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQConfiguration.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQConfiguration.java new file mode 100644 index 00000000000..8d7cd2213bf --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQConfiguration.java @@ -0,0 +1,220 @@ +/* + * 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.component.activemq; + +import java.lang.reflect.Constructor; + +import jakarta.jms.ConnectionFactory; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.Service; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.jms.JmsConfiguration; +import org.springframework.jms.connection.CachingConnectionFactory; +import org.springframework.jms.connection.DelegatingConnectionFactory; +import org.springframework.jms.connection.JmsTransactionManager; +import org.springframework.jms.connection.SingleConnectionFactory; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.transaction.PlatformTransactionManager; + +public class ActiveMQConfiguration extends JmsConfiguration { + private ActiveMQComponent activeMQComponent; + private String brokerURL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; + private volatile boolean customBrokerURL; + private boolean useSingleConnection; + private boolean usePooledConnection = true; + private boolean trustAllPackages; + + public ActiveMQConfiguration() { + } + + public String getBrokerURL() { + return brokerURL; + } + + /** + * Sets the broker URL to use to connect to ActiveMQ broker. + */ + public void setBrokerURL(String brokerURL) { + this.brokerURL = brokerURL; + this.customBrokerURL = true; + } + + public boolean isUseSingleConnection() { + return useSingleConnection; + } + + /** + * @deprecated - use JmsConfiguration#getUsername() + * @see JmsConfiguration#getUsername() + */ + @Deprecated + public String getUserName() { + return getUsername(); + } + + /** + * @deprecated - use JmsConfiguration#setUsername(String) + * @see JmsConfiguration#setUsername(String) + */ + @Deprecated + public void setUserName(String userName) { + setUsername(userName); + } + + /** + * Enables or disables whether a Spring {@link SingleConnectionFactory} will be used so that when messages are sent + * to ActiveMQ from outside of a message consuming thread, pooling will be used rather than the default with the + * Spring {@link JmsTemplate} which will create a new connection, session, producer for each message then close them + * all down again. + * <p/> + * The default value is false and a pooled connection is used by default. + */ + public void setUseSingleConnection(boolean useSingleConnection) { + this.useSingleConnection = useSingleConnection; + } + + public boolean isUsePooledConnection() { + return usePooledConnection; + } + + /** + * Enables or disables whether a PooledConnectionFactory will be used so that when messages are sent to ActiveMQ + * from outside of a message consuming thread, pooling will be used rather than the default with the Spring + * {@link JmsTemplate} which will create a new connection, session, producer for each message then close them all + * down again. + * <p/> + * The default value is true. + */ + public void setUsePooledConnection(boolean usePooledConnection) { + this.usePooledConnection = usePooledConnection; + } + + public boolean isTrustAllPackages() { + return trustAllPackages; + } + + /** + * ObjectMessage objects depend on Java serialization of marshal/unmarshal object payload. This process is generally + * considered unsafe as malicious payload can exploit the host system. That's why starting with versions 5.12.2 and + * 5.13.0, ActiveMQ enforces users to explicitly whitelist packages that can be exchanged using ObjectMessages. + * <br/> + * This option can be set to <tt>true</tt> to trust all packages (eg whitelist is *). + * <p/> + * See more details at: http://activemq.apache.org/objectmessage.html + */ + public void setTrustAllPackages(boolean trustAllPackages) { + this.trustAllPackages = trustAllPackages; + } + + /** + * Factory method to create a default transaction manager if one is not specified + */ + @Override + protected PlatformTransactionManager createTransactionManager() { + JmsTransactionManager answer = new JmsTransactionManager(getOrCreateConnectionFactory()); + answer.afterPropertiesSet(); + return answer; + } + + protected void setActiveMQComponent(ActiveMQComponent activeMQComponent) { + this.activeMQComponent = activeMQComponent; + } + + @Override + public void setConnectionFactory(ConnectionFactory connectionFactory) { + ActiveMQConnectionFactory acf = null; + + ConnectionFactory target = connectionFactory; + if (target instanceof CachingConnectionFactory) { + CachingConnectionFactory ccf = (CachingConnectionFactory) target; + target = ccf.getTargetConnectionFactory(); + } + if (target instanceof DelegatingConnectionFactory) { + DelegatingConnectionFactory dcf = (DelegatingConnectionFactory) target; + target = dcf.getTargetConnectionFactory(); + } + if (target instanceof ActiveMQConnectionFactory) { + acf = (ActiveMQConnectionFactory) target; + } + + if (acf != null) { + if (customBrokerURL) { + // okay a custom broker url was configured which we want to ensure + // the real target connection factory knows about + acf.setBrokerURL(brokerURL); + } else { + // its the opposite the target has the brokerURL which we want to set on this + setBrokerURL(acf.getBrokerURL()); + } + } + + super.setConnectionFactory(connectionFactory); + } + + @Override + protected ConnectionFactory createConnectionFactory() { + org.apache.activemq.ActiveMQConnectionFactory answer + = new org.apache.activemq.ActiveMQConnectionFactory(); + answer.setTrustAllPackages(trustAllPackages); + if (getUsername() != null) { + answer.setUserName(getUsername()); + } + if (getPassword() != null) { + answer.setPassword(getPassword()); + } + answer.setBrokerURL(getBrokerURL()); + if (isUseSingleConnection()) { + SingleConnectionFactory scf = new SingleConnectionFactory(answer); + if (activeMQComponent != null) { + activeMQComponent.addSingleConnectionFactory(scf); + } + return scf; + } else if (isUsePooledConnection()) { + ConnectionFactory pcf = createPooledConnectionFactory(answer); + if (activeMQComponent != null) { + activeMQComponent.addPooledConnectionFactoryService((Service) pcf); + } + return pcf; + } else { + return answer; + } + } + + protected ConnectionFactory createPooledConnectionFactory(ActiveMQConnectionFactory connectionFactory) { + try { + Class type = loadClass("org.apache.activemq.pool.PooledConnectionFactory", getClass().getClassLoader()); + Constructor constructor = type.getConstructor(org.apache.activemq.ActiveMQConnectionFactory.class); + return (ConnectionFactory) constructor.newInstance(connectionFactory); + } catch (Exception e) { + throw new RuntimeCamelException("Failed to instantiate PooledConnectionFactory: " + e, e); + } + } + + public static Class<?> loadClass(String name, ClassLoader loader) throws ClassNotFoundException { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + if (contextClassLoader != null) { + try { + return contextClassLoader.loadClass(name); + } catch (ClassNotFoundException e) { + return loader.loadClass(name); + } + } else { + return loader.loadClass(name); + } + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java new file mode 100644 index 00000000000..bf57ea9c4e2 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQEndpoint.java @@ -0,0 +1,73 @@ +/* + * 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.component.activemq; + +import java.util.Map; + +import org.apache.camel.Category; +import org.apache.camel.component.jms.JmsBinding; +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsConfiguration; +import org.apache.camel.component.jms.JmsEndpoint; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; + +/** + * Send messages to (or consume from) Apache ActiveMQ. This component extends the Camel JMS component. + */ +@UriEndpoint(firstVersion = "1.0.0", extendsScheme = "jms", scheme = "activemq", title = "ActiveMQ", + syntax = "activemq:destinationType:destinationName", + category = { Category.MESSAGING }) +public class ActiveMQEndpoint extends JmsEndpoint { + + @UriParam(multiValue = true, prefix = "destination.", label = "consumer,advanced") + private Map<String, String> destinationOptions; + + public ActiveMQEndpoint() { + } + + public ActiveMQEndpoint(String uri, JmsComponent component, String destinationName, boolean pubSubDomain, + JmsConfiguration configuration) { + super(uri, component, destinationName, pubSubDomain, configuration); + } + + public ActiveMQEndpoint(String endpointUri, JmsBinding binding, JmsConfiguration configuration, String destinationName, + boolean pubSubDomain) { + super(endpointUri, binding, configuration, destinationName, pubSubDomain); + } + + public ActiveMQEndpoint(String endpointUri, String destinationName, boolean pubSubDomain) { + super(endpointUri, destinationName, pubSubDomain); + } + + public ActiveMQEndpoint(String endpointUri, String destinationName) { + super(endpointUri, destinationName); + } + + public Map<String, String> getDestinationOptions() { + return destinationOptions; + } + + /** + * Destination Options are a way to provide extended configuration options to a JMS consumer without having to + * extend the JMS API. The options are encoded using URL query syntax in the destination name that the consumer is + * created on. See more details at https://activemq.apache.org/destination-options. + */ + public void setDestinationOptions(Map<String, String> destinationOptions) { + this.destinationOptions = destinationOptions; + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQQueueEndpoint.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQQueueEndpoint.java new file mode 100644 index 00000000000..a40f7d6457b --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQQueueEndpoint.java @@ -0,0 +1,101 @@ +/* + * 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.component.activemq; + +import java.util.Collections; +import java.util.List; + +import org.apache.camel.Exchange; +import org.apache.camel.api.management.ManagedAttribute; +import org.apache.camel.api.management.ManagedResource; +import org.apache.camel.component.jms.DefaultQueueBrowseStrategy; +import org.apache.camel.component.jms.JmsBrowsableEndpoint; +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsConfiguration; +import org.apache.camel.component.jms.QueueBrowseStrategy; +import org.apache.camel.spi.BrowsableEndpoint; +import org.springframework.jms.core.JmsOperations; + +/** + * An endpoint for a JMS Queue which is also browsable + */ +@ManagedResource(description = "Managed JMS Queue Endpoint") +public class ActiveMQQueueEndpoint extends ActiveMQEndpoint implements JmsBrowsableEndpoint, BrowsableEndpoint { + private int maximumBrowseSize = -1; + private final QueueBrowseStrategy queueBrowseStrategy; + + public ActiveMQQueueEndpoint(String uri, JmsComponent component, String destination, + JmsConfiguration configuration) { + this(uri, component, destination, configuration, null); + setDestinationType("queue"); + } + + public ActiveMQQueueEndpoint(String uri, JmsComponent component, String destination, + JmsConfiguration configuration, QueueBrowseStrategy queueBrowseStrategy) { + super(uri, component, destination, false, configuration); + setDestinationType("queue"); + if (queueBrowseStrategy == null) { + this.queueBrowseStrategy = createQueueBrowseStrategy(); + } else { + this.queueBrowseStrategy = queueBrowseStrategy; + } + } + + public ActiveMQQueueEndpoint(String endpointUri, String destination, QueueBrowseStrategy queueBrowseStrategy) { + super(endpointUri, destination, false); + setDestinationType("queue"); + if (queueBrowseStrategy == null) { + this.queueBrowseStrategy = createQueueBrowseStrategy(); + } else { + this.queueBrowseStrategy = queueBrowseStrategy; + } + } + + public ActiveMQQueueEndpoint(String endpointUri, String destination) { + super(endpointUri, destination, false); + setDestinationType("queue"); + queueBrowseStrategy = createQueueBrowseStrategy(); + } + + @ManagedAttribute + public int getMaximumBrowseSize() { + return maximumBrowseSize; + } + + /** + * If a number is set > 0 then this limits the number of messages that are returned when browsing the queue + */ + @ManagedAttribute + public void setMaximumBrowseSize(int maximumBrowseSize) { + this.maximumBrowseSize = maximumBrowseSize; + } + + @Override + public List<Exchange> getExchanges() { + if (queueBrowseStrategy == null) { + return Collections.emptyList(); + } + String queue = getDestinationName(); + JmsOperations template = getConfiguration().createInOnlyTemplate(this, false, queue); + return queueBrowseStrategy.browse(template, queue, this); + } + + protected QueueBrowseStrategy createQueueBrowseStrategy() { + return new DefaultQueueBrowseStrategy(); + } + +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQSendDynamicAware.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQSendDynamicAware.java new file mode 100644 index 00000000000..418e6468c41 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQSendDynamicAware.java @@ -0,0 +1,25 @@ +/* + * 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.component.activemq; + +import org.apache.camel.component.jms.JmsSendDynamicAware; +import org.apache.camel.spi.annotations.SendDynamic; + +@SendDynamic("activemq") +public class ActiveMQSendDynamicAware extends JmsSendDynamicAware { + +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryQueueEndpoint.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryQueueEndpoint.java new file mode 100644 index 00000000000..c8862ceb82b --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryQueueEndpoint.java @@ -0,0 +1,39 @@ +/* + * 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.component.activemq; + +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsConfiguration; +import org.apache.camel.component.jms.JmsTemporaryQueueEndpoint; +import org.apache.camel.component.jms.QueueBrowseStrategy; + +public class ActiveMQTemporaryQueueEndpoint extends JmsTemporaryQueueEndpoint { + + public ActiveMQTemporaryQueueEndpoint(String uri, JmsComponent component, String destination, + JmsConfiguration configuration) { + super(uri, component, destination, configuration); + } + + public ActiveMQTemporaryQueueEndpoint(String uri, JmsComponent component, String destination, + JmsConfiguration configuration, QueueBrowseStrategy queueBrowseStrategy) { + super(uri, component, destination, configuration, queueBrowseStrategy); + } + + public ActiveMQTemporaryQueueEndpoint(String endpointUri, String destination) { + super(endpointUri, destination); + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryTopicEndpoint.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryTopicEndpoint.java new file mode 100644 index 00000000000..0f6bfd1fa7b --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/ActiveMQTemporaryTopicEndpoint.java @@ -0,0 +1,33 @@ +/* + * 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.component.activemq; + +import org.apache.camel.component.jms.JmsComponent; +import org.apache.camel.component.jms.JmsConfiguration; +import org.apache.camel.component.jms.JmsTemporaryTopicEndpoint; + +public class ActiveMQTemporaryTopicEndpoint extends JmsTemporaryTopicEndpoint { + + public ActiveMQTemporaryTopicEndpoint(String uri, JmsComponent component, String destination, + JmsConfiguration configuration) { + super(uri, component, destination, configuration); + } + + public ActiveMQTemporaryTopicEndpoint(String endpointUri, String destination) { + super(endpointUri, destination); + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/OriginalDestinationPropagateStrategy.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/OriginalDestinationPropagateStrategy.java new file mode 100644 index 00000000000..a28674ad210 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/OriginalDestinationPropagateStrategy.java @@ -0,0 +1,56 @@ +/* + * 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.component.activemq; + +import jakarta.jms.Message; +import jakarta.jms.Session; + +import org.apache.activemq.command.ActiveMQDestination; +import org.apache.activemq.command.ActiveMQMessage; +import org.apache.camel.Exchange; +import org.apache.camel.component.jms.JmsMessage; +import org.apache.camel.component.jms.MessageCreatedStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A strategy to enrich JMS message with their original destination if the Camel route originates from a JMS + * destination. + */ +public class OriginalDestinationPropagateStrategy implements MessageCreatedStrategy { + + private static final transient Logger LOG = LoggerFactory.getLogger(OriginalDestinationPropagateStrategy.class); + + @Override + public void onMessageCreated(Message message, Session session, Exchange exchange, Throwable cause) { + if (exchange.getIn() instanceof JmsMessage) { + JmsMessage msg = exchange.getIn(JmsMessage.class); + Message jms = msg.getJmsMessage(); + if (jms != null && jms instanceof ActiveMQMessage && message instanceof ActiveMQMessage) { + ActiveMQMessage amq = (ActiveMQMessage) jms; + if (amq.getOriginalDestination() == null) { + ActiveMQDestination from = amq.getDestination(); + if (from != null) { + LOG.trace("Setting OriginalDestination: {} on {}", from, message); + ((ActiveMQMessage) message).setOriginalDestination(from); + } + } + } + } + } + +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQConverter.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQConverter.java new file mode 100644 index 00000000000..a2b5bf87e42 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQConverter.java @@ -0,0 +1,38 @@ +/* + * 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.component.activemq.converter; + +import org.apache.activemq.command.ActiveMQDestination; +import org.apache.camel.Converter; + +@Converter(generateLoader = true) +public class ActiveMQConverter { + + /** + * Converts a URL in ActiveMQ syntax to a destination such as to support "queue://foo.bar" or 'topic://bar.whatnot". + * Things default to queues if no scheme. This allows ActiveMQ destinations to be passed around as Strings and + * converted back again. + * + * @param name is the name of the queue or the full URI using prefixes queue:// or topic:// + * @return the ActiveMQ destination + */ + @Converter + public ActiveMQDestination toDestination(String name) { + return ActiveMQDestination.createDestination(name, ActiveMQDestination.QUEUE_TYPE); + } + +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQMessageConverter.java b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQMessageConverter.java new file mode 100644 index 00000000000..3795d950758 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/ActiveMQMessageConverter.java @@ -0,0 +1,97 @@ +/* + * 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.component.activemq.converter; + +import java.io.Serializable; + +import jakarta.jms.JMSException; +import jakarta.jms.Message; +import jakarta.jms.MessageListener; + +import org.apache.activemq.command.ActiveMQMessage; +import org.apache.activemq.command.ActiveMQObjectMessage; +import org.apache.activemq.command.ActiveMQTextMessage; +import org.apache.camel.Converter; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.jms.JmsBinding; + +@Converter(generateLoader = true) +public class ActiveMQMessageConverter { + private JmsBinding binding = new JmsBinding(); + + /** + * Converts the inbound message exchange to an ActiveMQ JMS message + * + * @return the ActiveMQ message + */ + @Converter + public ActiveMQMessage toMessage(Exchange exchange) throws JMSException { + ActiveMQMessage message = createActiveMQMessage(exchange); + getBinding().appendJmsProperties(message, exchange); + return message; + } + + /** + * Allows a JMS {@link MessageListener} to be converted to a Camel {@link Processor} so that we can provide better + * <a href="">Bean Integration</a> so that we can use any JMS MessageListener in in Camel as a bean + * + * @param listener the JMS message listener + * @return a newly created Camel Processor which when invoked will invoke + * {@link MessageListener#onMessage(Message)} + */ + @Converter + public Processor toProcessor(final MessageListener listener) { + return new Processor() { + public void process(Exchange exchange) throws Exception { + Message message = toMessage(exchange); + listener.onMessage(message); + } + + @Override + public String toString() { + return "Processor of MessageListener: " + listener; + } + }; + } + + private static ActiveMQMessage createActiveMQMessage(Exchange exchange) throws JMSException { + Object body = exchange.getIn().getBody(); + if (body instanceof String) { + ActiveMQTextMessage answer = new ActiveMQTextMessage(); + answer.setText((String) body); + return answer; + } else if (body instanceof Serializable) { + ActiveMQObjectMessage answer = new ActiveMQObjectMessage(); + answer.setObject((Serializable) body); + return answer; + } else { + return new ActiveMQMessage(); + } + + } + + // Properties + // ------------------------------------------------------------------------- + public JmsBinding getBinding() { + return binding; + } + + public void setBinding(JmsBinding binding) { + this.binding = binding; + } +} \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/package.html b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/package.html new file mode 100644 index 00000000000..a1c8201ede9 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/converter/package.html @@ -0,0 +1,30 @@ +<!-- + + 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. + +--> +<html> +<head> +</head> +<body> + +Defines the <a href="http://camel.apache.org/type-converter.html">Type Converters</a> for working +with JMS and ActiveMQ with <a href="http://camel.apache.org/">Camel</a> +<a href="http://camel.apache.org/enterprise-integration-patterns.html">Enterprise Integration Patterns</a> + + +</body> +</html> \ No newline at end of file diff --git a/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/package.html b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/package.html new file mode 100644 index 00000000000..96fcdcbeb27 --- /dev/null +++ b/components/camel-activemq/src/main/java/org/apache/camel/component/activemq/package.html @@ -0,0 +1,31 @@ +<!-- + + 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. + +--> +<html> +<head> +</head> +<body> + +Defines the <a href="http://camel.apache.org/activemq.html">ActiveMQ Component</a> for +<a href="http://camel.apache.org">Camel</a> to provide great +<a href="http://camel.apache.org/enterprise-integration-patterns.html">Enterprise Integration Patterns</a> +integration for ActiveMQ users. + + +</body> +</html> \ No newline at end of file diff --git a/components/camel-activemq/src/test/resources/log4j2-test.properties b/components/camel-activemq/src/test/resources/log4j2-test.properties new file mode 100644 index 00000000000..b147f8b8207 --- /dev/null +++ b/components/camel-activemq/src/test/resources/log4j2-test.properties @@ -0,0 +1,28 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +appender.out.type = File +appender.out.name = out +appender.out.fileName = target/camel-activemq-test.log +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +appender.stdout.type = Console +appender.stdout.name = stdout +appender.stdout.layout.type = PatternLayout +appender.stdout.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +rootLogger.level = INFO +rootLogger.appenderRef.out.ref = out diff --git a/components/pom.xml b/components/pom.xml index 47f2883f5d5..56b8b7b701a 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -74,6 +74,7 @@ <module>camel-service</module> <!-- regular modules in alphabetic order --> + <module>camel-activemq</module> <module>camel-amqp</module> <module>camel-arangodb</module> <module>camel-as2</module> diff --git a/parent/pom.xml b/parent/pom.xml index 03b66f1d6e7..6a2a9b566d6 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -50,6 +50,7 @@ <checkstyle.failOnViolation>false</checkstyle.failOnViolation> <!-- dependency versions --> <abdera-version>1.1.3</abdera-version> + <activemq-version>5.18.1</activemq-version> <activemq-artemis-version>2.29.0</activemq-artemis-version> <angus-mail-version>2.0.2</angus-mail-version> <apacheds-version>2.0.0.AM26</apacheds-version>
