Spring Integration MQTT cleanSession=false fails because client unsubscribes from topics - spring

I'm configuring Spring Integration to use cleanSession=false on one of my channels.
<bean id="clientFactory" class="org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory">
<property name="cleanSession" value="false" />
</bean>
<int-mqtt:message-driven-channel-adapter id="mqttLiveDataInbound"
client-id="client1"
url="${mqtt.broker.url}"
qos="1"
topics="liveData"
client-factory="clientFactory"
channel="channelLiveData"/>
Reason being I want to be able to receive message while my application is offline. When my application restarts, I want it to receive whatever QoS>0 message that were published during my absence.
Now I noticed something weird : my application doesn't pick up the missing QoS>0 messages after a downtime.
I've logged a simple scenario where
Spring Integration starts
A QoS1 message is sent to the topic and received by Spring Integration
Spring Integration exits
A QoS1 message is sent to the topic
Spring Integration starts
Spring Integration does not receive the QoS1 message that was sent while it was offline.
The reason being the following (as can be seen from the logs below) :
spring integration exits
it unsubscribes from the topic
it disconnects the client
This is essentially telling the broker that this client is no longer interested in these messages. When my app is down, the broker is no longer persisting these QoS>0 messages for me.
When my app starts up again, it fails to receive the QoS>0 messages that were published while it was down.
1448917620: New connection from 127.0.0.1 on port 1883.
1448917620: New client connected from 127.0.0.1 as client1 (c0, k60).
1448917620: Sending CONNACK to client1 (0, 0)
1448917620: Received SUBSCRIBE from client1
1448917620: liveData (QoS 1)
1448917620: Sending SUBACK to client1
1448917632: New connection from ::1 on port 1883.
1448917632: New client connected from ::1 as mosqpub/25936-MacBook-P (c1, k60, u'system').
1448917632: Sending CONNACK to mosqpub/25936-MacBook-P (0, 0)
1448917632: Received PUBLISH from mosqpub/25936-MacBook-P (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917632: Sending PUBACK to mosqpub/25936-MacBook-P (Mid: 1)
1448917632: Sending PUBLISH to client1 (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917632: Received DISCONNECT from mosqpub/25936-MacBook-P
1448917632: Client mosqpub/25936-MacBook-P disconnected.
1448917633: Received PUBACK from client1 (Mid: 1)
1448917643: Received UNSUBSCRIBE from client1
1448917643: liveData
1448917643: Received DISCONNECT from client1
1448917643: Client client1 disconnected.
1448917648: New connection from ::1 on port 1883.
1448917648: New client connected from ::1 as mosqpub/25945-MacBook-P (c1, k60, u'system').
1448917648: Sending CONNACK to mosqpub/25945-MacBook-P (0, 0)
1448917648: Received PUBLISH from mosqpub/25945-MacBook-P (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917648: Sending PUBACK to mosqpub/25945-MacBook-P (Mid: 1)
1448917648: Received DISCONNECT from mosqpub/25945-MacBook-P
1448917648: Client mosqpub/25945-MacBook-P disconnected.
1448917665: New connection from 127.0.0.1 on port 1883.
1448917665: Client client1 disconnected.
1448917665: New client connected from 127.0.0.1 as client1 (c0, k60).
1448917665: Sending CONNACK to client1 (1, 0)
1448917665: Received SUBSCRIBE from client1
1448917665: liveData (QoS 1)
1448917665: Sending SUBACK to client1
I ran this scenario using the mosquitto client tools, and there exiting the mosquitto subscriber disconnects the clients but does not unsubscribe from the topic
1448917534: New connection from ::1 on port 1883.
1448917534: New client connected from ::1 as client1 (c0, k60).
1448917534: Sending CONNACK to client1 (0, 0)
1448917534: Received SUBSCRIBE from client1
1448917534: liveData (QoS 1)
1448917534: Sending SUBACK to client1
1448917550: New connection from ::1 on port 1883.
1448917550: New client connected from ::1 as mosqpub/25879-MacBook-P (c1, k60, u'system').
1448917550: Sending CONNACK to mosqpub/25879-MacBook-P (0, 0)
1448917550: Received PUBLISH from mosqpub/25879-MacBook-P (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917550: Sending PUBACK to mosqpub/25879-MacBook-P (Mid: 1)
1448917550: Sending PUBLISH to client1 (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917550: Received DISCONNECT from mosqpub/25879-MacBook-P
1448917550: Client mosqpub/25879-MacBook-P disconnected.
1448917550: Received PUBACK from client1 (Mid: 1)
1448917553: Socket error on client client1, disconnecting.
1448917554: New connection from ::1 on port 1883.
1448917554: New client connected from ::1 as mosqpub/25884-MacBook-P (c1, k60, u'system').
1448917554: Sending CONNACK to mosqpub/25884-MacBook-P (0, 0)
1448917554: Received PUBLISH from mosqpub/25884-MacBook-P (d0, q1, r0, m1, 'liveData', ... (68 bytes))
1448917554: Sending PUBACK to mosqpub/25884-MacBook-P (Mid: 1)
1448917554: Received DISCONNECT from mosqpub/25884-MacBook-P
1448917555: Client mosqpub/25884-MacBook-P disconnected.
1448917556: New connection from ::1 on port 1883.
1448917556: Client client1 disconnected.
1448917556: New client connected from ::1 as client1 (c0, k60).
1448917556: Sending CONNACK to client1 (0, 0)
1448917556: Sending PUBLISH to client1 (d0, q1, r0, m2, 'liveData', ... (68 bytes))
1448917556: Received SUBSCRIBE from client1
1448917556: liveData (QoS 1)
1448917556: Sending SUBACK to client1
1448917556: Received PUBACK from client1 (Mid: 2)
Any idea how to deal with this situation ?
EDIT :
When implementing the workaround as proposed in the accepted answer, I'm getting the following error. My Spring context is loaded from a webapp. I've tried putting the IgnoreUnsubscribePahoClientFactory in a seperate JAR (same level as spring-integration / paho) as well as in the webapp classes itself.
2015-12-02 15:47:43,703 ERROR org.springframework.integration.handler.LoggingHandler - org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.eclipse.paho.client.mqttv3.MqttAsyncClient]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206)
at org.springframework.aop.framework.ProxyFactoryBean.getProxy(ProxyFactoryBean.java:368)
at org.springframework.aop.framework.ProxyFactoryBean.getSingletonInstance(ProxyFactoryBean.java:322)
at org.springframework.aop.framework.ProxyFactoryBean.getObject(ProxyFactoryBean.java:246)
at com.ecs.vdm.rest.integration.IgnoreUnsubscribePahoClientFactory.proxy(IgnoreUnsubscribePahoClientFactory.java:62)
at com.ecs.vdm.rest.integration.IgnoreUnsubscribePahoClientFactory.getAsyncClientInstance(IgnoreUnsubscribePahoClientFactory.java:43)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.connectAndSubscribe(MqttPahoMessageDrivenChannelAdapter.java:216)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.access$300(MqttPahoMessageDrivenChannelAdapter.java:45)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter$1.run(MqttPahoMessageDrivenChannelAdapter.java:272)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 16 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 20 more
Caused by: java.lang.SecurityException: class "org.eclipse.paho.client.mqttv3.MqttAsyncClient$$EnhancerBySpringCGLIB$$d14754a9_4603"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(ClassLoader.java:952)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:666)
at java.lang.ClassLoader.defineClass(ClassLoader.java:794)
... 25 more

It's a bug - it unconditionally unsubscribes during the stop().
I don't see a simple work around; but I have a couple of ideas; I'll post here if/when I have something.
In the meantime, please open a JIRA Issue.
EDIT
Gist Here
It's a bit of a sledgehammer, but it should work for you; it effectively ignores the call to unsubscribe on the client. It could be made a little more sophisticated, to only ignore when the QOS is > 0, but that would be quite a bit more involved.
If you're already using the DefaultMqttPahoClientFactory just change the bean class to this one. If you're not currently using a factory, declare it as a bean and provide it to the adapter using the client-factory attribute.
We'll fix it properly in an upcoming release.

Related

AMQP Closing all channels from connection when docker run on port 5672

I have run Rabbitmq as a docker compose and it work well with port 15672 on browser, but 5672 not working.
docker-compose
rabbitmq:
image: 'rabbitmq:3-management-alpine'
container_name: rabbitmq
ports:
- '5672:5672'
- '15672:15672'
environment:
- RABBITMQ_NODE_TYPE=stats
- RABBITMQ_NODE_NAME=rabbit#stats
- RABBITMQ_ERL_COOKIE=s3cr3tc00ki3
- RABBITMQ_DEFAULT_USER=rabbitmquser
- RABBITMQ_DEFAULT_PASS=rabbitmquser
volumes:
- '/rabbitmq/data:/var/lib/rabbitmq/'
- '/rabbitmq/log:/var/log/rabbitmq'
spring application.properties
spring.rabbitmq.host = 192.168.1.212
spring.rabbitmq.port = 15672
spring.rabbitmq.username = rabbitmquser
spring.rabbitmq.password = rabbitmquser
error in docker log when enter http://192.168.100.12:5672
2021-04-07 13:30:07.742 [info] <0.731.0> Resetting node maintenance status
2021-04-07 13:31:27.979 [info] <0.1050.0> accepting AMQP connection <0.1050.0> (192.168.2.2:62786 -> 172.19.0.4:5672)
2021-04-07 13:31:28.093 [error] <0.1050.0> closing AMQP connection <0.1050.0> (192.168.2.2:62786 -> 172.19.0.4:5672):
{bad_header,<<"GET / HT">>}
2021-04-07 13:31:28.111 [info] <0.1055.0> Closing all channels from connection '192.168.2.2:62786 -> 172.19.0.4:5672' because it has been closed
2021-04-07 13:31:29.224 [info] <0.1053.0> accepting AMQP connection <0.1053.0> (192.168.2.2:62787 -> 172.19.0.4:5672)
2021-04-07 13:31:29.225 [error] <0.1053.0> closing AMQP connection <0.1053.0> (192.168.2.2:62787 -> 172.19.0.4:5672):
{bad_header,<<"GET / HT">>}
2021-04-07 13:31:29.228 [info] <0.1062.0> Closing all channels from connection '192.168.2.2:62787 -> 172.19.0.4:5672' because it has been closed
2021-04-07 13:31:34.276 [info] <0.1060.0> accepting AMQP connection <0.1060.0> (192.168.2.2:62789 -> 172.19.0.4:5672)
2021-04-07 13:31:34.280 [error] <0.1060.0> closing AMQP connection <0.1060.0> (192.168.2.2:62789 -> 172.19.0.4:5672):
{bad_header,<<"GET / HT">>}
2021-04-07 13:31:34.282 [info] <0.1069.0> Closing all channels from connection '192.168.2.2:62789 -> 172.19.0.4:5672' because it has been closed
2021-04-07 13:31:44.279 [info] <0.1067.0> accepting AMQP connection <0.1067.0> (192.168.2.2:62790 -> 172.19.0.4:5672)
2021-04-07 13:31:44.280 [error] <0.1067.0> closing AMQP connection <0.1067.0> (192.168.2.2:62790 -> 172.19.0.4:5672):
{handshake_timeout,handshake}
2021-04-07 13:31:44.282 [info] <0.1073.0> Closing all channels from connection '192.168.2.2:62790 -> 172.19.0.4:5672' because it has been closed
error in spring
declaring queue for inbound: springCloudBus.anonymous.PRr6HWmwTqGU2akit5Rc9Q, bound to: springCloudBus
Attempting to connect to: [192.168.1.212:15672]
Channel 'springCloudBus.anonymous.PRr6HWmwTqGU2akit5Rc9Q.errors' has 1 subscriber(s).
Broker not available; cannot force queue declarations during start: java.net.ConnectException: Connection timed out: no further information
onsumer raised exception, processing can restart if the connection factory supports it. Exception summary: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection timed out: no further information
Change:
spring.rabbitmq.port = 5672

Telegram bot python erro in webhooks heroku

I deploy a bot in heroku but it give a erro
2021-04-03T02:56:36.610385+00:00 app[web.1]: 2021-04-03 02:56:36,604 - apscheduler.scheduler - INFO - Scheduler started
2021-04-03T02:56:37.316107+00:00 app[web.1]: 2021-04-03 02:56:37,315 - telegram.ext.updater - ERROR - Error while bootstrap set webhook: Bad webhook: webhook can be set up only on ports 80, 88, 443 or 8443
2021-04-03T02:56:37.316196+00:00 app[web.1]: 2021-04-03 02:56:37,316 - telegram.ext.updater - ERROR - Failed bootstrap phase after 0 retries (Bad webhook: webhook can be set up only on ports 80, 88, 443 or 8443)
2021-04-03T02:47:04.325287+00:00 app[web.1]: 2021-04-03 02:47:04,317 - telegram.ext.updater - ERROR - unhandled exception in Bot:1718309867:updater
Well, i tryed all port 80, 88, 8443 but it give me the same erro again.
My hook and port code:
#change PORT TO HEROKU
PORT = int(os.environ.get('PORT', '8443'))
updater = Updater(SECRET_KEY, use_context=True)
#hook to heroku
updater.start_webhook(listen="0.0.0.0",
port=PORT,
url_path=SECRET_KEY)
updater.bot.set_webhook('https://myapp.herokuapp.com/' + SECRET_KEY)
PS: In localhost work very well
Given the date of this question, I assume that you're using PTB v13.4+. In that case, please see this channel post, i.e. change
updater.start_webhook(listen="0.0.0.0",
port=PORT,
url_path=SECRET_KEY)
updater.bot.set_webhook('https://myapp.herokuapp.com/' + SECRET_KEY)
to
updater.start_webhook(listen="0.0.0.0",
port=PORT,
url_path=SECRET_KEY,
webhook_url='https://myapp.herokuapp.com/' + SECRET_KEY)

Cant connect to MQ Spring boot SSL

I am trying to establish a connection to the MQ service
For SSL connection I use the commands
-Djavax.net.ssl.trustStore=/opt/app/key.jks"
-Djavax.net.ssl.trustStorePassword=111111
Appliction.properties config
ibm.mq.connName=10.20.31.25(1414)
ibm.mq.channel=OIV.CHAN
ibm.mq.queueManager=OIV
ibm.mq.user=TEST
ibm.mq.password=passw0rd
ibm.mq.ssl-cipher-spec=TLS_RSA_WITH_AES_256_CBC_SHA
When the application starts, everything is ok
INFO IbmJmsConfiguration - Initializing SSL context:
protocol=TLSv1.2, keyStore=null, trustStore=/opt/app/key.jks
INFO IbmJmsConfiguration - SSL context initialized:
keyManagers item(s) = 0, trustManagers item(s) = 1
But when making a request to MQ, I get an error
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2393;AMQ9771: SSL handshake failed. [1=java.lang.IllegalArgumentException[Unsupported ciphersuite SSL_RSA_WITH_AES_256_CBC_SHA256]
text error
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2393;AMQ9771: SSL handshake
failed. [1=java.lang.IllegalArgumentException[Unsupported ciphersuite
SSL_RSA_WITH_AES_256_CBC_SHA],3=10.90.51.15/10.90.50.15:1414
(10.96.51.15),4=SSLSocket.createSocket,5=default]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnection.java:2360)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.bindAndConnectSocket(RemoteTCPConnection.java:816)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1381)
at com.ibm.mq.jmqi.remote.impl.RemoteConnection.connect(RemoteConnection.java:976)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getNewConnection(RemoteConnectionSpecification.java:553)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSessionFromNewConnection(RemoteConnectionSpecification.java:233)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSession(RemoteConnectionSpecification.java:141)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionPool.getSession(RemoteConnectionPool.java:127)
at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.jmqiConnect(RemoteFAP.java:13302)
... 74 common frames omitted
Caused by: java.lang.IllegalArgumentException: Unsupported ciphersuite SSL_RSA_WITH_AES_256_CBC_SHA
at sun.security.ssl.CipherSuite.valueOf(CipherSuite.java:228)
at sun.security.ssl.CipherSuiteList.<init>(CipherSuiteList.java:79)
at sun.security.ssl.SSLSocketImpl.setEnabledCipherSuites(SSLSocketImpl.java:2491)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnection.java:2351)
... 82 common frames omitted

