I'm trying to learn Spring Integration and for this i would like to create an application like this:
From Oracle i send messages (on Oracle Queue), this message will be intercepted from a Java application (build with Spring Integration) and the application will send an email based on message received. The message will contain To: - Cc: and the text to send.
To make this kind of communication i've decided to use JMS (i think in Oracle this is made with Oracle AQ).
In the database i've already created the Queue and now i'm trying to create a simple applicationContext.xml to start this handshake.
Looking on the net i've found really few articles about this (Spring Integration + Oracle AQ) and i'm getting some error. The main error is this: java.lang.ClassNotFoundException: oracle.jms.AQjmsFactory
Right now this is my applicationContext.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:orcl="http://www.springframework.org/schema/data/orcl"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/data/orcl http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd">
<int:channel id="inbound" />
<int:channel id="outbound" />
<bean id="simpleMessageListener" class="it.dirimo.SimpleMessageListener" />
<int-jms:inbound-channel-adapter
channel="inbound"
connection-factory="connectionFactory"
destination-name="Q1">
<int:poller fixed-delay="1000" />
</int-jms:inbound-channel-adapter>
<int:service-activator input-channel="inbound" output-channel="outbound" ref="simpleMessageListener" method="onMessage" />
<int-jms:outbound-channel-adapter id="jmsOut"
channel="outbound"
connection-factory="connectionFactory"
destination-name="sampleQueue" />
<int:poller id="poller" default="true" fixed-delay="10000" />
<orcl:aq-jms-connection-factory id="connectionFactory"
data-source="dataSource"
use-local-data-source-transaction="true"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="false">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:ORCL" />
<property name="username" value="user" />
<property name="password" value="password" />
</bean>
</beans>
Maybe i'm using "old" technologies (for example i've seen for the first time this org.apache.commons.dbcp.BasicDataSource)
Unfortunally i'm so new about Spring Integration and i've seen for the first time Oracle Queue (i'm using Oracle for work but never used any kind of Queue).
Some advice of how to proceed will be apreciated :)
EDIT 1
To solve the problem about the AQjmsFactory need to include aqapi.jar
java.lang.ClassNotFoundException: oracle.jms.AQjmsFactory
This simply means you are missing the jar that contains that class from the classpath.
Oracle, typically, requires that you manually download their jars from them directly.
Related
I am working on a high-volume integration with using spring integration tcp and I only send a request and receive more than millions of data over one connection and the time between two receiving message is lower than 100 milliseconds.
Here is my context xml and I am using TCPOutboundGateway.
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ip https://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">
<bean class="org.springframework.integration.samples.tcpclientserver.EchoService"
id="echoService"/>
<bean class="org.springframework.integration.samples.tcpclientserver.ByteArrayToStringConverter"
id="javaDeserializer"/>
<int-ip:tcp-connection-factory
apply-sequence="true" deserializer="javaDeserializer"
host="127.0.0.1"
id="TCPClientFactory1"
port="443"
single-use="false"
type="client"
/>
<int-ip:tcp-outbound-gateway
async="true" close-stream-after-send="false" connection-factory="TCPClientFactory1"
id="outGateway"
remote-timeout="10000"
reply-channel="serverBytes2StringChannel"
reply-timeout="10000"
request-channel="input"
request-timeout="10"
/>
<int:channel id="input"/>
<int:channel id="toSA"/>
<int:gateway default-request-channel="input"
id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"/>
<int:object-to-string-transformer auto-startup="true" id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:service-activator
input-channel="toSA"
method="test"
ref="echoService"
/>
<int:transformer expression="payload.failedMessage.payload + ':' + payload.cause.message"
id="errorHandler"
input-channel="errorChannel"/>
</beans>
I took an example from github.
My issue is; I can successfully handle and process first received message. But the rest is got below exception.
20:21:34.550 [pool-1-thread-1] ERROR org.springframework.integration.ip.tcp.TcpOutboundGateway - Cannot correlate response - no pending reply for 127.0.0.1:443:57385:e164052f-64e5-4d41-9d46-4a12bad12cd4
I read the source code of TcpOutboundGateway and also read caching client connection factory document but could not found a proper way to achieve solution.
The gateway is not designed for that scenarion it only supports 1 reply per request.
You can use a pair of outbound/inbound channel adapters, instead of the gateway, for scenarios like this.
The upcoming 5.4 release has an enhancement to the gateway to support this scenario.
After my poller fetches data from DB, I am calling an external service.
After getting response from that service, I want to do call another systems in a separate thread. Means, after getting response, my poller should take another record and send.In addition calling other systems should work in parallel.
For this I used a direct channel for receiving the data from DB. Used a service activator for sending request to external service. The response is passed to an executer channel.can anyone please tell me whether the below configuration is correct for the scenario ?
For clarity I am sharing the poller.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task" xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-4.1.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.1.xsd
http://www.springframework.org/schema/integration/http
http://www.springframework.org/schema/integration/http/spring-integration-http-4.1.xsd
http://www.springframework.org/schema/integration/jdbc
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc-4.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd">
<!-- <import resource="persistence-config.xml" /> <int:channel id="inchannel">
</int:channel> <int:channel id="outchannel"> <int:dispatcher task-executor="taskExecutor"/>
</int:channel> <task:executor id="taskExecutor" pool-size="2"/> <bean id="poller"
class="main.java.com.as.poller.PollerService" /> <int:service-activator input-channel="inchannel"
output-channel="outchannel" ref="poller" method="sendMessage" /> -->
<int-jdbc:inbound-channel-adapter id="dataChannel"
query="select loyalty_id, process_id,mobile_uid from TBL_RECEIPT where r_cre_time=(select min(r_cre_time) from TBL_RECEIPT where receipt_status=0)"
data-source="dataSource" max-rows-per-poll="1"
update="update TBL_RECEIPT set receipt_status=11 where loyalty_id in (:loyalty_id)">
<int:poller fixed-rate="5000">
</int:poller>
</int-jdbc:inbound-channel-adapter>
<bean id="poller" class="main.java.com.as.poller.PollerService" />
<int:channel id="executerchannel">
<int:dispatcher task-executor="taskExecutor"/>
</int:channel>
<task:executor id="taskExecutor" pool-size="20"/>
<int:service-activator input-channel="dataChannel"
output-channel="executerchannel" ref="poller" method="processMessage" />
<int:service-activator input-channel="executerchannel" ref="poller" method="processTpg">
</int:service-activator>
<stream:stdout-channel-adapter id="executerchannel"/>
No; it's not correct (it is almost correct).
<stream:stdout-channel-adapter id="executerchannel"/>
this overrides your executor channel definition (an outbound adapter with no channel attribute creates a channel with that id).
You will end up with a simple direct channel with 2 subscribers (stdout and your service activator) - they will get alternate messages.
I am not sure why you added that element; remove it or subscribe it to some other channel.
If you want it to go to both places; change the channel to a <publish-subscribe-channel/> with an executor.
First, I have just started looking at Spring Integration today, so I have very little experience. I already have a basic scheduled ftp file parser setup using spring integration:
<int:channel id="ftpIn" />
<int-ftp:inbound-channel-adapter
channel="ftpIn"
session-factory="ftpClientFactory"
filename-pattern="*.xml"
local-directory="${TEMP_DIR}">
<int:poller fixed-rate="${ftp.polling.rate}" />
</int-ftp:inbound-channel-adapter>
<bean id="ftpClientFactory" class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
<property name="host" value="${ftp.host}" />
<property name="port" value="${ftp.port}" />
<property name="username" value="${ftp.username}" />
<property name="password" value="${ftp.password}" />
</bean>
<int:service-activator
input-channel="ftpIn"
method="handle"
ref="ftpInHandler" />
<bean id="ftpInHandler" class="thanks.for.looking.FtpInHandler" />
This works; however, I want to add additional functionality that checks (at a fixed-rate) if the system is ready before starting the scheduled (fixed-rate) ftp adapter. I am stuck on the best way to implement this. Any help or guidance is appreciated.
Best Regards,
Jared
<poller> has an option like <advice-chain>.
So you just need to write some custom Advice:
public class CheckSystemInterceptor implements MethodInterceptor {
Object invoke(MethodInvocation invocation) throws Throwable {
return mySystem.isOK() ? invocation.proceed() : null;
}
}
Configure it as a <bean> with your system checker and inject it into that <advice-chain>.
It will be invoked on each poll.
I am trying to configure multiple flow executors for my project as I need one set of flows with 'always-redirect-on-pause' attribute as false and another as true. I have tried searching, skimming Spring Docs but been unable to come up with this configuration. Can anyone please share these configurations and/or direct to some relevant resource?
Thanks
You can have multiple workflow (flow definition files) location registration in your project Spring Configuration file
Spring Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
<bean id="assetManagementService" />
<bean id="savingsAssetService" />
<bean id="handlerMapping">
<property name="mappings">
<value>/assetMgmtHomeView.htm=flowController</value>
</property>
</bean>
<bean id="flowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
</webflow:flow-executor>
<webflow:flow-registry id="flowRegistry">
<webflow:flow-location id="assetMgmtHomeView" path="/WEB-INF/flows/assetMgmtFlow.xml" />
<webflow:flow-location id="savingsAssetViewFlow" path="/WEB-INF/flows/savingsAssetViewFlow.xml" />
</webflow:flow-registry>
</beans>
As you can see webflow:flow-registry contains two workflow xml files path. Keep in mind that those location registrations have different IDs used to distinguish among the workflows.
I wonder if anyone can help. I am working on a Spring Webflow 2 app, where I would also like to integrate Spring Mobile 1.0 with WURFL 1.4.2.
I have got Webflow and Spring Mobile working together like this:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="1"/>
<property name="mappings">
<value>/fnol=flowController</value>
</property>
<property name="interceptors">
<list>
<bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
</list>
</property>
And then within one of my action classes I can do this:
public Event startUp(RequestContext arg0) throws Exception {
// get the http request form the webflow RequestContext
ServletExternalContext externalContext = (ServletExternalContext) arg0.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getNativeRequest();
// get the Spring Mobile Device
Device currentDevice = DeviceUtils.getCurrentDevice(request);
This seems to work OK, but now I'd like to use WURFL with Spring Mobile so that I get a richer object representing the client capabilities.
This link suggests that I should be able to add a constructor to the DeviceResolverHandlerInterceptor like this:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="1"/>
<property name="mappings">
<value>/fnol=flowController</value>
</property>
<property name="interceptors">
<list>
<bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor">
<constructor-arg>
<device:wurfl-device-resolver root-location="/WEB-INF/wurfl/wurfl.zip" />
</constructor-arg>
</bean>
</list>
</property>
And I define the device namespace as:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:device="http://www.springframework.org/schema/mobile/device"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
http://www.springframework.org/schema/mobile/device
http://www.springframework.org/schema/mobile/device/spring-mobile-device-1.0.xsd" >
As far as my IDE is concerned (Eclipse) it is happy, and it deploys to wtp no problem. But when I start wtp I get the following error:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/mobile/device]
Offending resource: class path resource [fnol-webContext.xml]
Bean 'handlerMapping'
-> Property 'interceptors'
-> Bean ''
-> Constructor-arg
I'm not really sure what this means. Any ideas anyone?
Appreciate any help you guys can offer,
Cheers, Nathan
Had a look through the github repo to see if I could discern what happened: looks like WURFL support was deliberately removed due to licensing anomalies
https://github.com/SpringSource/spring-mobile/commit/ca81c6c20f1a9e524b0150e14dab20b020676e0b
This page alludes to a separate project which would provide WURFL support: I've not found it.