cant' get camel route to JMs active mq working - java

First user of camel/JMS/acivemq.
I set up a jms camel route and I'm trying to send as test text and see it in the active mq GUI http://127.0.0.1:8161/admin/topics.jsp but I am not seeing anything. This is my first time trying to get this all to work and really need to see something in active mq to prove that this is working correctly.
Here is the camel route
<cm:property-placeholder persistent-id="com.srcinc.ogre.alerts">
<cm:default-properties>
<cm:property name="jmsHostName" value="localhost" />
<cm:property name="jmsPort" value="61616" />
<cm:property name="jmsUserName" value="system" />
<cm:property name="jmsPassword" value="manager" />
</cm:default-properties>
</cm:property-placeholder>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://${jmsHostName}:${jmsPort}" />
<property name="userName" value="${jmsUserName}" />
<property name="password" value="${jmsPassword}" />
</bean>
<bean id="pooledJmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
init-method="start" destroy-method="stop">
<property name="maxConnections" value="8" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledJmsConnectionFactory" />
<property name="concurrentConsumers" value="10" />
</bean>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route id="AlertProcessorJMSDistributionRoute">
<from uri="vm:send-jms-alert?multipleConsumers=true" />
<to uri="activemq:topic:Alerts" />
</route>
</camelContext>
Here is my Java code that references the appropriate camel route.
private static final String VM__JMS_ROUTE = "vm::send-jms-alert";
private ProducerTemplate mProducer;
mProducer = new DefaultCamelContext().createProducerTemplate();
mProducer.sendBody(VM__JMS_ROUTE, "Testing 123");

In your Java code you should only have one colon, vm:send-jms-alert instead of vm::send-jms-alert

Related

Camel and ActiveMQ: Failed to resolve endpoint

I'm getting the following error in an application that user apache camel and activemq:
Failed to resolve endpoint: iasJms://setStatus due to: No component
found with scheme: iasJm
this is the declaration of the route that is causing the issue:
rest("/setStatus")
.put("/{number}")
.route()
.from("direct:setStatusRest")
.setExchangePattern(ExchangePattern.InOnly)
.to("iasJms:setStatus");
And this is my camelContext.xml
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties"
location="file:/etc/configmap/app.properties" propertiesParserRef="jasypt">
</propertyPlaceholder>
</camelContext>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="10" />
<property name="maximumActiveSessionPerConnection" value="10" />
<property name="connectionFactory" >
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:8161" />
<property name="userName" value="username"/>
<property name="password" value="password"/>
</bean>
</property>
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="transacted" value="true" />
<property name="concurrentConsumers" value="15" />
<property name="deliveryPersistent" value="true" />
<property name="requestTimeout" value="10000" />
<property name="cacheLevelName" value="CACHE_CONSUMER" />
</bean>
<bean id="iasJms" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig"/>
</bean>
In my pom.xml I added the dependencies for activemq-camel and activemq-pool.
Any idea of what's happening?
Change the name of id to activemq instead of iasJms and use that in your route.

Using messageSelector with AbstractMessageListenerContainer Spring Framework

I want to use messageSelector String which is inside the class AbstractMessageListenerContainer.class and here is the XML Configurations that i am giving.
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="autoStartup" value="${listener.setup}" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="paymentResponseQueue" />
<property name="messageListener" ref="myAbstractListener" />
</bean>
<bean id="myAbstractListener"
class="org.springframework.jms.listener.AbstractMessageListenerContainer">
<property name="autoStartup" value="${listener.setup}" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="paymentResponseQueue" />
<property name="messageListener" ref="authorisationResponseHandler" />
<property name="messageSelector" value="JMSCorelationId = 'AMM--AS1-6e07c3092bc94f77a183889ababeabc2'" />
</bean>
After giving this configuration, when i start tomcat, my application is not getting started.
Where as when i give the config as below and start tomcat, i am able to start my application and working as expected. xyzResponseHandler is referencing to Class file where i am implementing
public class xyzResponseHandler implements MessageListener{
}
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="autoStartup" value="${listener.setup}" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="paymentResponseQueue" />
<property name="messageListener" ref="xyzResponseHandler" />
</bean>
What wrong i am doing in the First Config. Can you please correct me if i am going in wrong direction. Basically i want to filter the message using messageSelector.
In DefaultMessageListenerContainer the property messageListener should be either a standard JMS MessageListener object or a Spring SessionAwareMessageListener object.
Refer the below spring doc
http://docs.spring.io/spring-framework/docs/3.0.5.RELEASE/api/org/springframework/jms/listener/AbstractMessageListenerContainer.html#setMessageListener(java.lang.Object)
But you are referring to a bean of another ListenerContainer.

