I am trying to use a UDP socket to send a simple datagram to a local service. I've tested the request and response using a nodejs client, but I cannot get the same response when using Mulesoft.
This is the nodejs code that works:
const dgram = require('node:dgram');
const process = require('node:process');
const buffer = require('node:buffer');
var soc = dgram.createSocket('udp4');
soc.on('error', (err) => {
console.error(`socket error:\n${err.stack}`);
});
soc.on('message', (msg) => {
console.log(`message received: ${msg}`);
});
soc.connect(1434, () => {
console.log(`socket connected`);
const queryInstanceCode = 3;
const buff = buffer.Buffer.alloc(1);
buff[0] = queryInstanceCode;
soc.send(buff);
});
Executing this node app will query the local service and return expected data.
My mule app uses the socket connector with this configuration:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:sockets="http://www.mulesoft.org/schema/mule/sockets"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/sockets http://www.mulesoft.org/schema/mule/sockets/current/mule-sockets.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="aaeb8ad9-c25d-4076-90b4-5fbf0584fefa" >
<http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<sockets:request-config name="SQLServiceBrowserSocket" doc:name="Sockets Request config" doc:id="ccebf069-3ea5-403b-8f38-14a1b181c93f" >
<sockets:udp-requester-connection host="127.0.0.1" port="1434" clientTimeout="5000"/>
</sockets:request-config>
<flow name="named.instance.finderFlow" doc:id="f0259fdc-c7ce-43ba-a124-07df0bee9ec4" >
<http:listener doc:name="Listener" doc:id="3ece9740-15b6-4681-b5e3-20ff66fa46c7" config-ref="HTTP_Listener_config" path="/mssqlhost/{host}/instance/{instance}/port" allowedMethods="GET" responseStreamingMode="NEVER">
</http:listener>
<logger level="INFO" doc:name="Log Request" doc:id="3bd2076d-23f6-4388-a3d8-0da2816d00dc" message="#attributes"/>
<sockets:send-and-receive doc:name="Query SQL Server Browser" doc:id="14f15af2-ee9a-41f9-9890-a021fd066d35" config-ref="SQLServiceBrowserSocket" target="instancePort" outputMimeType="application/octet-stream" outputEncoding="US-ASCII">
<non-repeatable-stream />
<sockets:content><![CDATA[3]]></sockets:content>
</sockets:send-and-receive>
<logger level="INFO" doc:name="Logger" doc:id="6ca780c0-21c7-409c-9c64-17cb0a0fc543" message="#payload"/>
</flow>
</mule>
When running the Mule app and performing a simple CURL on the url, the flow will timeout after 5 seconds, with no additional information than "UDP connection timed out".
I've tried adding debug logging for sockets, but I get no additional information. How do I get additional information on why the UDP Sockets connector is not properly interacting with the service?
The nodejs application works and proves that the service is available and functioning. The Mule application times out after 5 seconds without any further information. I have tried increasing level logging by adding this logger:
<AsyncLogger name="org.mule.extension.socket" level="DEBUG"/>
To the log4j2.xml of the package, but I get no additional information.
I expect the Sockets connector to send the UDP packate and receive the same response that the nodejs application receives. Instead the Socket connector times out.
The issue was encoding. Supplying the string "3" to the content of the socket made it encoded in ASCII. Instead, use dataweave:
%dw 2.0
output application/octet-stream
---
3
Related
I am trying to run a demo scenario for Soap XML request . Have used the sample calculator web service . I works fine when i trigger the request from Soap UI .But the connection fails on trying to access the request from IntelliJ using Karate .
#SoapTest
Feature:
Background:
* url 'http://www.dneonline.com'
* path 'calculator.asmx'
* configure ssl = true
Scenario: soap 1.1
Given url apiURL
And request
"""
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<intA>2</intA>
<intB>3</intB>
</Add>
</soap:Body>
</soap:Envelope>
"""
When soap action 'http://tempuri.org/Add'
Then status 200
And match /Envelope/Body/AddResponse/AddResult == 5
And Print response
**Below is the karate Config file being used **
function() {
var config = {
apiURL: 'http://www.dneonline.com/calculator.asmx'
};
karate.configure('connectTimeout', 5000);
karate.configure('readTimeout', 5000);
karate.configure('ssl', { trustAll: true });
return config;
}
Error Details:
12:38:56.822 [ForkJoinPool-1-worker-1] ERROR com.intuit.karate - org.apache.http.conn.ConnectTimeoutException: Connect to www.dneonline.com:80 [www.dneonline.com/45.40.165.23] failed: connect timed out, http call failed after 5068 milliseconds for URL: http://www.dneonline.com/calculator.asmx/calculator.asmx
12:38:56.822 [ForkJoinPool-1-worker-1] ERROR com.intuit.karate - http request failed:
org.apache.http.conn.ConnectTimeoutException: Connect to www.dneonline.com:80 [www.dneonline.com/45.40.165.23] failed: connect timed out
I am not quite sure if i need to configure any proxy setting in Intellij or in the karate framework.
or if it is something to do with the firewall as i am using my company's system.
Thanks .
Yes maybe you have to set a proxy: https://github.com/intuit/karate#configure
* configure proxy = 'http://my.proxy.host:8080'
Thanks for the prompt reply Peter... The solution given by you works fine . Many Thanks :)
I need to send an acknowledge response for some messages went an acknowledge needed flag is set for that purpose.
Using a Java component I build a Payload string array with this structure:
Payload[0]=message entry.
Payload[1]="true"/"false" // This is the acknowledge needed flag.
Payload[2]="OK"/"ON"/"OFF"// Response to the transport (went flag="true")
This is my XML code
<tcp:connector name="TCP" validateConnections="false" sendBufferSize="0" receiveBufferSize="0" receiveBacklog="0" keepAlive="true" clientSoTimeout="10000" serverSoTimeout="10000" socketSoLinger="0" doc:name="TCP">
<tcp:direct-protocol rethrowExceptionOnRead="true" payloadOnly="true"/>
</tcp:connector>
<flow name="verifyFlow">
<tcp:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9446" connector-ref="TCP" responseTimeout="10000" doc:name="TCP" transformer-refs="Byte_Array_to_String"/>
<component class="verify.as" doc:name="Java Component"/>
<choice doc:name="Choice">
<when expression="#[message.payload[1] == 'false']">
<set-payload value="""" doc:name="No response"/>
</when>
<otherwise>
<expression-transformer mimeType="text/plain" expression="#[message.payload[2]]" doc:name="Expression"/>
</otherwise>
</choice>
</flow>
The problem I'm facing is that went ever the flag is "false" there shouldn't be any response send to the transport (no 'null' value, no empty string, no "", Etc.) ¿Is there any way to change the exchange pattern of the TCP (or UDP) connector from request-response to one way inside the flow?
I'm using Mule EE 3.5.2.
I'm posting an HTTP request (PostMan) with a cookie header, to an incoming HTTP end point in Mule. How can I read this Cookie?
In practice this cookie will be coming through an NGinX proxy; i need it to pass to another application.
First make sure your connector have enableCookies="true".
Then you'll find a inboundProperty called cookies of type Lorg.apache.commons.httpclient.Cookie.
To access them just #[message.inboundProperties['cookies'].
Here's how to save the cookies from a rest response in a session variable without a custom java class.
<set-session-variable variableName="incomingCookies" value="#[org.mule.transport.http.CookieHelper.parseCookiesAsAClient(message.inboundProperties['set-cookie'],null)]" doc:name="Set incomingCookies as Session Variable"/>
<set-variable variableName="cookie-name" value="#[org.mule.transport.http.CookieHelper.getCookieValueFromCookies(incomingCookieMap,'cookie-name')]" doc:name=“Set cookie-name as Flow Variable”/>
You can use a similar approach for extracting cookies from a rest request using the parseCookiesAsAServer method from the CookieHelper class.
More info on the CookieHelper class is here https://www.mulesoft.org/docs/site/3.8.0/apidocs/org/mule/transport/http/CookieHelper.html
That doesn't work anymore with the new http:listener component.
Setting that property will give :
org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'enableCookies' is not allowed to appear in element 'http:listener'.
So how to do this with the new http:listener component...
A problem I had was that I needed to access the cookies that came in and Mule only provides the cookies in an unformatted string.
So this is an option a friend of mine developed, which I enhanced a bit to get easy access to the cookies in a flow:
package transformers;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.transformer.AbstractMessageTransformer;
import org.mule.transport.http.CookieHelper;
import org.apache.commons.httpclient.Cookie;
public class CookieGrabber extends AbstractMessageTransformer {
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
Object _CookieHeader = message.getInboundProperty("Cookie");
List<Cookie> _CookieList = null;
Map<String,String> _CookieMap = new HashMap<String,String>();
try {
//Grab the cookies from the header and put them into a List
_CookieList = (List<Cookie>) Arrays.asList(CookieHelper.parseCookiesAsAServer(_CookieHeader.toString(),
new URI("" + message.getInboundProperty("host"))));
//And put them in a convenient List which can be accessed from the flow
message.setProperty("incomingCookieList", _CookieList, PropertyScope.SESSION);
//Let's also put them in a nice Map, since incoming cookies will
//usually only contain a name and a value, so let's get easy access to them by their name.
for (Cookie _Cookie : _CookieList){
_CookieMap.put(_Cookie.getName(), _Cookie.getValue());
}
message.setProperty("incomingCookieMap", _CookieMap, PropertyScope.SESSION);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return message;
}
}
Then there is this flow example which shows how to use this code snippet.
It contains a listener that sets some cookies, forwards it to a "proxy", which will read the cookies, but also forward the request to another endpoint, making it a transparent proxy, but which does read the cookies in the process.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
version="EE-3.6.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
<custom-transformer class="transformers.CookieGrabber"
name="MyCookieTranformer"
doc:name="Java"/>
<http:listener-config name="HTTP_Configuration_CookieHandlerExample"
host="0.0.0.0"
port="8080"
doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Configuration"
host="localhost"
port="8080"
doc:name="HTTP Request Configuration"/>
<flow name="CookieSetterFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/setCookies/*"
doc:name="setCookies"
doc:description="Call this module by entering http://localhost:8080/setCookie"/>
<message-properties-transformer doc:name="Set the cookies"
doc:description="Set some random cookies in the header">
<add-message-property key="Cookie"
value="token=abcde; name=dennis"/>
</message-properties-transformer>
<http:request config-ref="HTTP_Request_Configuration"
path="/proxyCookie"
method="GET"
doc:name="call proxyCookies"
doc:description="Invoke the cookieReceiver with the cookies we've just set. Note the failure status code validator with a non-existing http code. It's a nasty bug, but it works like this...">
<http:failure-status-code-validator values="00000"/>
</http:request>
</flow>
<flow name="CookieProxyFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/proxyCookie"
doc:name="proxyCookies"
doc:description="This connector will proxy the cookieReceiver"/>
<transformer ref="MyCookieTranformer"
doc:name="GrabCookies"
doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
<logger message="CookieProxy: Value of cookie "token": "#[sessionVars.incomingCookieMap.get('token')]"."
level="INFO"
doc:name="Have a cookie!"
doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
<flow-ref name="copy-and-clean-headers"
doc:name="copy-and-clean-headers"
doc:description="Cope the headers and clean the Mule stuff from the headers to forward it clean to the receiver."/>
<set-property propertyName="host"
value="localhost"
doc:name="Set Host"
doc:description="Now not really necessary, but you'll probably want to set the hostname to the actual service endpoint."/>
<http:request config-ref="HTTP_Request_Configuration"
path="/receiveCookie"
method="GET"
doc:name="forward to receiveCookies"
doc:description="Invoke the cookieReceiver.">
<http:failure-status-code-validator values="00000"/>
</http:request>
<flow-ref name="copy-and-clean-headers"
doc:name="copy-and-clean-headers"
doc:description="Again copy the headers and clean the Mule http stuff."/>
</flow>
<sub-flow name="copy-and-clean-headers" >
<copy-properties propertyName="*"
doc:name="Copy All HTTP Headers"/>
<remove-property propertyName="Content-Length"
doc:name="Remove Content Length"/>
<remove-property propertyName="MULE_*"
doc:name="Remove MULE Properties"/>
<remove-property propertyName="X_MULE*"
doc:name="Remove X_MULE Properties"/>
<remove-property propertyName="http.*"
doc:name="Remove http Properties"/>
</sub-flow>
<flow name="CookieReceiverFlow">
<http:listener config-ref="HTTP_Configuration_CookieHandlerExample"
path="/receiveCookie"
doc:name="receiveCookies"
doc:description="This connector receives the cookies we've just set"/>
<transformer ref="MyCookieTranformer"
doc:name="GrabCookies"
doc:description="Use our custom transformers.CookieGrabber class to put the cookies in a nice java.util.List in a session variable."/>
<logger message="CookieReceiver: Value of cookie "token": "#[sessionVars.incomingCookieMap.get('token')]". Yep, still there :)"
level="INFO"
doc:name="Have a cookie!"
doc:description="Let get a cookie value, simply by referring the name of it as the key from our map"/>
<set-payload value="#[sessionVars.incomingCookieList.toArray(String)]"
doc:name="Put CookieList to payload"
doc:description="Put the session vairable List that contains the cookies in the payload"/>
<json:object-to-json-transformer returnClass="java.lang.String"
doc:name="Object to JSON"
doc:description="Convert our payload to a JSON object"/>
</flow>
</mule>
You can test it by running it and opening this page: http://localhost:8080/setCookies
Hope this helps.
You can fetch the cookies with:
#[headers:INBOUND:cookie] or #[message.inboundProperties['cookie']]
I've created a simple flow that exposes an HTTP endpoint linked to a REST service. The REST service returns a String which is then placed onto a JMS queue using the request-response pattern. The idea is that the String placed on the queue will be consumed by some consumer and a reponse will created using the Reply-To address. So basically this is implimenting synchronous JMS.
The flow works as expected, except when the HTTP endpoint is secured using Basic Authentication. In this case the response is:
java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1
and no message is placed on the queue. Removing Basic Authentication results in no exception being thrown. Also, removing the JMS outbound endpoint results in the String being echoed back which leads me to believe the problem is with the JMS endpoint. I suspect that the problem is with the response from the JMS endpoint because setting component in the flow to one-way negates the problem. I think the issue might be that the endpoint is sending some response to the HTTP endpoint without authentication credentials and it fails because of it, but I'm unsure how to deal with this.
Below is the flow that I created:
<mule
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:core="http://www.mulesoft.org/schema/mule/core"
version="CE-3.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:ss="http://www.springframework.org/schema/security" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/3.1/mule-spring-security.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd ">
<jms:activemq-connector name="Active_MQ" specification="1.1" brokerURL="tcp://localhost:61616"
validateConnections="true" doc:name="Active MQ"/>
<mule-ss:security-manager>
<mule-ss:delegate-security-provider name="memory-provider" delegate-ref="authenticationManager"/>
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider>
<ss:user-service id="userService">
<ss:user name="username" password="password" authorities="ROLE_ADMIN"/>
</ss:user-service>
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<flow name="RESTAPISync" doc:name="RESTAPISync">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP">
<mule-ss:http-security-filter realm="realm"/>
</http:inbound-endpoint>
<jersey:resources doc:name="REST">
<component class="SFREST"/>
</jersey:resources>
<jms:outbound-endpoint exchange-pattern="request-response" queue="tmp" connector-ref="Active_MQ"
doc:name="JMS"/>
</flow>
The SFREST.java component:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("/pops")
public class SFREST{
#GET
public String getPOPs() throws Exception{
return "hello";
}
}
And the exception:
ERROR 2012-11-04 21:40:57,485 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Authentication Attempt Failed. Message payload is of type: String
Code : MULE_ERROR-54999
--------------------------------------------------------------------------------
Exception stack is:
1. Bad credentials (org.springframework.security.authentication.BadCredentialsException)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider:137 (null)
2. Authentication Attempt Failed. Message payload is of type: String (org.mule.api.security.UnauthorisedException)
org.mule.security.MuleSecurityManager:96 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/security/UnauthorisedException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:137)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.mule.module.spring.security.SpringProviderAdapter.authenticate(SpringProviderAdapter.java:70)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
ERROR 2012-11-04 21:41:04,522 [[jmstest].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1
Code : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. com.sun.jersey.spi.container.ContainerResponse (java.io.NotSerializableException)
java.io.ObjectOutputStream:1164 (null)
2. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException)
org.apache.commons.lang.SerializationUtils:111 (null)
3. java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse (org.apache.commons.lang.SerializationException). Message payload is of type: MuleResponseWriter$1 (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:35 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.io.NotSerializableException: com.sun.jersey.spi.container.ContainerResponse
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.commons.collections.map.AbstractHashedMap.doWriteObject(AbstractHashedMap.java:1182)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Any ideas?
Turns out the problem was that the jersey_response property can't be serialized and needs to be removed. So regardless of what the payload is as long as this property is in the message, the message can't be passed to the JMS outbound component. More info can be found at:
http://forum.mulesoft.org/mulesoft/topics/http_authentication_with_jms_request_response?utm_content=topic_link&utm_medium=email&utm_source=reply_notification
The reason of the exception is because any jersey component returns a com.sun.jersey.spi.container.ContainerResponse that you need to transform before propagating it to the next message processor as explained here
I'm new to Mule, and am working on a problem that requires a flow that diapatches messages to a Mule message bus that listeners can receive to also receive notification of successful processing of those messages when the workers are done. The main criteria is that the 'dispatcher flow' not be blocked from continuing to do its work (of placing other different messages on the bus for potentially other listeners).
I have a test app that I've been running in MuleStudio (below) that encapsultates the basics of what I'm trying to achieve, simplified; this is a very simple 2 flow app, using request-reply to allow the 2nd flow to send a reply back to the main flow; the main issue here is that the main flow's thread is blocked, preventing it from doing anything until the response comes back. Is there a way to have the response come back on a different thread of the main flow, or are there other ways of accomplishing this given the criteria ?
Thanks for any help or pointers ;-)
...
<!-- simple Groovy transformer that changes the msg payload to a greeting w/ the current time-->
<scripting:transformer name="toCurrentTime">
<scripting:script engine="groovy">
import java.text.SimpleDateFormat;
def DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
def cal = Calendar.getInstance();
def sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return "Response # time " + sdf.format(cal.getTime())
</scripting:script>
</scripting:transformer>
<!--
note : neither of the following are allowed on the flow b/c of the request-reply
processingStrategy="synchronous"
processingStrategy="queued-asynchronous"
-->
<flow name="main" doc:name="main">
<http:inbound-endpoint ref="httpEventInjector" doc:name="HTTP"/>
<logger message="starting main flow" level="INFO"/>
<request-reply storePrefix="mainFlow">
<vm:outbound-endpoint path="worker"></vm:outbound-endpoint>
<vm:inbound-endpoint path="reply"></vm:inbound-endpoint>
</request-reply>
<!-- processing continues once we get the response on the 'reply' channel above from the worker -->
<!-- generate the response for the browser -->
<logger message="finishing main flow w/ browser response" level="INFO"/>
<response>
<transformer ref="toCurrentTime"/>
</response>
</flow>
<flow name="worker" doc:name="worker">
<vm:inbound-endpoint path="worker"/>
<logger message="starting worker task(s) ...." level="INFO"/>
<scripting:component doc:name="thread-sleep(10s)">
<scripting:script engine="Groovy">
System.out.println "about to sleep # time" + System.currentTimeMillis()
Thread.sleep(10000);
System.out.println "done sleeping # time" + System.currentTimeMillis()
</scripting:script>
</scripting:component>
<logger message="finishing up worker task(s) ...." level="INFO"/>
</flow>
You can use continuations to achieve what you want. I've written a blog post about this topic.