Camel and ActiveMQ: Failed to resolve endpoint - java

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.

Related

Camel creating too many tcp connections (over 15000) in TIME_WAIT status to connect ActiveMQ

I am using Apache Camel(with Spring) and ActiveMQ in project. Here are the settings related to JMS/ActiveMQ:
Camel version: activemq-camel-5.15.3.jar (all ActiveMQ related jars)
ActiveMQ version : 5.15.0
<!-- language: lang-xml -->
<bean id="defaultActiveMQRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
</bean>
<util:list id="redeliveryPolicyEntries">
<bean id="activeMQRedeliveryPolicy1" class="org.apache.activemq.RedeliveryPolicy">
<property name="queue" value="inbox"></property>
</bean>
</util:list>
<bean id="amqRedeliveryPolicyMap"
class="org.apache.activemq.broker.region.policy.RedeliveryPolicyMap">
<property name="defaultEntry" ref="defaultActiveMQRedeliveryPolicy"></property>
<property name="redeliveryPolicyEntries" ref="redeliveryPolicyEntries"></property>
</bean>
<bean id="amqPrefetchPolicy" class="org.apache.activemq.ActiveMQPrefetchPolicy">
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="20" />
<property name="maximumActiveSessionPerConnection" value="40" />
<property name="connectionFactory" ref="jmsConnectionFactory">
</property>
</bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${jmsConnectionFactory.brokerURL}" />
<property name="userName" value="admin" />
<property name="password" value="admin" />
<property name="prefetchPolicy" ref="amqPrefetchPolicy" />
<property name="redeliveryPolicyMap" ref="amqRedeliveryPolicyMap" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="concurrentConsumers" value="15" />
<property name="maxConcurrentConsumers" value="30" />
<property name="asyncConsumer" value="false" />
<property name="cacheLevelName" value="CACHE_CONSUMER" />
</bean>
<!-- this bean actually represents a jms component to be used in our camel-integration
setup.make endpoints by using name(id) of this bean. -->
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig" />
<property name="transacted" value="false" />
<property name="transactionManager">
<bean class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
</property>
</bean>
As you see I am using PooledConnectionFactory so I am expecting a fixed no of connections to connect with ActiveMQ. But unexpectedly I see a large no of TCP connections being opened in TIME_WAIT even when my application is idle and no messages are being produced/consumed at time. I confirmed this situation with infra team that confirmed all the Operating System level configuration are fine.
Here I tried debugging the doReceiveAndExecute method in AbstractPollingMessageListenerContainer- sessionToUse is not null, consumerToUse is also not null and code flows through receiveMessage(line number 304).I could not find the problem in debug trace as attached in debug screenshots:
and
and my actual problem
Is it a problem with MessageListenerContainer or with ConnectionFactory?? Am I missing some configuration which would prevent this from happening or is this an existing issue? If so is there a workaround?
Just spotted in your configuration that you configured the jmsConnectionFactory (not the pooled factory) in your transaction manager. Not sure if this could raise the issue because the pooled factory is simply not used.
<property name="transactionManager">
<bean class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
</property>

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).

JMS automatically reconnecting to TOPIC

I have two apps one app is publishing to a topic and another app is reading from that topic. We had a scenario where a queuemanager went down and then was available again. The publisher (without a restart) carries on working fine after the queuemanager restarts, but the topic consumer does not recieve the new messages from the publisher until it is restarted. Is there some configuration that can be setup on the topic consumer to refresh its connection somehow? We are using java / spring / spring integration over IBM MQ. The following is the configuration of our consumer.
<bean id="jmsAlertsServiceMessageListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="alertConnectionFactory"/>
<property name="destination" ref="alertsServiceTopic"/>
<property name="autoStartup" value="false"/>
<property name="clientId" value="${ps.Alert.clientId}"/>
<property name="taskExecutor" ref="jmsTaskExecutor"/>
<property name="subscriptionDurable" value="true"/>
<property name="pubSubDomain" value="true"/>
<property name="messageSelector" value="AlertState = 'RESOLVED'"/>
<property name="messageListener" ref="alertsMessageListener"/>
<property name="durableSubscriptionName" value="replay"/>
<property name="recoveryInterval" value="30000"/>
</bean>
<bean id="alertConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory" >
<property name="transportType" value="1" />
<property name="queueManager" value="${alert.mq.qm}" />
<property name="hostName" value="${alert.mq.host}" />
<property name="port" value="${alert.mq.port}" />
<property name="channel" value="${alert.mq.channel}" />
<property name="SSLCipherSuite" value="SSL_RSA_WITH_RC4_128_SHA" />
<property name="brokerPubQueue" value="${alert.mq.topic_connection_factory_broker_pub_queue}"/>
<property name="brokerQueueManager" value="${alert.mq.topic_connection_factory_broker_queue_manager}"/>
<property name="providerVersion" value="${alert.mq.topic_connection_factory_provider_version}"/>
<property name="brokerVersion" value="1"/>
<property name="messageSelection" value="1"/>
</bean>
<bean id="alertsServiceTopic" class="com.ibm.mq.jms.MQTopic">
<constructor-arg value="${alert.mq.topic}" />
<property name="brokerDurSubQueue" value="${alert.mq.queue}"/>
<property name="brokerVersion" value="1"/>
</bean>
<bean id="alertsMessageListener" class="org.springframework.integration.jms.ChannelPublishingJmsMessageListener">
<property name="requestChannel" ref="alertsJmsInputChannel"/>
</bean>
<bean id="jmsTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1"/>
<property name="maxPoolSize" value="1"/>
<property name="waitForTasksToCompleteOnShutdown" value="true"/>
<property name="daemon" value="false"/>
<property name="threadNamePrefix" value="jmsInbound-"/>
<property name="queueCapacity" value="3"/>
<!-- Discard any task that gets rejected. -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$DiscardPolicy"/>
</property>
</bean>
The DefaultMessageListenerContainer will automatically reconnect according to the recoveryInterval.
Turn on DEBUG (or even TRACE) logging to figure out what's happening.

Spring4 with Hibernate4 fails in standalone process

I'm failling to use Spring4 togather with Hibernate4 in a standalone process (no container like tomcat, WAS, ...)
How can I use Hibernate4, Spring4 and Spring data repositories togather in a standalone process?
However I confiugre Spring I allways get the same exception:
Caused by: java.lang.NullPointerException
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118)
at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149)
When googling for this, I get pointet to some information about hibernate.transaction.jta.platform and the docu for Hibernate 4.3 is here http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html_single/#services-JtaPlatform
But the only option I see for my case would be org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform but this still leads to the same error.
Here is my Spring config:
<context:component-scan base-package="com.xx.yy" />
<jpa:repositories base-package="com.xx.zz.respositories"></jpa:repositories>
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/culture" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="dataSource" />
<property name="packagesToScan" value="culture.matching.index.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="database" value="MYSQL" />
</bean>
</property>
<property name="jpaProperties">
<value>
hibernate.transaction.jta.platform=org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform
</value>
</property>
</bean>
Answer by #geoand helped a lot: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-simple
I therefore moved from XML to Java config

Categories

Resources