1
votes

Currently we are using Spring Integration 2.1.0 Release in our application. Application flow is as below:

  1. Some operation is performed in application and we got the output string in String via Active MQ.
  2. I have used message-driven-channel-adapter and service-activator to read the data from queue.
  3. That data is displayed successfully on Server(application is working as client) using tcp-outbound-gateway.
  4. Problem is while getting the acknowledgement from server.
  5. Created a new channel and entered in reply-channel in tcp-outbound-gateway
  6. Passing the same channel in service-activator as input channel.
  7. It is showing below error:

    [task-scheduler-5] 2017-10-05 18:32:20,732 ERROR org.springframework.integration.handler.LoggingHandler - org.springframework.integration.MessageDeliveryException: Dispatcher has no subscribers.
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:108)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:101)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    

Code is as below

<context:property-placeholder />

<!-- Gateway and connection factory setting -->
<int:channel id="telnetLandingChannel" />

<int:channel id="telnetReplyChannel" />

<beans:bean id="clientCustomSerializer"
    class="com.telnet.core.serializer.CustomSerializer">
    <beans:property name="terminatingChar" value="10" />
    <beans:property name="maxLength" value="65535" />
</beans:bean>

<int:gateway id="gw" default-reply-channel="telnetReplyChannel" default-reply-timeout="100000"
    service-interface="com.telnet.core.integration.connection.ParseTcpConfiguration$SimpleGateway"
    default-request-channel="telnetLandingChannel"/>

<ip:tcp-connection-factory id="clientFactory"
    type="client" host="localhost" port="7777" single-use="false" using-nio="false"
    serializer="${client.serializer}" deserializer="${client.serializer}"  />   

<ip:tcp-outbound-gateway id="clientInGw"
    request-channel="telnetLandingChannel"
    connection-factory="clientFactory"
    reply-channel="telnetReplyChannel"
    reply-timeout="100000"/>

<!-- To send the messege over server via JMS and serviceActivator -->
<int:channel id="incidentDispatchMessageChannel" />

<int:channel id="jmsChannel" />

<beans:bean id="customClientServiceActivator"
    class= "com.telnet.core.integration.CustomClientServiceActivator">
</beans:bean>


<int-jms:message-driven-channel-adapter id="incidentDispatchMessageChannelAdapter" error-channel="errorChannel"
    connection-factory="mqConnectionFactory"
    destination-name="${incident.processing.messaging.dispatch.queues}" 
    channel="incidentDispatchMessageChannel"/>

<int:service-activator id="incidentMessageActivator" 
    input-channel="incidentDispatchMessageChannel" 
    output-channel="jmsChannel"
    ref="customClientServiceActivator" method="getOutboundMessage">
</int:service-activator>

<int:object-to-string-transformer id="clientBytes2String"
    input-channel="jmsChannel" 
    output-channel="telnetLandingChannel"/>

<!-- To receive the acknowledgement message on server via serviceActivator -->      
<int:service-activator id="incidentAck" 
    input-channel="telnetReplyChannel" 
    ref="customClientServiceActivator" method="getAck">
</int:service-activator>

I have studied various article on stackverFlow but not able to get any solution

2

2 Answers

0
votes

Yeah... That isn't clear by the error what channel is guilty.

On the other hand you really use very old Spring Integration version. Would be great to consider to upgrade to the latest: http://projects.spring.io/spring-integration/.

However I think that issue is somehow around exactly that reply-channel, which you use not only for the <service-activator> but for the <int:gateway> as well.

I suggest you to remove default-reply-channel="telnetReplyChannel" from the gateway definition, remove reply-channel="telnetReplyChannel" from the <ip:tcp-outbound-gateway> definition. And let them communicate via replyChannel header populated by the gateway during request.

Regarding your <int-jms:message-driven-channel-adapter> flow which leads to the same <ip:tcp-outbound-gateway>, I would suggest to still stay with the replyChannel header but here populate it via <header-enricher> before sending message to the telnetLandingChannel. That replyChannel via <header-enricher> would be exactly an input-channel for the subsequent <int:service-activator> to handle ack from the <ip:tcp-outbound-gateway>.

0
votes

I got the solution of this issue, there are multiple xmls in our code but i have added the code in one to show flow in stackOverflow. Issue was i had defined in a xml which has only configuration part like Outbound adapter connection factory where as it should be defined in another xml where I am using service activator. Changed the place of channel definition and it worked.

I want to disconnect the TCP (as server) the moment i got the response message. As of now I am using so-timeout, so my TCP server will gets timedout after the time given in so-timeout, but requirement is to disconnect the connection the moment TCP print/display the acknowledgement. Please suggest how can I implement this.