Spring Integration Webservices - spring-integration

I am very new at spring integration, I am trying to convert following code into spring integration code but I am not able to send the request properly.
I really don't know what I am doing wrong and what to do, actually the task is to split the XML which are sending to webservices then get the response back from it and then aggregate to make it one XML.
Normal code:
connection = (HttpURLConnection) validateServer.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
String parameters = "";
if (isMultipleVal) {
parameters = ADD_FUNCTION2
+ URLEncoder.encode(getxmldatalist, "UTF-8");
} else {
parameters = ADD_FUNCTION
+ URLEncoder.encode(getxmldatalist, "UTF-8");
}
LOG.info("parameters:" + parameters);
System.out.println("In client parameters "+parameters);
byte[] parameterAsBytes = parameters.getBytes();
System.out.println("Parameters as bytes "+parameterAsBytes);
connection.setRequestProperty(CONTENT_LENGTH,String.valueOf(parameterAsBytes.length));
OutputStream oStream = connection.getOutputStream();
oStream.write(parameterAsBytes, 0, parameterAsBytes.length);
oStream.flush();
oStream.close();
Spring Integration code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
xmlns:int-ws="http://www.springframework.org/schema/integration/ws"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int-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/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd
http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
<int:channel id="requestGatewayChannel"/>
<int:gateway id="serviceGateway" service-interface="xxx.xxx.xxx" default-request-channel="requestGatewayChannel" default-reply-channel="replyGatewayChannel" />
<int:channel id="replyGatewayChannel"/>
<int:splitter ref="rootSplitter" input-channel="requestGatewayChannel" output-channel="splitterOutputChannel" method="splitRoot"/>
<int:channel id="splitterOutputChannel"/>
<bean id="rootSplitter" class="xxx.xxx.xxx.VehicleRootSpliter" />
<int-xml:marshalling-transformer id="marshaller" input-channel="splitterOutputChannel" output-channel="marshallerOutputChannel" marshaller="marshallerUnmarshaller" result-type="StringResult" />
<int:channel id="marshallerOutputChannel"></int:channel>
<int:object-to-string-transformer input-channel="marshallerOutputChannel" output-channel="stringOutputChannel"></int:object-to-string-transformer>
<int:channel id="stringOutputChannel"></int:channel>
<int:transformer id="dataTransformer" input-channel="stringOutputChannel" output-channel="dataTransformerOutputChannel" ref="xmlToEncode" method="dataTransformer"></int:transformer>
---To encode the string of xml using custom transformer---
<int:channel id="dataTransformerOutputChannel"></int:channel>
<bean id="xmlToEncode" class="xxx.xxx.xxx.DataTransformer"></bean>
<int:header-enricher default-overwrite="true" input-channel="dataTransformerOutputChannel" output-channel="enricherOutputChannel">
<int:header name="Content_length" ref="headerBean" method="valueLength"></int:header>
</int:header-enricher>
<int:channel id="enricherOutputChannel"></int:channel>
<bean id="headerBean" class="xxx.xxx.xxx.DataTransformer"></bean>
<int-http:outbound-gateway url="${toms.ws.url}" request-channel="enricherOutputChannel" reply-channel="httpOutputChannel"
header-mapper="headerMapper" http-method="POST"
expected-response-type="java.lang.String"/>
<bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
<property name="outboundHeaderNames" value="HTTP_REQUEST_HEADERS, Content_length"></property>
<property name="userDefinedHeaderPrefix" value=""></property>
</bean>
<int:channel id="httpOutputchannel"></int:channel>
<int:service-activator input-channel="httpOutputChannel" ref="webserviceActivator" method="checkerWeb"></int:service-activator>
<bean id="webserviceActivator" class="xxx.xxx.xxx"></bean>
<bean id="marshallerUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
<property name="classesToBeBound">
<list>
<value>com.xxx.xxx.xxx.VRoot</value>
</list>
</property>
</bean>
</beans>

Related

how to write unit test for spring integration xml code

