Receiving messages from tcp server with Citrus framework and Spring Integration times out

我的未来我决定 提交于 2019-12-23 21:16:32

问题


I am trying to test a simple tcp send/receive sequence making use of citrus framework. I am able to send messages fine but receiving messages proves problematic. Basically, the reply is not detected by citrus and citrus then times out.

Citrus bean 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:citrus="http://www.citrusframework.org/schema/config"
   xmlns:int="http://www.springframework.org/schema/integration"
   xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

    http://www.citrusframework.org/schema/config http://www.citrusframework.org/schema/config/citrus-config.xsd
    http://www.springframework.org/schema/integration  http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/ip  http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">

<citrus:channel-endpoint id="citrusServiceInputEndpoint"
                         channel-name="input" />

<citrus:channel-endpoint id="citrusServiceRepliesEndpoint"
                         channel-name="replies" />

<int-ip:tcp-connection-factory id="client"
                               type="client" host="localhost" port="9123" single-use="false"
                               so-timeout="10000" using-nio="true" />

<int:channel id="input" />

<int:channel id="replies">
    <int:queue capacity="10" />
</int:channel>

<int-ip:tcp-outbound-channel-adapter
        id="outboundClient" channel="input" connection-factory="client" />

<int-ip:tcp-inbound-channel-adapter
        id="inboundClient" channel="replies" connection-factory="client" />

Citrus test case:

@Test
@CitrusTest(name = "sendSpringIntegrationMessageTest")
public void sendSpringIntegrationMessageTest() throws Exception {
    send("citrusServiceInputEndpoint").payload("Req");
    receive("citrusServiceRepliesEndpoint").payload("Rsp");
}

Im using a simple netcat server to test:

nc -kl 9123

When running the test case, the "Req" text arrives fine on netcat. However, when typing "Rsp" on netcat, the data does not arrive at the citrus test. After about 5 seconds, the test case fails with the following message:

com.consol.citrus.exceptions.TestCaseFailedException: Test case failed

at com.consol.citrus.TestCase.executeAction(TestCase.java:218)
at com.consol.citrus.TestCase.doExecute(TestCase.java:139)
at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
at com.consol.citrus.Citrus.run(Citrus.java:243)
at com.consol.citrus.dsl.junit.JUnit4CitrusTest.invokeTestMethod(JUnit4CitrusTest.java:90)
at com.consol.citrus.dsl.junit.JUnit4CitrusTestDesigner.invokeTestMethod(JUnit4CitrusTestDesigner.java:68)
at com.consol.citrus.dsl.junit.JUnit4CitrusTest.run(JUnit4CitrusTest.java:71)
at com.consol.citrus.junit.CitrusJUnit4Runner$InvokeRunMethod.evaluate(CitrusJUnit4Runner.java:212)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.consol.citrus.exceptions.ActionTimeoutException: Action timeout while receiving message from channel 'replies'
    at com.consol.citrus.channel.ChannelConsumer.receive(ChannelConsumer.java:97)
    at com.consol.citrus.messaging.AbstractSelectiveMessageConsumer.receive(AbstractSelectiveMessageConsumer.java:50)
    at com.consol.citrus.actions.ReceiveMessageAction.receive(ReceiveMessageAction.java:146)
    at com.consol.citrus.actions.ReceiveMessageAction.doExecute(ReceiveMessageAction.java:125)
    at com.consol.citrus.actions.AbstractTestAction.execute(AbstractTestAction.java:42)
    at com.consol.citrus.TestCase.executeAction(TestCase.java:211)
    ... 33 more

So basically Citrus didn't receive the response. Note that I have to define a queue for the replies channel as this is what Citrus expects, the reply channel must implement Interface PollableChannel.

Please help me understand as to why the data is not received by Citrus from the queue?


回答1:


By default, the tcp connection factory expects messages to be delimited by \r\n.

nc terminates the response with just \n so the connection factory doesn't see a complete message.

See the discussion in the documentation about serializers/deserializers. You need to configure the serializer and deserializer to point to a ByteArrayLfSerializer bean which just expects \n to terminate the message.




回答2:


Here is the correct bean config to make this test work. Added the serializer/deserializer as suggested by Gary.

I also had to add an Message transformer (object-to-string-transformer) as the data made available by Spring on the replies channel will be of type byte[]. Citrus expects to validate against a String type so a transformation is necessary to convert the byte array to a string.

Hopefully it would help someone in future!

<?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:citrus="http://www.citrusframework.org/schema/config"
   xmlns:int="http://www.springframework.org/schema/integration"
   xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.citrusframework.org/schema/config http://www.citrusframework.org/schema/config/citrus-config.xsd
http://www.springframework.org/schema/integration  http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ip  http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">

<citrus:channel-endpoint id="citrusServiceInputEndpoint"
                         channel-name="input" />

<citrus:channel-endpoint id="citrusServiceRepliesEndpoint"
                         channel-name="response" />

<int-ip:tcp-connection-factory id="client"
                               type="client" host="localhost" port="9123" single-use="false"
                               so-timeout="10000" using-nio="true" deserializer="javaSerializer"
                               serializer="javaSerializer" />

<bean id="javaSerializer"
      class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer" />

<int:channel id="input" />

<int:channel id="replies">
</int:channel>

<int:channel id="response">
    <int:queue />
</int:channel>

<int:object-to-string-transformer id="transformer" input-channel="replies" output-channel="response" />

<int-ip:tcp-outbound-channel-adapter
        id="outboundClient" channel="input" connection-factory="client" />

<int-ip:tcp-inbound-channel-adapter
        id="inboundClient" channel="replies" connection-factory="client" />



来源:https://stackoverflow.com/questions/36772833/receiving-messages-from-tcp-server-with-citrus-framework-and-spring-integration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!