apache-camel throttle does not work as expected

Apache-Camel: 2.12.2, activemq: 5.7
We noticed that in the following route throttling works fine for the first 100 exchanges. After that instead of sending 100 exchanges per second, it sends only 1 exchange per second. Now if we set timePeriodMillis=100 it seems to be working fine. Note that we send 500 exchanges at the same time.
<bean id="myProject" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="connectionFactory" ref="myProjectPooledConnectionFactory" />
<property name="preserveMessageQos" value="true" />
<property name="transacted" value="false" />
<property name="maxConcurrentConsumers" value="10" />
</bean>
<bean id="myProjectPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop" init-method="start">
<property name="connectionFactory" ref="myProjectAmqConnectionFactory" />
<property name="maxConnections" value="20" />
<property name="idleTimeout" value="0" />
</bean>
<bean id="myProjectAmqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" >
<property name="brokerURL" value="${myProject.broker.url}" />
<property name="copyMessageOnSend" value="false" />
<property name="useAsyncSend" value="true" />
</bean>
<!-- Local ActiveMQ Configuration -->
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="false"/>
<property name="maxConcurrentConsumers" value="500"/>
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop" init-method="start">
<property name="connectionFactory" ref="amqConnectionFactory" />
<property name="maxConnections" value="1" />
<property name="idleTimeout" value="0" />
</bean>
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" >
<property name="brokerURL" value="${broker.url}" />
<property name="copyMessageOnSend" value="false" />
<property name="useAsyncSend" value="true" />
</bean>
<route id="myProject.outbound.traffic" errorHandlerRef="error.handler.myProject">
<from uri="{{queue.myProject.mint.in}}{{queue.myProject.mint.in.args}}"/>
<throttle timePeriodMillis="1000" >
<constant>100</constant>
<process ref="myProjectProcessor" />
<inOnly uri="myProject:{{queue.myProject}}">
<log logName="myProject.myProjectProcessor" loggingLevel="INFO" message="this is a test message" />
</throttle>
</route>
A colleague of mine found the answer. It is a bug in camel 2.12.2 and it seems to have been solved in 2.12.3. It has to do with the way an exchange is assigned to a slot. Instead of checking if a slot is active it should check if the slot has past first.
protected synchronized TimeSlot nextSlot() {
if (slot == null) {
slot = new TimeSlot();
}
if (slot.isFull() || !slot.isActive()) {
slot = slot.next();
}
slot.assign();
return slot;
}
See here

Camel/ActiveMQ Transactions, Redelivery and DLQs