What is the best practice to create a mock service with Citrus Automation Framework for multiple responses?

I've got Component Integration Test suite setup with Citrus Framework. In order to create a mock service for different components. I've been using simple mapping strategy with the help of XPathPayloadMappingKeyExtractor.
The challenge I've got is to create a multiple responses for different soap requests.
I've been struggling to understand the way it's responding. Any experienced person who can help me out on Citrus and Spring please ?
My Context file:
<citrus-ws:client id="ClientEndpoint"
request-url="http://localhost:8085/"/>
<citrus-ws:server id="BS_Customer_Information"
port="8085"
auto-start="true"/>
My Test Method:
#CitrusTest
public void testingServer() {
soap().client(ClientEndpoint)
.send()
.soapAction("urn:RetrieveAddressBookOP_01")
.payload(new ClassPathResource("Requests/Sample1.xml"));
soap().server(BS_Customer_Information)
.receive()
.soapAction("urn:RetrieveAddressBookOP_01");
soap().server(BS_Customer_Information)
.send()
.payload(new ClassPathResource("AtomicResponses/Response1.xml"));
soap().client(ClientEndpoint)
.receive()
.messageType(MessageType.XML);
}
Issue 1: My Soap Client times out and could not get the response
Question 1: Should the server response be parsed into Soap Env and Body ?
Question 2: Why Would it still call go to Channel Endpoint.inbound when I've already defined my response?
Console Log:
2521 DEBUG gEndpointInterceptor| Received SOAP request:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<RetrieveAddressBookOP_01"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
2527 DEBUG r.WebServiceEndpoint| Received SOAP request:
SOAPMESSAGE [payload: <?xml version="1.0" encoding="UTF-8"?><au:RetrieveAddressBookOP_01 xmlns:au="au.com.teysau.dataservice"/>][headers: {citrus_message_id=e1311140-6ee3-415a-815e-0d162cbc03c1, citrus_message_timestamp=1490649843807, citrus_soap_action=urn:RetrieveAddressBookOP_01, citrus_http_request_uri=/, citrus_http_context_path=, citrus_http_query_params=, citrus_http_method=POST}][header-data: [<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>]][attachments: []]
2527 DEBUG annelEndpointAdapter| Forwarding request to message channel ...
2527 DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'
2527 DEBUG ltCorrelationManager| Saving correlation key for 'citrus_message_correlator_ChannelEndpointAdapter:producer'
2527 DEBUG context.TestContext| Setting variable: citrus_message_correlator_ChannelEndpointAdapter:producer with value: 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
2527 DEBUG .ChannelSyncProducer| Sending message to channel: 'BS_Customer_Information.inbound'
2527 DEBUG .ChannelSyncProducer| Message to send is:
SOAPMESSAGE [payload: <?xml version="1.0" encoding="UTF-8"?><RetrieveAddressBookOP_01"/>][headers: {citrus_message_id=e1311140-6ee3-415a-815e-0d162cbc03c1, citrus_message_timestamp=1490649843807, citrus_soap_action=urn:RetrieveAddressBookOP_01, citrus_http_request_uri=/, citrus_http_context_path=, citrus_http_query_params=, citrus_http_method=POST}][header-data: [<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>]][attachments: []]
2527 INFO .ChannelSyncProducer| Message was sent to channel: 'BS_Customer_Information.inbound'
3539 WARN annelEndpointAdapter| Reply timed out after 1000ms. Did not receive reply message on reply channel
3540 DEBUG annelEndpointAdapter| Did not receive reply message - no response is simulated
3540 DEBUG r.WebServiceEndpoint| No reply message from endpoint adapter 'com.consol.citrus.channel.ChannelEndpointAdapter#6dbd0a41'
3540 WARN r.WebServiceEndpoint| No SOAP response for calling client
3542 DEBUG ageDispatcherServlet| Successfully completed request
3546 DEBUG server.Server| RESPONSE / 202 handled=true
3546 DEBUG ver.HttpChannelState| HttpChannelState#244a4722{s=DISPATCHED i=true a=null} unhandle DISPATCHED
3553 DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback#27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback#2f1ea019] generate: NEED_HEADER (null,[p=0,l=0,c=0,r=0],true)#START
3556 DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback#27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback#2f1ea019] generate: FLUSH ([p=0,l=114,c=8192,r=114],[p=0,l=0,c=0,r=0],true)#COMPLETING
3556 DEBUG io.WriteFlusher| write: WriteFlusher#76f08437{IDLE} [HeapByteBuffer#2c34f7c0[p=0,l=114,c=8192,r=114]={<<<HTTP/1.1 202 Acce....v20160210)\r\n\r\n>>>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}]
3557 DEBUG io.WriteFlusher| update WriteFlusher#76f08437{WRITING}:IDLE-->WRITING
3562 INFO ent.WebServiceClient| SOAP message was sent to endpoint: 'http://localhost:8085/'
3562 INFO ent.WebServiceClient| Received no SOAP response from endpoint: 'http://localhost:8085/'
3562 INFO citrus.Citrus|
3562 DEBUG citrus.Citrus| TEST STEP 1/4 SUCCESS
3562 INFO citrus.Citrus|
3562 DEBUG citrus.Citrus| TEST STEP 2/4: receive
3563 DEBUG io.ChannelEndPoint| flushed 114 SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,W,1092/30000,HttpConnection}{io=0,kio=0,kro=1}
3566 DEBUG nnel.ChannelConsumer| Receiving message from: BS_Customer_Information.inbound
3567 DEBUG nnel.ChannelConsumer| Received message from: BS_Customer_Information.inbound
3567 DEBUG ltCorrelationManager| Saving correlation key for 'citrus_message_correlator_BS_Customer_Information:consumer'
3567 DEBUG context.TestContext| Setting variable: citrus_message_correlator_BS_Customer_Information:consumer with value: 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3567 DEBUG ltCorrelationManager| Saving correlated object for 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3567 DEBUG ageValidatorRegistry| Found 3 message validators for message type: XML
3567 DEBUG mXmlMessageValidator| Start message validation ...
3567 DEBUG mXmlMessageValidator| Start XML message validation
3569 DEBUG mXmlMessageValidator| Starting XML schema validation ...
3569 WARN mXmlMessageValidator| Neither schema instance nor schema repository defined - skipping XML schema validation
3569 INFO mXmlMessageValidator| XML message validation successful: All values OK
3569 DEBUG mXmlMessageValidator| Start message header validation ...
3570 DEBUG io.WriteFlusher| update WriteFlusher#76f08437{IDLE}:WRITING-->IDLE
3570 DEBUG erver.HttpConnection| org.eclipse.jetty.server.HttpConnection$SendCallback#27d2cb2e[PROCESSING][i=ResponseInfo{HTTP/1.1 202 null,-1,false},cb=org.eclipse.jetty.server.HttpChannel$CommitCallback#2f1ea019] generate: DONE ([p=114,l=114,c=8192,r=0],[p=0,l=0,c=0,r=0],true)#END
3570 DEBUG mXmlMessageValidator| Validating header element: citrus_soap_action='urn:RetrieveAddressBookOP_01': OK.
3571 INFO mXmlMessageValidator| Message header validation successful: All properties OK
3571 INFO mXmlMessageValidator| Message validation successful: All values OK
3571 INFO citrus.Citrus|
3571 DEBUG citrus.Citrus| TEST STEP 2/4 SUCCESS
3571 INFO citrus.Citrus|
3571 DEBUG citrus.Citrus| TEST STEP 3/4: send
3571 DEBUG ngCorrelationManager| Get correlation key for 'citrus_message_correlator_BS_Customer_Information:consumer'
3571 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = 'e1311140-6ee3-415a-815e-0d162cbc03c1''
3571 DEBUG .ChannelSyncConsumer| Sending message to reply channel: 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#66f66866'
3571 DEBUG .ChannelSyncConsumer| Message to send is:
SOAPMESSAGE [payload: <AddressBook>
<Address>
<Address_Number>14</Address_Number>
<Long_Address>Willis Street</Long_Address>
<Tax_ID>7987398</Tax_ID>
<Alpha_Name>what is alpha</Alpha_Name>
<Code>UN_</Code>
<Mailing_Name>James Bond</Mailing_Name>
<Address_Line1>take the first part of the long address</Address_Line1>
<Address_Line2>You may take the second part not</Address_Line2>
<Postal_Code>8900</Postal_Code>
<City>WLN</City>
<Country>NZ</Country>
<Prefix>233</Prefix>
<Phone_Number>025364</Phone_Number>
<Prefix_2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<Phone_Number2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<userID>s3b9d</userID>
<BatchNumber>jkdhj59</BatchNumber>
<Tansaction_Number>jkd3j29</Tansaction_Number>
<Line_Number>291597</Line_Number>
</Address>
</AddressBook>][headers: {citrus_message_id=fd946a46-f67a-405d-b118-b1b6b3d562c1, citrus_message_timestamp=1490649843443}][attachments: []]
3572 WARN emporaryReplyChannel| Reply message received but the receiving thread has exited due to a timeout:GenericMessage [payload=SOAPMESSAGE [payload: <AddressBook>
<Address>
<Address_Number>14</Address_Number>
<Long_Address>Willis Street</Long_Address>
<Tax_ID>7987398</Tax_ID>
<Alpha_Name>what is alpha</Alpha_Name>
<Code>UN_</Code>
<Mailing_Name>James Bond</Mailing_Name>
<Address_Line1>take the first part of the long address</Address_Line1>
<Address_Line2>You may take the second part not</Address_Line2>
<Postal_Code>8900</Postal_Code>
<City>WLN</City>
<Country>NZ</Country>
<Prefix>233</Prefix>
<Phone_Number>025364</Phone_Number>
<Prefix_2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<Phone_Number2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<userID>s3b9d</userID>
<BatchNumber>jkdhj59</BatchNumber>
<Tansaction_Number>jkd3j29</Tansaction_Number>
<Line_Number>291597</Line_Number>
</Address>
</AddressBook>][headers: {citrus_message_id=fd946a46-f67a-405d-b118-b1b6b3d562c1, citrus_message_timestamp=1490649843443}][attachments: []], headers={id=cfc4eeaa-eac8-8f00-2f45-2e3fcb16fdb6, timestamp=1490649844854}]
3572 INFO .ChannelSyncConsumer| Message was sent to reply channel: 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#66f66866'
3572 INFO citrus.Citrus|
3572 DEBUG citrus.Citrus| TEST STEP 3/4 SUCCESS
3572 INFO citrus.Citrus|
3572 DEBUG citrus.Citrus| TEST STEP 4/4: receive
3572 DEBUG ngCorrelationManager| Get correlation key for 'citrus_message_correlator_ClientEndpoint'
3572 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
3572 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
3575 DEBUG http.HttpParser| reset HttpParser{s=END,214 of 214}
3576 DEBUG http.HttpParser| END --> START
3576 DEBUG server.HttpChannel| HttpChannelOverHttp#4820529f{r=1,c=false,a=IDLE,uri=} handle exit, result COMPLETE
3576 DEBUG io.ChannelEndPoint| filled 0 SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}
3576 DEBUG io.ChannelEndPoint| filled 0 SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}
3576 DEBUG http.HttpParser| parseNext s=START HeapByteBuffer#6b681750[p=0,l=0,c=16384,r=0]={<<<>>>POST / HTTP/1.1\r\n...\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}
3576 DEBUG o.AbstractConnection| fillInterested HttpConnection#2c01adea[FILLING,SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp#4820529f{r=1,c=false,a=IDLE,uri=}]
3576 DEBUG o.AbstractConnection| FILLING-->FILLING_FILL_INTERESTED HttpConnection#2c01adea[FILLING_FILL_INTERESTED,SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp#4820529f{r=1,c=false,a=IDLE,uri=}]
3577 DEBUG o.AbstractConnection| FILLING_FILL_INTERESTED-->FILL_INTERESTED HttpConnection#2c01adea[FILL_INTERESTED,SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,-,-,13/30000,HttpConnection}{io=0,kio=0,kro=1}][p=HttpParser{s=START,0 of -1},g=HttpGenerator{s=START},c=HttpChannelOverHttp#4820529f{r=1,c=false,a=IDLE,uri=}]
3577 DEBUG electChannelEndPoint| Local interests updating 0 -> 1 for SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,R,-,0/30000,HttpConnection}{io=1,kio=0,kro=1}
3577 DEBUG io.SelectorManager| Queued change org.eclipse.jetty.io.SelectChannelEndPoint$1#67e66c5c
3578 DEBUG io.SelectorManager| Selector loop woken up from select, 0/1 selected
3578 DEBUG io.SelectorManager| Running change org.eclipse.jetty.io.SelectChannelEndPoint$1#67e66c5c
3578 DEBUG electChannelEndPoint| Key interests updated 0 -> 1 on SelectChannelEndPoint#1c2a40b4{/127.0.0.1:54924<->8085,Open,in,out,R,-,1/30000,HttpConnection}{io=1,kio=1,kro=1}
3578 DEBUG io.SelectorManager| Selector loop waiting on select
4072 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
4072 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
4573 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
4573 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
5073 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
5073 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
5574 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
5574 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
6075 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
6075 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
6575 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
6575 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
7075 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
7075 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
7576 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
7576 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
8076 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
8076 DEBUG citrus.RetryLogger| Reply message did not arrive yet - retrying in 500ms
8576 DEBUG ltCorrelationManager| Finding correlated object for 'citrus_message_id = '69b4056a-cae6-4004-a837-41de069865b8''
8580 INFO report.JIRAConsumer| Invoking JIRA API...
works.integration.jira.exceptions.ServiceBindingException: Missing Required Properties - SUMMARY, EXMESSAGE, DETAILEDEXCEPTION, PROJECT
You have to add a fork(true) option to the first `soap().client().send()' action because the Http SOAP protocol is synchronous by nature. The first action in your test waits for a synchronous response and blocks the rest of the test case execution.
Obviously your test needs to receive some other messages before that client response with soap().server(). That is why you need to fork the client send action in the first place so the server actions can perform before the client response has arrived.
In general the SOAP components in Citrus automatically handle SOAP Envelope and SOAP body. So you just need to define the pure body content as payload. SOAP Envelope is added automatically.
Hope this is more clear now.

Websphere MQ 7with Spring JMS - infinite delivery

I have written a Websphere MQ listener using Spring boot (JMS). I have configured the backout queue at queue level with threshold as 0
As part of program I am throwing JMSException immediately I receive message so that my message goes to back out queue.
The problem that I am facing is that message is getting continuously re-delivered to listener
JMSMessage class: jms_text
JMSType: null
JMSDeliveryMode: 2
JMSExpiration: 0
JMSPriority: 0
JMSMessageID: ID:414d51204d5148554244313020202020583e8e2b26af9905
JMSTimestamp: 1484639118180
JMSCorrelationID: null
JMSDestination: null
JMSReplyTo: null
JMSRedelivered: true
JMSXAppID: WebSphere MQ Client for Java
JMSXDeliveryCount: 98
JMSXUserID: a450922
JMS_IBM_Character_Set: UTF-8
JMS_IBM_Encoding: 546
JMS_IBM_Format: MQSTR
JMS_IBM_MsgType: 8
JMS_IBM_PutApplType: 28
JMS_IBM_PutDate: 20170117
JMS_IBM_PutTime: 07451818
#JmsListener(destination = "${ibm.mq.incomingqueue}", containerFactory = "defaultJmsListenerContainerFactory")
public void onMessage(TextMessage message) throws JMSException {
System.out.println("Here" + message.toString());
throw new JMSException("reason");
}
BOTHRESH must be greater than or equal to 1. Setting BOTHRESH to 0 disables it.
Reference the How WebSphere Application Server handles poison messages by IBM's
Paul Titheridge.
When WebSphere MQ is the JMS provider
By default, queues created with WebSphere MQ have the Backout threshold property (known in WebSphere MQ terms as BOTHRESH) set to 0. Therefore, the default behaviour of WebSphere MQ is never to back out poison messages.

Resources