Could you tell me how to log the SOAP Message send/received of int-ws:outbound-gateway ?
I have tried
<int-ws:outbound-gateway id="ais-outbound-gateway"
request-channel="aisRequestChannel" reply-channel="aisResponseChannel"
uri="http://localhost:8080/services/ONESHOT"
marshaller="aisMarshaller" unmarshaller="aisMarshaller" />
<int:channel id="aisRequestChannel">
<int:interceptors>
<int:wire-tap channel="logChannel"/>
</int:interceptors>
</int:channel>
<int:channel id="aisResponseChannel">
<int:interceptors>
<int:wire-tap channel="logChannel"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter expression="payload" id="logChannel" level="DEBUG" />
But the payload is just java object, not SOAP message.
Best regards,
The <int-ws:outbound-gateway> supports interceptor injection:
<xsd:documentation>
Reference to the bean definition of a ClientInterceptor.
</xsd:documentation>
So, you should implement your own LoggingClientInterceptor.
The logging ideas you can borrow from the existing PayloadLoggingInterceptor.
Related
I am working on the spring integration http. Wanted to make multiple http calls and collect the response to one common java object. I am facing an issues which says no output/reply channel at the end of the aggregator.
This is the xml definition
<int:channel id="intermediateWChannel">
<int:interceptors>
<int:wire-tap channel="intermediateWLogger" />
</int:interceptors>
</int:channel>
<int:channel id="intermediateSChannel">
<int:interceptors>
<int:wire-tap channel="intermediateSLogger" />
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="intermediateWLogger" expression="'Fetch Wtms Trip : '.concat(payload)" level="INFO" />
<int:logging-channel-adapter id="intermediateSLogger" level="INFO" />
<int:chain input-channel="intermediateSChannel" output-channel="publishsubscribechannel">
<int-http:outbound-gateway
id="outboundGateway"
url="{url2}"
http-method="GET"
request-factory="requestFactory"
charset="UTF-8"
mapped-request-headers="Accept:application/json"
expected-response-type="java.lang.String"></int-http:outbound-gateway>
<int:object-to-json-transformer/>
</int:chain>
<int:chain id="chain2" input-channel="publishsubscribechannel" output-channel="aggregatorChannel">
<int:transformer ref="fetchTransformer" method="process" />
</int:chain>
<int:chain id="request-chain" input-channel="publishsubscribechannel" output-channel="aggregatorChannel">
<int-http:outbound-gateway
id="strideOutboundGateway1"
url="url3"
http-method="GET"
request-factory="requestFactory"
charset="UTF-8"
mapped-request-headers="Accept:application/json"
expected-response-type="java.lang.String"></int-http:outbound-gateway>
<int:transformer ref="fetchTransformer" method="process1" />
</int:chain>
<int:chain id="chain3" input-channel="aggregatorChannel" output-channel="outputChannel">
<int:aggregator id="tAggregator"
ref="tDataAggregator"
method="processAggregator"
correlation-strategy-expression="headers['id']"
release-strategy="aggregatorReleaseStrategy"
expire-groups-upon-completion="true"/>
</int:chain>
But, I have specified the output channel in the aggregator.
Below is the exception and even if I add the reply-channel in headers, application is going for stackoverflow.
org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:452) ~[spring-integration-core-5.5.13.jar:5.5.13]
at org.springframework.integration.handler.AbstractMessageProducingHandler.doProduceOutput(AbstractMessageProducingHandler.java:325) ~[spring-integration-core-5.5.13.jar:5.5.13]
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:268) ~[spring-integration-core-5.5.13.jar:5.5.13]
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:232) ~[spring-integration-core-5.5.13.jar:5.5.13]
The transformer is different from other endpoints that it does not modify a Message we return from its method call. It is counted as transformer has a full control over the reply message creation. So, if there is a need to preserve some request message headers, it is recommended to use a MessageBuilder.copyHeadersIfAbsent() API. This way in request-reply scenario, the necessary replyChannel header is present in the reply message.
We probably have to mention shouldCopyRequestHeaders() behavior for the transformer in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/message-transformation.html#messaging-transformation-chapter. Feel free to raise a GH issue.
I am doing Spring Integration with Server and Client request/response demo. The request comes with a Byte array which is to be converted to Object. Then the request comes to the input channel, I need to check which class is to be send to the service activator. Then the service activator will send it to the reply channel.
<bean id="javaSerializer"
class="org.springframework.core.serializer.DefaultSerializer"/>
<bean id="javaDeserializer"
class="org.springframework.core.serializer.DefaultDeserializer"/>
<!-- single-use="true" : A new message has to wait until the reply to the previous message has been received -->
<int-ip:tcp-connection-factory id="server"
type="server"
host="localhost"
port="10101"
single-use="true"
so-timeout="10000"
serializer="javaSerializer"
deserializer="javaDeserializer"
task-executor="severTaskExecutor"/>
<int-ip:tcp-inbound-gateway id="inGateway"
request-channel="inputChannel"
reply-channel="replyChannel"
connection-factory="server"
reply-timeout="10000"/>
<int:channel id="inputChannel"/>
<!-- How to switch the request to the different channel??? -->
<int:channel id="myChannelOne"/>
<int:channel id="myChannelTwo"/>
<int:service-activator
input-channel="myChannelOne"
output-channel="replyChannel"
ref="myServiceOne"
method="get" />
<int:service-activator
input-channel="myChannelTwo"
output-channel="replyChannel"
ref="myServiceTwo"
method="get" />
<int:channel id="replyChannel"/>
<bean id="myServiceOne" class="com.my.demo.MyServiceOne"/>
<bean id="myServiceTwo" class="com.my.demo.MyServiceTwo"/>
Use a payload type router https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#router-implementations-payloadtyperouter
<int:payload-type-router input-channel="routingChannel">
<int:mapping type="java.lang.String" channel="stringChannel" />
<int:mapping type="java.lang.Integer" channel="integerChannel" />
</int:payload-type-router>
I am using Spring integration with Oracle AQ,configuration code is as below.
Currently with the below configuration,the service activator is not getting invoked consistently with even the dequeue was successful at oracle end, unable to trace the message after successful Dequeue with the application logs, not even single error message shown on the log. Tried Debug,Trace and info options in the jms adaptor, but no clue from the log details. I have verified with Oracle team on enque and deque messages, but the health check reports are clearing mentioning the messages are dequeued successfully.
Badly required your help to get rid of this inconsitency behaviour while invoking the service activator using spring
<int:logging-channel-adapter id="jmslogger" log-full-message="true" level="TRACE"/>
<!-- Oracle Advanced Queue Integration -->
<bean id="jdbc4NativeJdbcExtractor"
class="org.springframework.jdbc.support.nativejdbc.Jdbc4NativeJdbcExtractor"
p:connectionType="oracle.jdbc.driver.OracleConnection" />
<orcl:aq-jms-connection-factory
id="oracleAqConnectionFactory"
use-local-data-source-transaction="true"
native-jdbc-extractor="jdbc4NativeJdbcExtractor"
data-source="dataSource"/>
<!-- Siebel Atlas Service Request - Oracle Advanced Queue Integration -->
<bean id="jmsJsonMessageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter"
p:typeIdPropertyName="javaDtoClass"
/>
<int:channel id="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel" ></int:channel>
<int:channel id="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel" >
<int:interceptors>
<int:wire-tap channel="jmslogger"/>
</int:interceptors>
</int:channel>
<int:channel id="createSiebelAtlasCreateServiceRequestOutboundReplyChannel" />
<int:logging-channel-adapter id="createSiebelAtlasCreateServiceRequestOutboundReplyChannelLogger"
channel="createSiebelAtlasCreateServiceRequestOutboundReplyChannel" />
<int:gateway
id="submitSiebelAtlasCreateServiceRequestMessagingService"
service-interface="ServiceRequestOutboundGatewayMessagingService"
default-request-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel"
default-reply-channel="submitSiebelAtlasCreateServiceRequestOutboundReplyChannel" />
<int:header-enricher input-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel" output-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel">
<int:correlation-id expression="payload.getRequestId()"/>
</int:header-enricher>
<!-- Outbound driven channel adapter, meaning messagings are being sent to / queued in AQ -->
<int-jms:outbound-channel-adapter
id="siebelAtlasCreateServiceRequestJmsOutboundChannelAdapter"
destination-name="Q_NAME"
channel="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel"
connection-factory="oracleAqConnectionFactory"
message-converter="jmsJsonMessageConverter"
auto-startup="true">
</int-jms:outbound-channel-adapter>
<int:service-activator
output-channel="createSiebelAtlasCreateServiceRequestOutboundReplyChannel"
input-channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel"
ref="createCustomerRelationshipsSiebelAtlasServiceRequestService"
method="create">
</int:service-activator>
<int:channel id="createSiebelAtlasCreateServiceRequestInboundRequestChannel">
<int:interceptors>
<int:wire-tap channel="jmslogger"/>
</int:interceptors>
</int:channel>
<!-- Inbound message driven channel adapter, meaning messagings are being consumed / dequeued from AQ -->
<int-jms:message-driven-channel-adapter connection-factory="oracleAqConnectionFactory"
message-converter="jmsJsonMessageConverter"
destination-name="Q_NAME"
channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel"
acknowledge="transacted"
max-concurrent-consumers="5"
transaction-manager="transactionManager"
auto-startup="true"
concurrent-consumers="2" />
My module is on spring integration which pushes message to RabbitMQ.
<task:executor id="bulkChannelExecutor" keep-alive="50" poolsize="50-100" queue-capacity="500"
></task:executor>
<int:channel id="logIngesterRestEndpointBulk" >
<int:dispatcher task-executor="bulkChannelExecutor" failover="false" />
</int:channel>
While Load testing ist not able to handle heavy loads(100 concurrent users) it causing message or request lost ,if i remove pool-size ,having unbounded poolsize its able to handling heavy loads but its creating memory thread leaks?
Rest Gateway will get input as Json and pass it to Filter and then will to
Chain ,there Json messages will get parsed and splitted as indivdiual messages and then will get push to rabbitMQ
<task:executor id="bulkChannelExecutor" keep-alive="50" pool-size="100-500"
queue-capacity="500"
></task:executor>
<int:channel id="logIngesterRestEndpointBulk" >
<int:dispatcher task-executor="bulkChannelExecutor" failover="false" />
</int:channel>
<int-http:inbound-gateway id="logIngesterGatewayBulk" auto-startup="true"
supported-methods="POST" request-channel="logIngesterRestEndpointBulk"
path="/rest/log/bulk" error-channel="errorChannel" reply-timeout="50"
request-payload-type="java.lang.String">
</int-http:inbound-gateway>
<int:channel id="filterChannelbulk">
</int:channel>
<int:channel id="messageOutputChannel" >
</int:channel>
<int:filter input-channel="logIngesterRestEndpointBulk"
throw-exception-on-rejection="true" method="validate" ref="payloadValidation"
output-channel="filterChannelbulk">
</int:filter>
<int:chain input-channel="filterChannelbulk" output-channel="messageOutputChannel" id="chaining" >
<int:splitter id="splitter" ref="payloadSplitter" method="splitPayLoad" >
</int:splitter>
<int:transformer id="logMessageTransformerbulk" ref="logMessageHeaderTransformer"
method="transform">
</int:transformer>
</int:chain>
<int:service-activator input-channel="errorChannel"
ref="responseHandler" method="handleFailedPayLoad" >
</int:service-activator>
<!-- Start RabbitMQ Configuration -->
<int:channel id="ackchannel">
</int:channel>
<int-amqp:outbound-channel-adapter
id="amqpAdapter" channel="messageOutputChannel" amqp-template="amqpTemplate" lazy-connect="false" confirm-ack-channel="ackchannel" confirm-correlation-expression="headers['amqp_publishConfirm']"
exchange-name="dhp_exchange" routing-key-expression="headers['routingKey']" >
</int-amqp:outbound-channel-adapter>
<int:service-activator id="ackservice" input-channel="ackchannel" ref="responseHandler" method="confirmAck" />
Since you are using HTTP, you should remove the task executor and allow the web container to manage the threads. If you need more threads, do it through the web container configuration; don't use a thread handoff here; it really serves no purpose and can cause the issues you describe.
I have code to read message from IBM MQ with spring integration config as below. I need to convert to Java 7 DSL using Spring integration annotations.
<bean id="inQueue" class="com.ibm.mq.jms.MQQueue" depends-on="esbQueueConnectionFactory">
<constructor-arg value="******" />
</bean>
<int:channel id="readFromChannel">
<int:interceptors>
<!-- <int:wire-tap channel="logger" /> -->
</int:interceptors>
</int:channel>
<int-jms:message-driven-channel-adapter
id="jmsInAdapter" connection-factory="esbQueueConnectionFactory"
destination="inQueue" channel="readFromChannel" />
<bean id="msgProcesser" class="com.gap.si.service.MessageProcessService" />
<int:service-activator id="servAct"
input-channel="readFromChannel" ref="msgProcesser" method="processMessage" />
If you want to use the Java DSL, see the reference manual.
Use the Jms factory class
IntegrationFlows.from(Jms.messageDriven...)
.handle(...)
.get();
If you want to use just annotations, see the Spring Integration reference manual.
The message driven adapter is simply a #Bean of type JmsMessageDrivenEndpoint which gets a listener container and a ChannelPublishingJmsMessageListener.