0

I’m struggling to find good examples of Spring Integration using the MarshallingWebServiceInboundGateway

I put together a working sample that uses MarshallingWebServiceInboundGateway to expose an Order service, and when called it consumes an order detail service using the MarshallingWebServiceOutboundGateway

https://github.com/yortch/spring-integration-demo/blob/outboundgateway/services/order-flow/src/main/java/com/demo/integration/order/OrderEndpoint.java

    @ServiceActivator(inputChannel= ChannelNames.ORDER_INVOCATION, outputChannel = ChannelNames.ORDER_DETAIL_REQUEST_BUILDER)
    OrderRequest getOrder(OrderRequest orderRequest) {
        return orderRequest;
    }

This is somehow working, however my expectation for the method below is that this should be the signature of the web service method, i.e. return an OrderResponse type. I had this initially working this way when I was manually building the OrderResponse by calling other POJOs, however I can’t figure out how to keep the original web service method signature and internally use Spring Integration for the implementation, i.e via calling a channel to do the transformation and in turn call the order detail service (using MarshallingWebServiceOutboundGateway).

If you know any code examples for doing this, please share. I came across this one, but this is directly building the response (without using Spring Integration channels): https://bitbucket.org/tomask79/spring-boot-webservice-integration/src/master/

  • Your question is not clear. Everything what you need is a `MarshallingWebServiceInboundGateway` `@Bean` definition and `@EnableIntegration`. However according your description it looks like you have everything on board. Please, elaborate more what doesn't work and how you would like to see it working? – Artem Bilan May 15 '19 at 16:35
  • I would like to preserve the signature of the web service API, i.e. getOrder method should return an OrderResponse instead of OrderRequest... ``` OrderResponse getOrder(OrderRequest orderRequest) { \\return OrderResponse generated via calling a Spring Integration channel } ``` However if I change the method signature, I can't figure out how to return the output of a Spring Integration channel that would return the OrderResponse instance – Jorge Balderas May 15 '19 at 19:00
  • That's still unclear. You just have such a `@ServiceActivator` method and create that `OrderResponse` yourself for return. If this is the end of integration flow, that object becomes a `payload` of reply message. The `MarshallingWebServiceInboundGateway` will take care then about the proper marshalling for this `OrderResponse` object. – Artem Bilan May 15 '19 at 19:14
  • Correct, I could build `OrderResponse` directly, however I also have a `@Transformer`(https://github.com/yortch/spring-integration-demo/blob/a18974829ea4667d1f7f649db88b46bd035c5a0d/services/order-flow/src/main/java/com/demo/integration/transformer/OrderDetailTransformer.java#L24) that builds an `OrderDetailRequest` which in turn is used to call another web service using `MarshallingWebServiceOutboundGateway`. I'd like to be able to build the `OrderResponse` object by calling my @Transformer\MarshallingWebServiceOutbountGateway route. Is there a way to invoke the @Transformer programmatically? – Jorge Balderas May 15 '19 at 19:28

1 Answers1

0

Sounds like some misunderstanding what is Spring Integration flow and how its endpoints work.

  1. Three first class citizens in Spring Integration: Message, Channel, Endpoint
  2. Endpoints are connected via channels
  3. Endpoints consume messages from their input channels
  4. Endpoints may produce messages as a result of their calculation into the output channels.

So, in your case you want to expose a SOAP service which is going to call internally another SOAP service.

You have started properly with the MarshallingWebServiceInboundGateway. This one, I guess, produces into its channel an OrderRequest object. It expects an OrderResponse in its replyChannel (explicit or temporary in headers). I'm not sure what your getOrder() does, but if there is yet a transformer and MarshallingWebServiceOutboundGateway, you need to consider to connect them all into the flow. So, I think that a result of your service, should go to the channel which is an input for the transformer. An output of this transformer should go to the MarshallingWebServiceOutboundGateway. And result of this gateway may go to some other transformer to build an OrderResponse which may just go into the reply channel of the MarshallingWebServiceInboundGateway.

If that's not what you expect as an explanation, I then will request you to rephrase your question...

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • That is actually what I already have in place, but what I was hoping to accomplish is to combine the `@ServiceInvocation` method and the reply channel method into one “send and receive” method so that it’s clear that the `getOrder` method takes an `OrderRequest` and returns an `OrderResponse`. It sounds like either this is not feasible or not the “right” way to do it with Spring Integration? – Jorge Balderas May 15 '19 at 21:27
  • It can be done with the `@MessagingGateway` call from that `@ServiceActivator` method: https://docs.spring.io/spring-integration/docs/current/reference/html/#gateway. Although it doesn't sound for me a reasonable to do that fine-graining since we can just do a normal flow with direct channels and endpoints composition. – Artem Bilan May 15 '19 at 21:30
  • That is what I suspected, it sounds like what I have already in place is the better way to go. Unfortunately this makes our code flow harder to follow. Thank you Artem for your input and for taking the time! – Jorge Balderas May 16 '19 at 15:10