How to integrate my Java application as a consumer? - java

I have a Java application. How do I use it as consumer of messages in activemq? Do I need to write any code where I will be passing my name of java application to list it as a consumer?
Or do I need to integrate any software (like camel, spring) which will help me to achieve this. Right now what I am looking for is that this Java application needs to be called when activemq gets populated with a message.
If I need to integrate something into my activemq please put some links which will clearly explain how to go about the integration.
PS I am new to activemq and I am super dependent on your help .

If you are working on a Spring application. Or have knowledge of how to work with it, it's pretty simple.
The configuration would be something like this:
<bean id="messageListener" class="jmsexample.ExampleListener" />
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="destination"/>
<property name="messageListener" ref="messageListener" />
</bean>
Look at the documentation: http://static.springsource.org/spring/docs/3.0.x/reference/jms.html

Related

IBM MQ and Spring Integration - security settings

I've got a Spring Integration flow which uses an inbound gateway to get messages from an IBM MQ queue:
<int-jms:inbound-gateway id="InputGateway"
request-destination="RequestQueue"
request-channel="RequestChannel"
reply-channel="ReplyChannel"
/>
However I'm not capable of assigning security settings. In particular, I need an username, password and userAuthenticationMQCSP = false (for reasons beyond the scope of this post, I won't get into details but my broker will throw a MQRC = 2009 otherwise).
I've followed the IBM guide to connect with jmsTemplate and works just fine. This uses the official Spring boot starter from IBM MQ which will kindly create a connection factory and will autoconfigure it with some defaults from application.properties:
ibm.mq.queueManager=myQMName
ibm.mq.channel=myChannel
ibm.mq.connName=myhostname(myPort)
ibm.mq.user=username
ibm.mq.password=*******
ibm.mq.userAuthenticationMQCSP=false
Now, back to the Spring Integration case. According to the int-jms:inbound-gateway spec, a connectionFactory will be injected to the gateway, by name (attribute: connection-factory) which is set up to be "jmsConnectionFactory" by default
By default, all of the JMS adapters that require a reference to the
ConnectionFactory automatically look for a bean named
jmsConnectionFactory. That is why you do not see a connection-factory
attribute in many of the examples. However, if your JMS
ConnectionFactory has a different bean name, you need to provide that
attribute.
I don't see any way to set up a predictable name for the connection factory that I can plug into the int-jms:inbound-gateway.
Now, taking a different approach, as per this example I've created my connectionFactory with an adecuate name:
<bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1"/>
<property name="queueManager" value="myQMName"/>
<property name="hostName" value="myhostname"/>
<property name="port" value="myPort" />
<property name="channel" value="myChannel"/>
</bean>
But now I need somewhere to put the credentials and the security parameters. Looking at the example above, it looks like I need to plug something like:
<bean id="secureJmsConnectionAdapter" class="**yourpackages.SecureJMSConnectionAdapter**">
<property name="targetConnectionFactory" ref="${jms.mq.connection.factory}" />
<property name="userName" value="${jms.username}"/>
<property name="pwdAlias" value="${jms.alias}"/>
</bean>
However it is unclear to me how to implement this SecureJMSConnectionAdapter.
Additionally, if I set up my own connection factory, I will lose all of MQ boot starter automagic thanks to this annotation on the MQAutoConfiguration class:
#ConditionalOnMissingBean(value=javax.jms.ConnectionFactory.class)
Any ideas on how to put these pieces together?
EDIT: Just to avoid any possible red herrings to anyone, the MQRC2009 was irrelevant to ibm.mq.userAuthenticationMQCSP=false.
Some of my old projects I used a bean like this:
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
<property name="username" value="${jms.username}"/>
<property name="password" value="${jms.alias}"/>
</bean>
Should work well as a wrapper for your com.ibm.mq.jms.MQQueueConnectionFactory, but you have to use this jmsQueueConnectionFactory in the target components.
Although it looks like the mentioned IBM MQ JMS Spring doesn't that for us properly exposing a jmsConnectionFactory bean. You can rely on the default from Spring Integration in this case or use that jmsConnectionFactory explicitly for the connection-factory.
Also with Spring Boot you should consider to go away from XML configuration and give a chance for Spring Integration Java DSL: https://docs.spring.io/spring-integration/docs/5.1.7.RELEASE/reference/html/#java-dsl

Niolocker is not working in spring boot application

