Spring Integration Channel Interceptor SOAP Envelope - spring-integration

Is there any way to get the entire SOAP message inside channel interceptor call back methods ? Is there any MessageContext injected by default to any of the callback methods?

The question doesn't sound good. The ChannelInterceptor does not do anything with SOAP. They know only about the channels and messages to pass.
In general Spring Integration is stateless, so no any context injected to the channel interceptor.
Any MessageContext is responsibility of your own application.
One of the approach is a MessageHeaders as I recommend you in your other questions: before sending message to the channel you store something to its headers and than you have access to that object from the channel interceptor methods via provided message.

Related

Difference between Spring Inbound channel adapters and application event listing message producers

I am working on a POC using Spring Integration and STOMP. The initial POC is successful.
I followed the adapters configuration mentioned in https://docs.spring.io/spring-integration/reference/html/stomp.html#stomp
In my POC, I did not include the last two #Bean definitions from the above link.
Inbound Channel Adapter and Message Handlers were sufficient to handle the incoming messages.
Now, my question is:
What is the difference between Inbound channel adapters and application event listing message producers?
Is ApplicationListener used when we follow DSL as mentioned in an example here?
Thanks,
Mahesh
Well, as you noticed in that Spring Integration documentation about STOMP support there is some bunch of ApplicationEvents emitted by STOMP Channel Adapters. You indeed can handle them using regular ApplicationListener (#EventListener) if your logic for handling those events is pretty much simple and doesn't need further distribution. But if your logic is much complicated and you may need store an even (or its part) in some database, or send via email, do that in parallel after some aggregtion, etc., then indeed that ApplicationEventListeningMessageProducer is much better solution when we have Spring Integration on board already.
However if you talk about a StompInboundChannelAdapter nature and relationship with those mentioned events, you need to take a look into the StompIntegrationEvent implementations. You quickly realize that there is no events for payload in the STOMP frame. So, that is what is done really by the StompInboundChannelAdapter - it produces messages based on the body from STOMP frame.
All the mentioned events emitted fro that channel adapter are more about that adapter state sharing for possible management in your application.

How to expose SOAP Web Service using MarshallingWebServiceInboundGateway (with Spring Integration DSL)

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/
Sounds like some misunderstanding what is Spring Integration flow and how its endpoints work.
Three first class citizens in Spring Integration: Message, Channel, Endpoint
Endpoints are connected via channels
Endpoints consume messages from their input channels
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...

Spring Integration: channel interceptor vs endpoint?

When dealing with an enterprise integration flow in Spring-integration, is it more "proper" to handle concerns such as transmission validation and state tracking in Channel Interceptors, or endpoints like Service Activators and Filters? Or is that purely a matter of style?
Generally it's just style but most people prefer to limit interceptors for simple stuff like wiretapping, logging, etc, or something you want to apply globally to multiple channels via a global interceptor that matches on channel name patterns.
But, it's not unusual to do validation in an interceptor.
Not sure what you mean by "state tracking" but, generally, that's handled in message headers (when you want to pass state from one endpoint to another).

Send data to a Channel from a callback method (Spring Integration)

I have a method that is called as a callback from some communication library when data are received.
Using Spring Integration, I would like to send data to a specific Channel that will be later picked up by some Sender and some Database Recorder. These two may work in parallel. How could I do it?
I prefer not to use XML for anything.
These two may work in parallel.
For this purpose Spring Integration provides PublishSubscribeChannel. With its executor option you really can make subscribers working in parallel.
I would like to send data to a specific Channel
So, just do that from that callback method.
You can consider to use Messaging Gateway for dependency injection instead of direct channel injection for sending.
That way you will call the gateway's method from that callback and the data will be send to predefined PublishSubscribeChannel channel for distribution between its subscribers.
how do I create that "existing channel"
That's all about Spring and its inversion of control implementation.
You may consider to consult existing Spring Integration Samples for ideas.

How to get JMSMessageId after sending it with an outbound-channel-adapter?

I am sending a JMS message with the outbound channel adapter like this:
<intjms:outbound-channel-adapter
destination-name="MY.QUEUE"
connection-factory="myConnectionFactory"
channel="mySender"/>
After this I need to know the JMS Message Id. How can I get it?
There is a way to do it in a custom JmsTemplate I could provide in the adapter, but maybe there is a simpler solution for this problem.
I can not use the gateway because there is no response.
You can send JMS Message as a payload of Spring Integration Message to that adapter. And use its getJMSMessageID() after successful sending.
UPDATE
But this means I can not use the convencience of the JmsTemplate and have to deal with javax.jms.Connection and javax.jms.Session on my own to be able to create a javax.jms.Message, correct?
Well, no one forbid you to use even JmsTemplate directly as a reference from the general <service-activator>. The <outbound-channel-adapter> is one-way by the goal. So it is really not intended to return anything. Your corner case really requires something to do. And that is the javax.jms.Session hooks and tricks to create a JMS Message to be able to retrieve its ID afterwards. There is a ThreadLocal hole over the custom JmsHeaderMapper and the message access from its fromHeaders() implementation, but I think that for this case it would be better to use JmsTemplate directly.

Resources