Hi I am currently using Spring Integration 4.0.3.I have a requirement of logging the actual request which are coming to the Http Inbound Gateways.The request are to be logged before they are converted into a message by the Http Inbound Messaging Gateway and sent to the gateway request channel.This is how I am trying to achieve this .
Configured a aop pointcut on the HttpRequestHandlingMessagingGateway class handleRequest method.
Configured a custom method Interceptor as an advice and configured the pointcut to execute this advice in the aop config.
In the MethodInterceptor I am retreiving the Request and Response object and logging the request.
But it seems whenever I am applying the aop on handleRequest method the dispatcher servlet is unable to find the handler for any of the url mapping used by all of my http inbound gateways.
I know the same can be achieved through configuring filters in web.xml but I am just curious why this is happening....Please help ...
Actually you can't proxy HttpRequestHandlingMessagingGateway#handleRequest because it is final.
From other side there is no reason to do so complex AOP work for that logging stuff.
HttpRequestHandlingMessagingGateway populates RequestContextHolder.currentRequestAttributes() as EvaluatationContext variable, so you can put it to MessageHeader and use anywhere in downstream flow:
<int-http:inbound-gateway path="/foo" request-channel="requestChannel">
<int-http:header name="requestAttributes" expression="#requestAttributes"/>
</int-http:inbound-gateway>
<publish-subscribe-channel id="requestChannel"/>
<logging-channel-adapter channel="requestChannel"
expression="headers.requestAttributes.request"/>
Related
I need to do some validations on the input http headers, trying to write GET http rest api with some http headers, need to validate if one of the headers has specific value, if not throw an exception. I have used http inbound gateway, created error-channel and using service activator to notify error handler, I am getting below error,
No reply received from error channel within timeout
My code looks like,
<int-http:inbound-gateway
request-channel="sampleRequestChannel"
reply-channel="sampleResponseChannel"
error-channel="apiErrorChannel"
reply-timeout="15000"
supported-methods="GET"
path="/test/{testId}"
mapped-request-headers="*"
payload-expression="#pathVariables.testId">
<int-http:header name="source" expression="#requestParams[source]"/>
</int-http:inbound-gateway>
<int:service-activator input-channel="sampleRequestChannel" ref="testAdapterController" method="getDetails" output-channel="testSourceRouter"/>
<int:service-activator input-channel="apiErrorChannel" ref="testErrorHandler" method="handleFailedRequest" output-channel="sampleResponseChannel"/>
<bean id="loadErrorHandler" class="com.test.adapter.controller.TestErrorHandler"/>
<int:router input-channel="testSourceRouter" expression="headers.source">
<int:mapping value="ABCD" channel="callABCDChannel"/>
<!--<int:mapping value="std" channel="intermediateStdChannel"/>-->
</int:router>
I am throwing exception in the code but its not reaching to the output channel even though I tried using output channel as reply channel.
I can see exception being thrown in my console logs but api doesn't throw it as a part of api response. I am pretty sure my understanding of working with spring integration is very limited, just started to work with it.
could someone please help?
To re-throw an exception to MVC there is just enough to not have that error-channel="apiErrorChannel" configured.
If you'd like to swallow it and return something else, then your testErrorHandler must return that object.
This is going to work as is if all your channels in the flow are DirectChannel which is a default type. If it is not, then you must look into this section of the doc and ensure an errorChannel downstream as a header: https://docs.spring.io/spring-integration/docs/current/reference/html/error-handling.html#error-handling
How can I consume Server Sent Events with Spring Integration? I am aware Spring supports SSE with Webflux, but how to convert the incoming Flux into separate Message instances? And possibly wrap this code into some Spring-Integration-Lifecycle-aware component (MessageProducerSupport?)
WebClient client = WebClient.create("http://myhost:8080/sse");
ParameterizedTypeReference<ServerSentEvent<String>> type
= new ParameterizedTypeReference<ServerSentEvent<String>>() {};
Flux<ServerSentEvent<String>> eventStream = client.get()
.uri("/stream-sse")
.retrieve()
.bodyToFlux(type);
eventStream.subscribe(
content -> ;/* here I believe the message should be produced/sent to a channel */ );
See Spring Integration WebFlux Outbound Gateway: https://docs.spring.io/spring-integration/docs/current/reference/html/webflux.html#webflux-outbound:
The setExpectedResponseType(Class<?>) or setExpectedResponseTypeExpression(Expression) identifies the target type of the response body element conversion. If replyPayloadToFlux is set to true, the response body is converted to a Flux with the provided expectedResponseType for each element, and this Flux is sent as the payload downstream. Afterwards, you can use a splitter to iterate over this Flux in a reactive manner.
WebFlux.outboundGateway("http://myhost:8080/sse/stream-sse")
.httpMethod(HttpMethod.GET)
.replyPayloadToFlux(true)
.setExpectedResponseTypeExpression(new ParameterizedTypeReference<ServerSentEvent<String>>() {})
To make it start working just after an application is ready, yo can implement an ApplicationRunner to send a "void" message into a channel for the flow with that WebFlux.outboundGateway(). I don't think we need a special, dedicated component just for SSE requesting and producing. The combination of existing components is fully enough.
We have a requirement to add the traceability (to add trace-id and spell-id) for incoming and outgoing JMS messages in controller module which is based on Spring Integration. Can anyone help me with the interceptor that can be used for this which can intercept all request coming into JMS queue and all the request that will be send onto the queue.
Below is the code snippet:
<!-- Need to trace the message once we receive in incoming_queue -->
<int-jms:message-driven-channel-adapter id="jmsIn" channel="channel_1"
destination-name="incoming_queue"></int-jms:message-driven-channel-adapter>
<!-- Need to trace the message before we send the message to outgoing_queue -->
<int-jms:outbound-channel-adapter id="jmsOut"
channel="channel_1" connection-factory="connectionFactory"
destination-name="outgoing_queue"/>
Thanks
On both side there is a DefaultJmsHeaderMapper with this JavaDoc:
* This implementation copies JMS API headers (e.g. JMSReplyTo) to and from
* Spring Integration Messages. Any user-defined properties will also be copied
* from a JMS Message to a Spring Integration Message, and any other headers
* on a Spring Integration Message (beyond the JMS API headers) will likewise
* be copied to a JMS Message. Those other headers will be copied to the
* general properties of a JMS Message whereas the JMS API headers are passed
* to the appropriate setter methods (e.g. setJMSReplyTo).
So, if your those trace-id and spell-id are in compatible types:
private static List<Class<?>> SUPPORTED_PROPERTY_TYPES = Arrays.asList(new Class<?>[] {
Boolean.class, Byte.class, Double.class, Float.class, Integer.class, Long.class, Short.class, String.class });
You are good to send and receive those headers.
If you think about something like logging those headers, you definitely can take a look into the ChannelInterceptor implementation to log those headers before/after sending/receiving to/from JMS.
I have a ws:outbound-gateway in place pointing to a org.springframework.ws.transport.jms.JmsMessageSender class in order to push a Soap message into the queue.
The output message has been generated okay and published into the queue normally with the following JMS properties on it: SOAPJMS_soapAction, SOAPJMS_contentLength, SOAPJMS_contentType, etc.
My question is: how can I add a custom JMS property as part of the JMS properties generated by default? Is this possible? I'm using Spring Integration 4.3.5.RELEASE.
The JmsMessageSender can be supplied with the MessagePostProcessor.
The you can supply any desired JMS property on target Message.
I'm using RestTemplate from Spring v4 to send http requests. RestTemplate uses Apache HttpClient v4 under the hood and I'm using Jackson v2 for pojo-json conversion.
I have Log4J working. How can I configure log4j.properties to show the sent json data in the logs?
Enabling these loggers in "FINEST" level didn't help:
org.springframework.http
org.apache.http
org.apache.commons.httpclient
httpclient
org.apache.logging.log4j.core.jackson
I'd prefer doing it via log4j.properties than coding some sort of interceptor (which I'll want to keep only in dev). But do let me know of other ways.