Im new to spring integration,I want to write unit test cases for my application. I'm working on an application where integration interface will be called by other system with XML input we transform the input XML using XSLT and will make a call to different system and the response will be sent to the caller.
<?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:task="http://www.springframework.org/schema/task"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-4.2.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-4.2.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-5.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>application.properties</value>
<value>application-${spring.profiles.active}.properties</value>
</list>
</property>
</bean>
<bean id="MessagePrinter" class="com.oms.integration.messagelogger.MessagePrinter"></bean>
<int:channel id="logIncommingCaptureRequestChannel"></int:channel>
<int:channel id="transformedCaptureRequestToCardinalChannel"></int:channel>
<int:channel id="incommingCaptureRequestToCardinal"></int:channel>
<int:channel id="CaptureRequestToCardinalChannel"></int:channel>
<int:channel id="logCaptureResponseFromCardinal"></int:channel>
<int:channel id="transformCaptureResponseFromCardinal"></int:channel>
<int:channel id="logTransformResponseFromCardinal"></int:channel>
<int:channel id="ResponseFromCardinalToYantraChannel"></int:channel>
<int-http:inbound-gateway request-channel="logIncommingCaptureRequestChannel" supported-methods="POST" path="/fp075" reply-channel="ResponseFromCardinalToYantraChannel"/>
<int-http:outbound-gateway request-channel="CaptureRequestToCardinalChannel" url="${Paypal_Url}={data}" expected-response-type="java.lang.String" http-method="GET" reply-channel="logCaptureResponseFromCardinal">
<int-http:uri-variable name="data" expression="payload"/>
</int-http:outbound-gateway>
<int:service-activator ref="MessagePrinter" input-channel="logIncommingCaptureRequestChannel" method="printIncommingCaptureRequestFromYantra" output-channel="incommingCaptureRequestToCardinal"></int:service-activator>
<int:service-activator ref="MessagePrinter" input-channel="transformedCaptureRequestToCardinalChannel" method="printTransformedCaptureRequestFromYantraToCardinal" output-channel="CaptureRequestToCardinalChannel"></int:service-activator>
<int:service-activator ref="MessagePrinter" input-channel="logCaptureResponseFromCardinal" method="printCaptureResponseFromCardinal" output-channel="transformCaptureResponseFromCardinal"></int:service-activator>
<int:service-activator ref="MessagePrinter" method="printTransformedResponseFromCardinal" input-channel="logTransformResponseFromCardinal" output-channel="ResponseFromCardinalToYantraChannel"></int:service-activator>
<int-xml:xslt-transformer
input-channel="incommingCaptureRequestToCardinal"
xsl-resource="classpath:/templates/FP075/DSW_XSLT_YANTRA_To_Paypal_Capture_Request_FP075.xslt"
output-channel="transformedCaptureRequestToCardinalChannel"
id="TransformIncommingCaptureRequest">
<int-xml:xslt-param name="MsgType"
value="${PP_Cardinal_MsgType_FP075}" />
<int-xml:xslt-param name="Version"
value="${PP_Cardinal_Version}" />
<int-xml:xslt-param name="ProcessorId"
value="${PP_Cardinal_ProcessorId}" />
<int-xml:xslt-param name="MerchantId"
value="${PP_Cardinal_MerchantId}" />
<int-xml:xslt-param name="TransactionPwd"
value="${PP_Cardinal_TransactionPwd}" />
</int-xml:xslt-transformer>
<int-xml:xslt-transformer
id="transformCaptureResponse"
input-channel="transformCaptureResponseFromCardinal"
xsl-resource="classpath:/templates/FP075/DSW_XSLT_YANTRA_To_Paypal_Capture_Response_FP075.xslt"
output-channel="logTransformResponseFromCardinal">
</int-xml:xslt-transformer>
</beans>
Since you have there <int-http:inbound-gateway> and <int-http:outbound-gateway> I would suggest you to take a look into the Mock Spring MVC: https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#spring-mvc-test-framework
The server side might be like this:
#RunWith(SpringRunner.class)
#WebAppConfiguration
#DirtiesContext
public class MyTests {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc =
MockMvcBuilders.webAppContextSetup(this.wac)
.build();
}
For the client side you need to use something like MockMvcClientHttpRequestFactory abd inject it into the HttpRequestExecutingMessageHandler for that mentioned <int-http:outbound-gateway>.
So, in the end your main configuration is the same and all the flow structure remains untouched. You send mock requests via this.mockMvc.perform() and expect response after your flow processing.

How is "acknowledge" used?

