1
votes

I want to check the status of the TCP Adapter(Client/Server connection factory) whether the adapter is connected or not.

This Question is posted in continuation with this Question but with some other issue.

After changing the method name : from: isConnected() to isClientModeConnected()

I have to change my control Bus Bean definition Earlier no output channel is configured hence its giving error

 @Bean
public IntegrationFlow controlBus() {
    return IntegrationFlowDefinition::controlBus;
}

Now,

@Bean
public IntegrationFlow controlBusFlow() {
    return IntegrationFlows.from(directChannel())
            .controlBus().channel(directChannel()).handle(System.out::println)
            .get();
}

also, my control Bus command method is now,

public boolean isConnectionAdapterConnected(String connectionName) {
        MessageChannel controlChannel = ac.getBean("controlBusFlow.channel#0", MessageChannel.class); 
        String exp = "@"+connectionName+"adapter"+".isClientModeConnected()";
    boolean status = controlChannel.send(new GenericMessage<String>(exp));
        return status;

    } 
  • whether its connected or not it always return true in status isConnectionAdapterConnected(String connectionName) method.
  • But my service activator in the controlbusflow Bean definition consist of message with actual correct status it means the above status is not the status of the adapter, actual status is received in service activator defined in controlBusFlow Bean,

I have created an API in which the user calls the function to check status of adapter whether its connected or not.

Issue:

  • How can I configure the application to return the status of the adpater from isConnectionAdapterConnected(String connectionName) method when the user calls this method as the actual status is received in Service activator of controlBusflow Bean Definition.
  • Also, How can I check the status of TCP adapter with server connection factory is in connected state or not as this method is only for TCP adapter with client connection factory

EDIT

By using appraoch defined by Mr. Artem Bilan , the first issue is resolved.

But for 2nd issue:

This is the integration flow which is registered at runtime with unique ID.

      IntegrationFlow flow = 
       IntegrationFlows.from(Tcp.inboundAdapter(Tcp.netServer(port)
      .serializer(customSerializer)
      .deserializer(customSerializer)
      .id(connectionName+"server").soTimeout(10000)))
      .enrichHeaders(f->f.header("abc","abc")))
      .channel(directChannel())
      .handle(Jms.outboundAdapter(ConnectionFactory())
      .destination("jmsInbound"))
      .get();

  theFlow =this.flowContext.registration(flow).id(connectionName+".flow").register();

The above flow get registered with unique id , suppose there are 3 server created then the above 3 flows will be registered (iterating the above flow 3 times in for loop) , so how can i get reference of AbstractServerConnectionFactory from registered flow so that I can get openConnectionIds.

1
I can't parse your first issue; please try rephrasing it, showing code and DEBUG logs and exactly what you mean. For your second issue; you can call getOpenConnectionIds() on any connection factory (but not with the control bus).Gary Russell
See my answer, please, and feel free to correct if I'm wrong somewhere.Artem Bilan

1 Answers

2
votes

How can I configure the application to return the status of the adpater from isConnectionAdapterConnected(String connectionName) method when the user calls this method as the actual status is received in Service activator of controlBusflow Bean Definition.

For this purpose you need to configure a @MessagingGateway to send to Control Bus channel and expect reply.

What you do now with the boolean status = controlChannel.send(new GenericMessage<String>(exp)); is fully wrong. That status is a result of MessageChannel.send() operation. There is nothing related to your target isClientModeConnected() call.

What I would do is like this:

@MessagingGateway(defaultRequestChannel = "controlBus.input")
public interface ControlBusGateway {

    Object execute(String command);

}

...

@Bean
public IntegrationFlow controlBus() {
     return IntegrationFlowDefinition::controlBus;
}

This way the request-reply scenario will be performed and a replyChannel header is going to be populated into the message sent to the Control Bus. Then this isClientModeConnected() is going to be executed and the result will be returned to the gateway call. Than you cast it into Boolean and that's it!

The server side is not related to the Channel Adapter at all. Only the AbstractServerConnectionFactory matters. See its:

/**
 * Returns a list of (currently) open {@link TcpConnection} connection ids; allows,
 * for example, broadcast operations to all open connections.
 * @return the list of connection ids.
 */
public List<String> getOpenConnectionIds() {

on the matter. That's exactly what Gary said you. I think you can wrap this call to a simple service with the @ManagedAttribute on the method call to let it to be performed via Control Bus.