Using Fabric8 379 build.
Currently struggling with ActiveMQ & Camel getting the desired behaviours of TransactionErrorHandler to work as expected.
Firstly as per the Camel error handler documentation (http://camel.apache.org/error-handler.html) if I invoke the TransactionErrorHandler as suggested i.e.
<errorHandler id="txEH" type="TransactionErrorHandler">
<redeliveryPolicy logStackTrace="false" logExhausted="false" maximumRedeliveries="3"/>
</errorHandler>
I get an error:
Caused by: org.xml.sax.SAXParseException: cvc-enumeration-valid: Value 'TransactionErrorHandler' is not facet-valid with respect to enumeration '[DeadLetterChannel, DefaultErrorHandler, NoErrorHandler, LoggingErrorHandler]'. It must be a value from the enumeration.
Which is fair enough, I guess TransactionErrorHandler has been removed from the schema and has to be invoked differently? So if I go the alternative route and specify a TransactionErrorHandler bean like so:
<bean id="transactionErrorHandler"
class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
<property name="deadLetterUri" value="activemq:queue:ActiveMQ.DLQ" />
<property name="redeliveryPolicy" ref="redeliveryPolicy" />
</bean>
<bean id="redeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
<property name="backOffMultiplier" value="2" />
<property name="maximumRedeliveries" value="2" />
<property name="redeliveryDelay" value="1000" />
<property name="useExponentialBackOff" value="true" />
</bean>
I can successfully use this within my route by specifying errorHandlerRef="transactionErrorHandler". However when testing this scenario, the redeliveryPolicy is completely ignored, with redelivery attempts being 6 (default) rather than the 2 specified above. I am hoping someone can point me in the right direction around how to properly specify a TransactionErrorHandler within a route. Below is my current test blueprint.xml, which is deployed onto a fabric:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.0.0.xsd">
<!-- blueprint property placeholders -->
<cm:property-placeholder id="test-adapter" persistent-id="uk.test.transactions">
<cm:default-properties>
<cm:property name="amqBrokerURL" value="discovery:(fabric:platform)" />
<cm:property name="amqBrokerUserName" value="admin" />
<cm:property name="amqBrokerPassword" value="admin" />
</cm:default-properties>
</cm:property-placeholder>
<camelContext xmlns="http://camel.apache.org/schema/blueprint" id="TestRouteContext" useMDCLogging="true">
<!-- <errorHandler id="txEH" type="TransactionErrorHandler">
<redeliveryPolicy logStackTrace="false"
logExhausted="false" />
</errorHandler> -->
<route id="platform-test-route" errorHandlerRef="txEH">
<from uri="activemq:queue:test-queue-in" />
<transacted ref="transactionPolicy" />
<!-- Basic Bean that logs a message -->
<bean ref="stubSuccess" />
<!-- Basic Bean that throws a java.lang.Exception-->
<bean ref="stubFailure" />
<to uri="activemq:queue:test-queue-out" />
</route>
</camelContext>
<bean id="stubSuccess" class="uk.test.transactions.stubs.StubSuccess" />
<bean id="stubFailure" class="uk.test.transactions.stubs.StubFailure" />
<bean id="transactionErrorHandler"
class="org.apache.camel.spring.spi.TransactionErrorHandlerBuilder">
<property name="deadLetterUri" value="activemq:queue:ActiveMQ.DLQ" />
<property name="redeliveryPolicy" ref="redeliveryPolicy" />
</bean>
<bean id="transactionPolicy" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jmsTransactionManager" />
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
<bean id="jmsTransactionManager"
class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="jmsPooledConnectionFactory" />
</bean>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="connectionFactory" ref="jmsPooledConnectionFactory" />
<property name="transacted" value="true" />
<property name="transactionManager" ref="jmsTransactionManager" />
<property name="cacheLevelName" value="CACHE_CONSUMER" />
</bean>
<bean id="jmsPooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
init-method="start" destroy-method="stop">
<property name="maxConnections" value="1" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<!-- <bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
<property name="backOffMultiplier" value="2" />
<property name="initialRedeliveryDelay" value="2000" />
<property name="maximumRedeliveries" value="2" />
<property name="redeliveryDelay" value="1000" />
<property name="useExponentialBackOff" value="true" />
</bean> -->
<bean id="redeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
<property name="backOffMultiplier" value="2" />
<property name="maximumRedeliveries" value="2" />
<property name="redeliveryDelay" value="1000" />
<property name="useExponentialBackOff" value="true" />
</bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${amqBrokerURL}" />
<property name="userName" value="${amqBrokerUserName}" />
<property name="password" value="${amqBrokerPassword}" />
<property name="watchTopicAdvisories" value="false" />
<!-- <property name="redeliveryPolicy" ref="redeliveryPolicy" /> -->
</bean>
</blueprint>
If anyone could see where I am going wrong it would be much appreciated.
You should configure the redelivery options on the AMQ broker as when you use TX, its the brokers responsible for doing the redelivery (not Camel).

How to set up a dead letter queue for each durableTopic?

I have set up an application to listen to an ActiveMQ topic. Here's the way I have configured it:
<jms:listener-container connection-factory="jmsFactory"
container-type="default" destination-type="durableTopic" client-id="CMY-LISTENER"
acknowledge="transacted">
<jms:listener destination="CMY.UPDATES"
ref="continuingStudiesCourseUpdateListener" subscription="CMY-LISTENER" />
</jms:listener-container>
<bean id="jmsFactoryDelegate" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${jmsFactory.brokerURL}" />
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="10" />
<property name="initialRedeliveryDelay" value="60000" />
<property name="redeliveryDelay" value="60000" />
<property name="useExponentialBackOff" value="true" />
<property name="backOffMultiplier" value="2" />
</bean>
</property>
</bean>
How do I set up a dead letter queue for each topic for those messages to get copied into when they reach the maximum deliveries?
This feature went into the most recent 5.5 release, you can find the info on the changes that were made here:
There's a new boolean attribute 'destinationPerDurableSubscriber' on IndividualDeadLetterStrategy in you activemq.xml

Categories

Resources