I am trying to integrate my application with JMS Queues (using ActiveMQ).
My requirement is, that once the message has been read from the input queue, message should not be removed from the queue. Rather I want to send an acknowledgement that application has received that message.
I am not able to understand the exact usage of property "acknowledge".
My code is as below:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Component scan to find all Spring components -->
<context:component-scan base-package="com.poc.springinteg._7" />
<!-- -->
<bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate" lazy-init="false">
<property name="environment">
<props>
<prop key="java.naming.provider.url">tcp://localhost:61616</prop>
<prop key="java.naming.factory.url.pkgs">org.apache.activemq.jndi</prop>
<prop key="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop>
<prop key="connectionFactoryNames">DefaultActiveMQConnectionFactory,QueueConnectionFactory</prop>
<prop key="queue.SendReceiveQueue">org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue</prop>
<prop key="queue.SendQueue">org.apache.geronimo.configs/activemq-ra/JCAAdminObject/MDBTransferBeanOutQueue</prop>
</props>
</property>
</bean>
<bean id="remoteConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="false">
<property name="jndiTemplate" ref="remoteJndiTemplate"/>
<property name="jndiName" value="QueueConnectionFactory"/>
<property name="lookupOnStartup" value="true" />
<property name="proxyInterface" value="javax.jms.ConnectionFactory" />
</bean>
<!-- writing queue -->
<bean id="destinationqueue"
class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0">
<value>OutputQueue_7</value>
</constructor-arg>
</bean>
<int:channel id="outbound"/>
<int-jms:outbound-channel-adapter id="jmsOut"
channel="outbound"
connection-factory="remoteConnectionFactory"
destination="destinationqueue" />
<!-- reading queue -->
<bean id="sourceQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0">
<value>OutputQueue_7</value>
</constructor-arg>
</bean>
<bean id="messageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="remoteConnectionFactory"/>
<property name="destination" ref="sourceQueue"/>
<property name="maxConcurrentConsumers" value="10"/>
<property name="concurrentConsumers" value="1"/>
<property name="autoStartup" value="true"/>
</bean>
<int:channel id="inbound"/>
<int-jms:message-driven-channel-adapter id="jmsIn"
channel="inbound"
extract-payload="false"
container="messageListenerContainer" />
<int:service-activator input-channel="inbound"
output-channel="outbound"
ref="messageReader"
method="onMessage" />
</beans>
-- Message Reader Class
import javax.jms.JMSException;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
#Component("messageReader")
public class MessageReader
{
#ServiceActivator
public void onMessage(Message inboundMessage) {
System.out.println(" -------Message Read Start--------");
System.out.println(inboundMessage.getHeaders());
System.out.println(" -------Message Headers Reading completed--------");
System.out.println("payload-->" + inboundMessage.getPayload().getClass());
String payload = inboundMessage.getPayload().toString();
System.out.println("payload value-->" + payload);
org.apache.activemq.command.ActiveMQTextMessage obj = (org.apache.activemq.command.ActiveMQTextMessage)inboundMessage.getPayload();
System.out.println("Object-->" + obj);
String var = null;
try {
var = obj.getText();
System.out.println("Datastructure-->" + obj.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
---- Message Writer Class
#Component("sendMessage")
public class SendMessage {
#Autowired
private MessageChannel outbound;
public void send(String name)
{
Entity entity = new Entity(1,"anuj");
Message<Entity> message = MessageBuilder.withPayload(entity)
.setHeader("Message_Header1", "Message_Header1_Value")
.setHeader("Message_Header2", "Message_Header2_Value")
.build();
outbound.send(message);
}
}
-- Application main class
public class App {
public static void main( String[] args )
{
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:7_applicationContext.xml" );
SendMessage sendMessage = (SendMessage)applicationContext.getBean( "sendMessage", SendMessage.class);
for(int i=0;i<10;i++){
sendMessage.send("This is Message Content");
}
applicationContext.registerShutdownHook();
}
}

Dynamically getting sftp connection properties from database and get sftpConnectionFactory in spring integration

I have requirement that I should get SFTP connection properties from database and create sftpSessionFactory by using properties comes from the database dynamically.
Below ${sftp.host}, ${sftp.port}, ${sftp.user} and ${sftp.password} properties values should come from database.
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${sftp.host}"/>
<property name="port" value="${sftp.port}" />
<property name="user" value="${sftp.user}"/>
<property name="password" value="${sftp.password}"/>
</bean>
How to create SFTP connection by getting properties from database?
web.xml
<!-- Loads the Spring application contexts -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:context/application-context-*.xml
</param-value>
</context-param>
application-context-services.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:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:annotation-config />
<context:component-scan base-package="com.abc.xyz.batch.services" />
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="preferFileSystemAccess" value="false" />
<property name="templateLoaderPath" value="classpath:templates/" />
<property name="freemarkerSettings">
<props>
<prop key="default_encoding">UTF-8</prop>
<prop key="locale">ar_AR</prop>
</props>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="cacheSeconds" value="0" />
<property name="defaultEncoding" value="UTF-8" />
<property name="useCodeAsDefaultMessage" value="true" />
<property name="basenames">
<list>
<value>classpath:validation-messages</value>
</list>
</property>
</bean>
EnvironmentLookupService.java
#Service
public class EnvironmentLookupService {
private static final Logger logger = LoggerFactory.getLogger(EnvironmentLookupService.class);
#Autowired
#Qualifier("transactionManager")
private PlatformTransactionManager txManager;
#Autowired
private ConfigDao configDao;
private final Map<String, String> config = new HashMap<String, String>();
/**
* Loads all lookups used in xyz from database
*/
#PostConstruct
public void loadLookupData() {
logger.info("loading lookup cache");
new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
loadLookups();
}
});
// initialize();
}
/**
* Refreshes the lookup caches
*/
#Scheduled(cron = "${core.lookups.cache.refresh.cron}")
public void refreshCache() {
loadLookupData();
}
/**
* Loads all lookups from database
*/
protected void loadLookups() {
final List<IConfig> list = configDao.findAll();
for (final IConfig property : list) {
config.put(property.getKey(), property.getValue());
}
}
/**
* Will return configuration value for the key provided
*
* #param key
* #return String
*/
public String retriveConfigValue(EConfig key) {
return config.get(key.getValue());
}
}
DynamicSftpChannelResolver.java
#Service
public class DynamicSftpChannelResolver {
#Autowired
private EnvironmentLookupService lookupService;
ConfigurableApplicationContext confAppContext;
#PostConstruct
public void setEnvironmentForSftpConnection() {
confAppContext = new ClassPathXmlApplicationContext("classpath*:context/*integration-context.xml");
final StandardEnvironment stdEnvironment = new StandardEnvironment();
final Properties props = new Properties();
props.setProperty(EConfig.SFTP_HOST.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_HOST));
props.setProperty(EConfig.SFTP_PORT.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_PORT));
props.setProperty(EConfig.SFTP_USER.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_USER));
props.setProperty(EConfig.SFTP_PASSWORD.getValue(), lookupService.retriveConfigValue(EConfig.SFTP_PASSWORD));
final PropertiesPropertySource propPropertySource = new PropertiesPropertySource("sftp", props);
stdEnvironment.getPropertySources().addLast(propPropertySource);
confAppContext.setEnvironment(stdEnvironment);
}
}
spring-integration-context.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:int-file="http://www.springframework.org/schema/integration/file"
xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:int-ws="http://www.springframework.org/schema/integration/ws"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<tx:annotation-driven transaction-manager="transactionManager" />
<context:property-placeholder />
<!-- <context:property-placeholder ignore-unresolvable="true" location="classpath:*.properties"/> -->
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${sftp.host}"/>
<property name="port" value="${sftp.port}" />
<property name="user" value="${sftp.user}"/>
<property name="password" value="${sftp.password}"/>
</bean>
<int:channel id="ch.file.download"></int:channel >
<int:channel id="ch.file.type.access"></int:channel >
<int:channel id="ch.file.type.excel"></int:channel >
<int:channel id="ch.file.type.csv"></int:channel >
<int:channel id="ch.file.validated"></int:channel>
<int-sftp:inbound-channel-adapter id="sftp.file.client.download"
session-factory="sftpSessionFactory" channel="ch.file.download"
auto-create-local-directory="true" remote-directory="${sftp.remote.directory}"
local-filename-generator-expression="#this"
temporary-file-suffix=".downloading"
local-directory="${sftp.local.directory}"
>
<int:poller fixed-rate="1000"/>
</int-sftp:inbound-channel-adapter>
After doing all the above sftpSessionFactory is not getting created. no exception also.
I guest *integration-conotext.xml is not loading.
Can you please suggest me ,what's going wrong ?.
Your web.xml has an option to load any XML config by pattern classpath*:context/application-context-*.xml. But the Spring Integration config name looks like spring-integration-context.xml.
From my perspective it doesn't matter and it would be better to use <context:import> on the matter.
From other side, pleas, take a look to the new DelegatingSessionFactory feature since Spring Integration 4.2 which allows to retrieve the target SessionFactory at runtime against the requestMessage.
And one more point. I use Commons Configuration to load Properties from DataBase and use the last one for the properties-placeholder:
<bean id="databaseConfiguration" class="org.apache.commons.configuration.DatabaseConfiguration">
<constructor-arg ref="dataSource"/>
<constructor-arg value="PROPERTIES"/>
<constructor-arg value="PROPERTY"/>
<constructor-arg value="PROPERTYVALUE"/>
</bean>
<bean id="propertiesFromDB" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
p:staticMethod="org.apache.commons.configuration.ConfigurationConverter.getProperties"
p:arguments-ref="databaseConfiguration"/>
<context:property-placeholder properties-ref="propertiesFromDB"/>
If that would be enough for you to load them from DB only once at startup.