Trying to test file lock mechanism in spring boot application by starting two instances of same application pointing to same source path which contains 10 files. Expecting only one instance should process a file and once processed it will be deleted from source. Same file should not be processed by other instance.So added Niolocker to the scanner. Tested in both windows and linux environments.But in windows, facing below exception in both the instances... In Linux, same file is polled/processed by both instances. No impact in Linux. Have implemented the below logic to acquire lock.
Please suggest on this.
Windows exception:
java.io.IOException: The process cannot access the file because another process has locked a portion of the file
Linux:
Both instance poller picks the same file and processing it
<file:inbound-channel-adapter id="filesInChannel" directory="file:${base.path}" auto-startup="false" scanner="recursiveScanner" auto-create-directory="true">
<integration:poller id="poller" max-messages-per-poll="${max.messages.per.poll}" fixed-rate="${message.read.frequency}" task-executor="pollingExecutor">
<integration:transactional transaction-manager="transactionManager" />
</integration:poller>
</file:inbound-channel-adapter>
<bean id="inboundFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
<constructor-arg>
<list>
<bean class="org.springframework.integration.file.filters.AcceptOnceFileListFilter"/>
<bean class="org.springframework.integration.file.filters.RegexPatternFileListFilter">
<constructor-arg value="${file.type}"/>
</bean>
</list>
</constructor-arg>
</bean>
<bean id="inboundChannelNioLocker" class="org.springframework.integration.file.locking.NioFileLocker" />
<bean id="recursiveScanner" class="org.springframework.integration.file.RecursiveDirectoryScanner">
<property name="filter" ref="inboundFilter" />
<property name="locker" ref="inboundChannelNioLocker"/>
</bean>
The NioLocker is really operation system dependent and doesn't guarantee exclusive access to the file. Well, only Windows does that for us properly.
I even start considering to deprecate and remove it altogether from the Framework. It causes too much confuses for target users...
Instead of file locker you need to consider to use a FileSystemPersistentAcceptOnceFileListFilter based on the shared ConcurrentMetadataStore. So, this way really only one instance will pick up the file for processing. All others will skip it and move on to the next files.
See Reference Manual for more info.

Using spring as configurator

I have a server application. Now I'm using Spring not only to inject dependencies, but also to config my application. Something like this:
<bean id="server" class="foo.bar.Server">
<property name="host" value="${config.host}"/>
<property name="someBean">
<ref bean="someBean"/>
</property>
</bean>
My colleague sad that configuring application in Spring is not obvious and we should avoid this. I see logic in his words, because Spring is for dependence injection and server port is not dependency, isn't it? But for me configuring application is Spring is very convenient and obvious. Is my colleague right?
Configuring in Spring is simple, clear and maintainable.
This way you can easily create several instances with different properties.

Multiple resource providers in same transaction Spring

I am using Jackrabbit to store files (data store) and Hibernate almost everything else. I do not know alot of transactions etc. but I know that I want a global transaction for these two so that an exception rolls back everything. At the moment the database stuff is rolled back, but Jackrabbit isn't.
I am using Spring 3.2. I have deployed the Jackrabbit JCA adapter to JBoss (7.1.1). I have these lines in the config xml:
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager"></bean>
<tx:annotation-driven transaction-manager="txManager"
proxy-target-class="true"/>
However that isn't enough it seems. Could somebody give me some clues to what I need to read about/where to find information on this? I need to roll back everything if something happens to one of the resource providers.
This was quite tricky to set up. One gotcha was the spring automagically uses 'transactionManager' as a default name which caused problems. It is definitely worth the effort though as synchronising mismatched data sources would soon become a nightmare.
Here is my sample config that worked for me. Of course now we would probably use #Configuration instead of the xml. This worked using, Spring Data, JTA, MySQL with XA driver and Neo4j. Neo4j specific things have been omitted.
Spring Data may also help you here.
Here is a starter...
<tx:annotation-driven transaction-manager="xaTransactionManager" />
<bean id="xaTransactionManager" class="some.type.of.ChainedTransactionManager">
<constructor-arg>
<list>
<ref bean="jpaTransactionManager"/>
<ref bean="otherTransactionManager"/>
</list>
</constructor-arg>
</bean>
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="localContainerEntityManagerFactoryBean"/>
</bean>
<bean id="otherTransactionManager" class="other.type.of.jta.TransactionManager">
<property name="transactionManager" ref="otherTransactionManagerService"/>
</bean>

how do I change persistence.xml at run time

I am new to openJPA.
I have a scenario where, depending upon the server where my application is running, I need to change the settings to persistance.xml.
For eg. if its running on Server A, then it should use different database(different url), different password etc. and if the application is running on Server B then it should use different information.
And could you also tell me, which way should it be done, using datasource or simply putting properties under persistence-unit.
FYI I am using WS app. server 7 and RAD 7.5
Any type of help would be highly appreciated.
You're using an application server so you don't need to set database connection settings in the persistence.xml file. You should be able to create a JNDI data source in your appserver and then use that. EAch server could have the data source have the same JNDI name and then there'll be no need for any persistence.xml differences.
Workshop, JPA, and DataSources seems particularly relevant to you. As does Setting up a JNDI data source in WebSphere 6.0/6.1 and WebSphere + JNDI + Spring Framework + Hibernate.
Are you using Spring? If so, then the problem is easy to solve: you don't put the data source information in your persistence.xml, you put it in your application context and that'll have different configuration on each server.
For example:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:database.properties"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.class}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
and each server could have a different database.properties file on each server (where each is in the classpath somewhere in this example):
database.username=scratch
database.password=scratch
database.class=oracle.jdbc.OracleDriver
database.url=jdbc:oracle:thin:#localhost:1521:XE
Changing persistence.xml at runtime is going to be problematic as that's not really how JPA is designed.
Of course, you can use JNDI data sources with Spring also.

Categories

Resources