1

I found a xml configured inbound adapter example what I do not fully understand. The configuration specifies a REST request setting request method, consumed format, etc.

I thought from the Spring Integration point of view the response should be much more important because the response is what is acutally feeding the message channel. Am I right?

The HTTP inbound adapter is used as message endpoint (actually a message startpoint) which calls a HTTP request - the URL of a REST service, let's say "http://myRest/transfer/next" - feeding a SI message channel with its result. Is that right?

It is either hard to find an example or to transform other examples into something which covers my needs. Even more as many examples are XML configured whereas I want to configure with Java or Dsl.

I am looking for an example where a REST service (which I will provide) is called which returns a JSON representation of TransferRequest object of mine which is fed into the SI channel "transfer_next_channel" to get processed by the Message Handler.

My code approach is rather skeleton-like. What do I have to do?

@Bean
public IntegrationFlow httpInboundFlow() {
    return IntegrationFlows
            .from(Http.inboundChannelAdapter("http://myRest/transfer/next")
                    .requestMapping(r -> r
                            .methods(HttpMethod.GET)
                            .consumes("text/html"))
                    .requestPayloadType(TransferRequest.class)
                    .headerMapper(myHeaderMapper)
                    )
            .channel("transfer_next_channel")
            .get();
}

@Bean
@ServiceActivator(inputChannel = "transfer_next_channel")
public MessageHandler handler() {
    return new MessageHandler() {
        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            System.out.println("myHandler: " + message.getPayload());
            System.out.println("myHandler: " + message.getHeaders());
        }
    };
}

EDIT 1

The whole thing is to generate a data message of a person from persistent DB state to a String message via TCP/IP. At first there is the information what message is needed. It is provided via external REST service. The result is a TransferRequest entity. From this the message has to be generated: another external REST service call to transform TransferRequest into some kind of DataMessage, the required data message. That result will be delivered via TCP/IP server as soon as a TCP/IP client has connected.

EDIT 2

The message channel is: starts with a request "http://myRest/transfer/next" to an external service, gets TransferRequest(containing a personId), push it as message into the channel, transformer/handler to request (another) external service "http://myRest/message/{personId}", gets DataMessage, push it as message into another channel, handler to push the message into a TcpOutboundGateway to be received by an external system.

JBStonehenge
  • 192
  • 3
  • 15

2 Answers2

2

Probably there is some misunderstanding in terminology:

  1. The Inbound Channel Adapter is an entry point for your application. We can call it server, which is expecting external requests and you do some logic downstream. With an Http.inboundChannelAdapter we talk about a Spring MVC controller.
  2. Unlike an Inbound Gateway, the Inbound Channel Adapter is a one-way entry point. So no reply (response) is expected for the external caller - the REST service.
  3. Another misunderstanding probably comes with misleading property names. Although they still are valid. The requestPayloadType is what makes conversion for the HTTP request body in that Inbound Channel Adapter and this data is going to be packed into the payload of the message to be sent to that transfer_next_channel.

You probably need to think of replacing your @ServiceActivator with a handle() like this:

 .channel("transfer_next_channel")
 .<TransferRequest>handle((p, h) -> )
 .get();

Note: you may not need that channel in between, the IntegrationFlow will take care of that for you.

Probably you to dig Spring Integration Reference Manual more to understand concepts of channel adapters, gateways and DSL.

Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • What scenario would you propose? I added **EDIT 1** to the question.. The end part made me think to use SI to benefit from its TCP/IP opportunities. So I thought I'll use a Http Inbound Adapter to request the REST service to feed the channel, do another REST request on the way to the TCP/IP endpoint. Now I understood the entry point has to be an Inbound Gateway, requesting the `TransferRequest` entity. – JBStonehenge Sep 01 '21 at 17:01
  • Still not clear from your description if you call some external REST service (being HTTP client) or you are the server for that exposed REST service. Let's assume the latest since you don't have the whole `http://` in your mapping, so what you need is a `transform()` to create that `DataMessage` for TCP call and then use a `handle(Tcp.outboundGateway())` – Artem Bilan Sep 01 '21 at 17:17
  • Thanks, Artem! Sorry, it is the first. So the mapping should have been `Http.httpInboundAnything("http://myRest/transfer/next")` since an external REST service is to be called to get the next person for whom to send a `DataMessage`. What does it change then? – JBStonehenge Sep 01 '21 at 22:14
  • It change it radically. You need then an `Http.outboundGateway()`. This is what we call `REST client`. The "outbound" means that we are going to call, not us. See more info in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/http.html#http-outbound – Artem Bilan Sep 01 '21 at 22:20
  • Thanks a lot, Artem! So you were right: Probably there is some misunderstanding in terminology. ... And I am at the very start again. – JBStonehenge Sep 01 '21 at 22:44
0

like this?

 @Bean
public IntegrationFlow httpInboundFlow() {
    return IntegrationFlows
            .from(Http.inboundGateway("/demo")
                    .replyChannel("reply")
                    .requestMapping(r -> r.methods(HttpMethod.GET))
                    .requestPayloadType(String.class)
            )
            .channel("next")
            .get();
}


@Bean
public MessageChannel reply() {
    return new QueueChannel();
}

@Bean
@ServiceActivator(inputChannel = "next",outputChannel = "reply")
public Function<Message<?>, String> handler() {
    return new Function<Message<?>, String>() {
        public String apply(Message<?> message) throws MessagingException {
            System.out.println("myHandler: " + message.getPayload());
            System.out.println("myHandler: " + message.getHeaders());
            return "ok";
        }

    };

}
yao Mr
  • 26
  • 2
  • Thanks a lot for your answer! Can you explain shortly, why Inbound Gateway instead of Inbound Adapter? – JBStonehenge Sep 01 '21 at 15:55
  • 1
    See my answer. See some short explanation of the difference in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/endpoint-summary.html#endpoint-summary – Artem Bilan Sep 01 '21 at 16:25