Spring integration xml file errors out on reactor StringUtils

I have a spring integration sftp flow which I load as a child context within my overall application context. This is based on the dynamic ftp SI example. My integration flow has nothing about reactor or streams in it. Its a simple flow with one direct channel connected with a sftp-outbound-gateway to transfer files to a sftp server. I can even run units tests and the flow work fine (is able to transfer files) but when I run an integration test which loads the full parent application and then initializes the child context with this sftp flow loaded in it, it throws an error for not being able to find reactor/StringUtils class.
The reason for that seems to be that spring-integration-sftp loads reactor jars as transient deps but since my parent application already has a different version of reactor loaded in the classpath I excluded the reactor-core from spring integration dep. If I dont exclude the reactor-core from spring-integration then there are some version conflicts so I would like to exclude it.
reactorVersion = 2.0.0.M2
compile("io.projectreactor:reactor-core:$reactorVersion")
compile "io.projectreactor.spring:reactor-spring-context:$reactorVersion"
compile("org.springframework.integration:spring-integration-sftp") {
exclude module: "reactor-core"
}
Initializing the SI flow
context = new ClassPathXmlApplicationContext(new String[] { "classpath:adapters/"
+ sink.getConfigurationFile() }, false);
setEnvironment(context, sink);
context.setParent(parentContext);
context.refresh();
context.registerShutdownHook();
The error when i ran the integration test
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [adapters/sftp.xml]; nested exception is java.lang.NoClassDefFoundError: reactor/util/StringUtils
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
Finally the SI flow
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd">
<import resource="common.xml" />
<bean id="sftpSessionFactory"
class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="defaultSftpSessionFactory" />
</bean>
<bean id="defaultSftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${sink.host}" />
<property name="port" value="22" />
<property name="privateKey" value="${sink.private.key}" />
<property name="privateKeyPassphrase" value="${sink.private.key.phrase}" />
<property name="user" value="${sink.user}" />
<property name="password" value="${sink.pass}" />
</bean>
<int:channel id="input" />
<int-sftp:outbound-channel-adapter
auto-startup="true" session-factory="sftpSessionFactory" channel="input"
remote-directory="${sink.path}" remote-filename-generator-expression="headers['remote_file_name']">
<int-sftp:request-handler-advice-chain>
<bean
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="onSuccessExpression" value="payload" />
<property name="successChannel" ref="successChannel" />
<property name="onFailureExpression" value="payload" />
<property name="failureChannel" ref="failureChannel" />
<property name="trapException" value="true" />
</bean>
</int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>
<int:channel id="successChannel" />
<int:service-activator input-channel="successChannel"
ref="completionHandler" method="handle" />
<int:channel id="failureChannel" />
<int:service-activator input-channel="failureChannel"
ref="failureHandler" method="handle" />
Updating to add my reactor configuration
#Configuration
#EnableReactor
public class ReactorConfiguration {
static {
Environment.initializeIfEmpty().assignErrorJournal();
}
#Bean
public EventBus eventBus() {
return EventBus.config().env(Environment.get()).dispatcher(Environment.SHARED).get();
}
#Bean
public IdGenerator randomUUIDGenerator() {
return new IdGenerator() {
#Override
public UUID generateId() {
return UUIDUtils.random();
}
};
}
}
Gradle currently doesn't do a great job excluding dependencies of transitive dependencies.
It's not spring-integration-sftp that pulls in reactor, it's spring-integration-core.
Try explicitly excluding via that.
We have removed the hard transitive reactor dependency in SI 4.2 (but it's not released yet).
The spring team has created a gradle plugin that might help.

spring integration int-redis:outbound-gateway exception

used a RedisMessageTranfomer to push a message to have a payload of test with a header redis_command=GET to redis outbound gateway and go the exception listed below.
<?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:p="http://www.springframework.org/schema/p"
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/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd
http://www.springframework.org/schema/integration/redis http://www.springframework.org/schema/integration/redis/spring-integration-redis.xsd
http://www.springframework.org/schema/integration/ws http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd
http://www.springframework.org/schema/integration/xml http://www.springframework.org/schema/integration/xml/spring-integration-xml.xsd"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
xmlns:int-redis="http://www.springframework.org/schema/integration/redis"
xmlns:int-ws="http://www.springframework.org/schema/integration/ws"
xmlns:si-xml="http://www.springframework.org/schema/integration/xml">
<int-http:inbound-gateway id="omega"
request-channel="channel3" path="/omega" supported-methods="GET,POST"
reply-channel="channel5" />
<int:channel id="channel3">
<int:interceptors>
<int:wire-tap channel="channel3LoggingChannel" />
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="channel3LoggingChannel"
level="INFO" expression="'*** Channel3 Log ' + headers + ' -> ' + payload">
</int:logging-channel-adapter>
<int:transformer
output-channel="channel4" input-channel="channel3"
ref="redisMessageTransformer"
method="transform">
</int:transformer>
<bean id="redisMessageTransformer"
class="org.springframework.integration.samples.http.RedisMessageTransformer"/>
<int:channel id="channel4">
<int:interceptors>
<int:wire-tap channel="channel4LoggingChannel" />
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="channel4LoggingChannel"
level="INFO" expression="'*** Channel4 Log ' + headers + ' -> ' + payload">
</int:logging-channel-adapter>
<int-redis:outbound-gateway request-channel="channel4"
reply-channel="channel5" redis-template="redisTemplate"
command-expression="'GET'" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<constructor-arg ref="redisConnectionFactory"/>
</bean>
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true" p:host-name="127.0.0.1" p:port="6379" />
<bean
id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="payloadArgumentsStrategy"
class="org.springframework.integration.samples.http.PayloadArgumentsStrategy"/>
<int:channel id="channel5">
<int:interceptors>
<int:wire-tap channel="channel5LoggingChannel" />
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="channel5LoggingChannel"
level="INFO" expression="'*** Channel5 Log ' + headers + ' -> ' + payload">
</int:logging-channel-adapter>
</beans>
package org.springframework.integration.samples.http;
import org.springframework.integration.redis.support.RedisHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
public class RedisMessageTransformer {
public Object transform(Object object)
{
Object m = object;
System.out.println("*** object.getClass().getName = " + object.getClass().getName());
m = MessageBuilder.withPayload("test").setHeader(RedisHeaders.COMMAND, "GET").build();
System.out.println("*** m = " + m);
return m;
}
}
Exception
<pre> Server Error</pre></p><h3>Caused by:</h3><pre>java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.execute(Ljava/lang/String;[[B)Ljava/lang/Object;
at org.springframework.integration.redis.outbound.RedisOutboundGateway$1.doInRedis(RedisOutboundGateway.java:125)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:162)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:133)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:121)
at org.springframework.integration.redis.outbound.RedisOutboundGateway.handleRequestMessage(RedisOutboundGateway.java:121)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170)
What needs to be changed to get redis-outboundgateway to read (GET) a value from redis>?
org.springframework.data.redis.connection.RedisConnection.execute(Ljava/lang/String;[[B)Ljava/lang/Object;
H-m... Which version of Spring Data Redis do you use?
Try to use that on which comes as transitive dependency for spring-integration-redis-4.0

Resources