How to unit test Spring Integration’s int-file:inbound-channel-adapter - unit-testing

I have a simple Spring Integration flow where I read XML files from a given directory, and send their content to another channel and do other processing.
After the processing is done, I need to move the input file in an archive/error directory.
file-integration.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-file="http://www.springframework.org/schema/integration/file"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/file https://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<import resource="transaction-manager-configuration.xml"/>
<context:property-placeholder location="classpath:app.properties"/>
<int:channel id="inputFileChannel"/>
<int-file:inbound-channel-adapter channel="inputFileChannel"
directory="${inputDir}"
filename-pattern="*.xml">
<int:poller fixed-delay="1000">
<int:transactional transaction-manager="txManager" synchronization-factory="syncFactory"/>
</int:poller>
</int-file:inbound-channel-adapter>
<int-file:file-to-string-transformer input-channel="inputFileChannel"
output-channel="contentChannel"/>
<int:channel id="contentChannel"/>
<int:channel id="inputFileSuccessChannel"/>
<int:channel id="inputFileErrorChannel"/>
<!-- Move file after being processed -->
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit channel="inputFileSuccessChannel"/>
<int:after-rollback channel="inputFileErrorChannel"/>
</int:transaction-synchronization-factory>
<int-file:outbound-channel-adapter channel="inputFileSuccessChannel"
directory="${archiveDir}"
delete-source-files="true"/>
<int-file:outbound-channel-adapter channel="inputFileErrorChannel"
directory="${errorDir}"
delete-source-files="true"/>
</beans>
My questions:
In a unit test context, how can I create & push an in-memory file in inputFileChannel, without relying on the real filesystem?
How can I test that my input file has been pushed to inputFileSuccessChannel / inputFileErrorChannel? How to mock the <int-file:outbound-channel-adapter/>?
Again in my unit test context without relying on the real filesystem, how can I test that my in-memory input file has been deleted (as configured with the delete-source-files="true" statements)?
At the moment, I have a JUnit 5 test class FileIntegrationTest.java:
#ExtendWith(SpringExtension.class)
#ContextConfiguration
#PropertySource("classpath:app.properties")
#SpringIntegrationTest
public class FileIntegrationTest {
#Autowired
MessageChannel inputFileChannel;
#Autowired
QueueChannel contentTestChannel;
#Test
void shouldReadInputFile_thenMoveIt() {
// arrange
File inputFile = new … // question 1
Message<File> inputMessage = MessageBuilder.withPayload(file).build();
// act
inputFileChannel.send(inputMessage);
// assert
assertThat(contentTestChannel.getQueueSize(), is(1));
assertThat(inputFileSuccessChannel contains my input file); // question 2
assertThat(inputFile has been deleted); // question 3
}
}
And its context file FileIntegrationTest-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"
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">
<import resource="classpath:/META-INF/spring/integration/file-integration.xml"/>
<int:bridge input-channel="contentChannel"
output-channel="contentTestChannel"/>
<int:channel id="contentTestChannel">
<int:queue/>
</int:channel>
</beans>
The official Spring Testing support page mentions the use of mocks, but I’m confused how to use it. I’ve checked out https://github.com/spring-projects/spring-integration-samples as well, but I could find a proper solution.

Yes
Add a channel interceptor to the channel, or see the documentation about mocking endpoints.
If you send a test file to the channel; you can check to see if still exists when the test completes.

Related

how to test a data source-based and websphere application using JUnit and IBM Rational Application Developer?

I have a package of many JAX-WS web services that run in WebSphere 7 where I had configured a data-source to a DB2 database including the JAAS authentication under an alias.
Now, i just want to test the logic of my DAOs, where -of course- I have an entity manager. So, I created an application client project, partially guided by this tutorial http://www.ibm.com/developerworks/rational/library/08/0219_jadhav/, where I have :
an application-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<application-client version="5"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application-client_5.xsd" metadata-complete="false">
<display-name>ServiciosAcademicoTests</display-name>
<resource-ref>
<res-ref-name>ServiciosAcademicoTests</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
a ibm-application-client-bnd.xml
<?xml version="1.0" encoding="UTF-8"?>
<application-client-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-client-bnd_1_0.xsd" version="1.0">
<resource-ref name="ServiciosAcademicoTests" binding-name="java:comp/env/jdbc/MyDB">
</resource-ref>
</application-client-bnd>
When I run my test, it returns the following error "Null userid is not supported." :
<openjpa-1.2.1- (...) fatal general error> org.apache.openjpa.persistence.PersistenceException: **Null userid is not supported.** ERRORCODE=-4461
I tried specifying and authentication in the ibm-application-client-bnd.xml but I'm still getting the same error :
<?xml version="1.0" encoding="UTF-8"?>
<application-client-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-client-bnd_1_0.xsd"
version="1.0">
<resource-ref name="ServiciosAcademicoTests" binding-name="java:comp/env/jdbc/MyDB">
<authentication-alias name="dmfloresNode01/XXX "/>
</resource-ref>
Just in case, my unit test is this :
public class CursosTest extends TestCase {
ICursoDAO cursoDAO; // From another project
Integer idAlumno = 123456;
String usuarioPortal = "xxx";
public void testCursosLlevados() throws Exception {
cursoDAO = new CursoDAO();
List<CursoLlevadoVO> lstCursos = cursoDAO
.obtenerCursosLlevadosPorAlumno(idAlumno, usuarioPortal);
if (lstCursos != null) {
for (CursoLlevadoVO cursoLlevadoVO : lstCursos) {
System.out.println(cursoLlevadoVO.getNombre());
}
}
assertNotNull(lstCursos);
}
}
I detected that the problem happen when the entitymanager is created :
entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
entityManager = entityManagerFactory.createEntityManager(); // <-- here
Could you help me, please ? two days looking for a solution :( .
UPDATE :
I think that my application-client even isn't querying the data source, because I changed the jdbc/MyDB to jdbc/XXX and the problem is the same (http://www-01.ibm.com/support/docview.wss?uid=swg21596108 , I'm not getting the "Could not lookup datasource named" message but it could be a cause). Also I tried to deactivate the authentication to the data source in the administrative console of Websphere, but I'm getting same results.
This is my persistence.xml file on the project of webservices (that runs fine, the problem is my application-client that is using a DAO class just for testing purposes, not for testing webservice just in case) :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="ServiciosAcademico">
<jta-data-source>jdbc/MyDB</jta-data-source>
<class>...</class>
<properties>
<property name="openjpa.jdbc.Schema" value="XXX"/>
</properties>
</persistence-unit>
. This is my data source on websphere, it's under a certain scope :
Day 3 :
Probably, when I remove the alias for the data source I get the same message, so the application-client could be ok about connecting to the data source, but this isn't using any authorization method.
Thanks for your help. I'm a novice of WebSphere.

how to config jax-ws Handler in Spring?

I according jax-ws API integration jax-ws with Spring ,but I get an exception at my webservice project,here is API site :http://jax-ws-commons.java.net/spring/ ,I have same config xml in my project,but i get an exception is below:
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'handlers' is not allowed to appear in element 'ws:service'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
who can give me solution?
The example given is wrong and not valid with regard to the schema. handlers is not an attribute, but a nested element. Use it like this:
<?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:wss="http://jax-ws.dev.java.net/spring/servlet"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core.xsd">
<wss:binding url="/services/demo">
<wss:service>
<ws:service bean="#demoEndpoint">
<ws:handlers>
<ref bean="demoHandler"/>
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
</bean>

Spring WS tutorial: no declarationcan be found for element 'context:component-scan' error

I'm following step-by-step (basically copying and pasting stuff) this spring-ws tutorial and I just hit a wall when configuring the spring-ws-servlet.xml 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:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
<context:component-scan base-package="com.mycompany.hr"/>
<sws:annotation-driven/>
</beans>
Adding the following line:
<context:component-scan base-package="com.mycompany.hr"/>
make STS starts yelling at me that:
cvc-complex-type.2.4.c: The matching wildcard is strict,
but no declarationcan be found for element 'context:component-scan'.
I don't know how to proceed..
You need to add:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
to the schemaLocation.

spring / metro / webservice problem

we try to use spring with metro stack to implement webservices.
The setup seems to be ok, but we get an error in the applicationContext.xml
cvc-complex-type.2.4.c: The matching
wildcard is strict, but no declaration
can be found for element
'wss:binding'.
I think that the published examples are out of date and that, for Spring 3, the binding has to be defined in a different way.
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:ws="http://jax-ws.java.net/spring/core"
xmlns:wss="http://jax-ws.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<wss:binding url="/ws">
<wss:service>
<ws:service bean="#webService"/>
</wss:service>
</wss:binding>
<!-- this bean implements web service methods -->
<bean id="webService" class="com.test.TestService"/>
</beans>
How do I have to configure the binding, or where can I find a description.
For a start, you seem to be missing this in your schemaLocation:
http://jax-ws.java.net/spring/core http://jax-ws.java.net/spring/core.xsd
http://jax-ws.java.net/spring/servlet http://jax-ws.java.net/spring/servlet.xsd
(more here, but I guess you've seen it already)

JPA 2 with managed transactions not persisting object

I'm using the OpenJPA implementation of JPA 2 and am having problems persisting an object to the database. I want to use transactions managed by the container (Websphere), so my understanding is that, since the transactions are managed, they boilerplate code like tx.begin(), tx.commit(), etc aren't needed.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="buildTest" transaction-type="JTA">
<jta-data-source>jdbc/lfcbuild</jta-data-source>
<class>entities.Build</class>
<properties>
<property name="openjpa.jdbc.Schema" value="APP"/>
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
</properties>
</persistence-unit>
</persistence>
The code I'm executing when persisting a build is this:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("buildTest");
EntityManager em = emf.createEntityManager();
Build b = new Build();
b.setFirstName("Dick");
b.setLastName("Tracy");
em.persist(b);
The code runs, and throws no exceptions. When I check the database, nothing has been persisted. Am I missing something, or should this be enough for the object to persist with container managed transactions?
Is that code part of an EJB? Otherwise you might have to start and commit the Tx programmatically.