I have following flows in my mule config .
<flow name="SimpleTest" processingStrategy="asynchronous">
<http:listener path="/orders/{id}" config-ref="myRequestConfig"
allowedMethods="GET" />
<set-payload value="SUCCESS" />
<flow-ref name="subFlowTest" />
<logger level="ERROR" message="value is : after subflow" />
</flow>
<sub-flow name="subFlowTest">
<scripting:component doc:name="sleep">
<scripting:script engine="groovy">
<scripting:text>
java.lang.Thread.sleep(5000);
</scripting:text>
</scripting:script>
</scripting:component>
</sub-flow>
It gives Unable to process a synchronous event asynchronously error . i want to call the subflow asynchronously , so if my parent flow is asyncronous , the subflow will automatically becomes asyncronous , correct ? so why am i getting this error ?
You can call your subflow asynchronously by using async message processor.
<async doc:name="Async">
<flow-ref name="subFlowTest" doc:name="Call Sub Flow"/>
</async>
HTTP endpoint makes a call to this flow through it automatically synchronous, so you have a conflict between your flow's strategy and its inbound endpoint. By definition, HTTP is synchronous.
Your problem lies on your understanding of HTTP.
Hope it helps.
/T
subflow semantic is more like a macro expansion than a function call. You don't call a subflow, but use a subflow to extract message processors into a different xml structure for readability. In runtime it is the same than if you copy all the message processors of the subflow and put them inside the flow.
Why would you execute your script component asynchronously?
Related
I've upgraded from Mule 3.5.x to 3.6.x and since the old http transport is deprecated in 3.6.x I wanted to migrate to the new HTTP connector.
Here is the original code for calling my webservice:
<http:outbound-endpoint ref="OrderEndpoint" doc:name="GetApprovedOrder">
<cxf:jaxws-client serviceClass="com.acme.orders.IOrderServiceBean"
port="OrderServiceBean_v2_0Port"
operation="getApprovedOrderOp" />
</http:outbound-endpoint>
The point I have got to with the new connector is as follows:
<cxf:jaxws-client serviceClass="com.acme.orders.v2_0.IOrderServiceBean" port="OrderServiceBean_v2_0Port" operation="getApprovedOrderOp" />
<http:request config-ref="http.request.config" path="acme-services/OrderServiceBean_v2_0" method="POST" />
The issue that I have is that with the old version of the code, after calling the web service, the payload would be the response [java] object. With the new version of the code the payload is a org.glassfish.grizzly.utils.BufferInputStream containing the soap xml.
I could use a combination of xpath and a jaxb-xml-object-transformer to convert the contents of the stream to the response object, this just seems like a backwards step though.
I have looked into using the jaxws-client without the request and also at the ws-consumer, but my following requirements seems to rule these options out (unless I'm just misunderstanding how to use them).
I need to use the contract first method for calling the web services, see above where I have specified serviceClass rather than wsdl.
The web services use basic auth, therefore I need to specify a username and password.
I need to be able to specify the host and port (or at least the address) of the web service.
The solution is: wrap your element into a processor-chain
As follows:
<processor-chain>
<cxf:jaxws-client serviceClass="com.acme.orders.v2_0.IOrderServiceBean" port="OrderServiceBean_v2_0Port" operation="getApprovedOrderOp" />
<http:request config-ref="http.request.config" path="acme-services/OrderServiceBean_v2_0" method="POST" />
</processor-chain>
This is because cxf is intercepting, so after the processor chain you would have the same object as you had in your previous solution.
We have a requirement to service the GUI with a SI service. The GUI communicates with the backend over JMS queues, and will wait for a response on a tmp queue that is specified in the jms replyTo header property.
So there can be 10 gui's making queries to the backend, and receiving messages on their individual tmp queues.
So I wrote a SI service using inbound gateway that looks like this
<int:channel id="inChannel" />
<int:channel id="outChannel" />
<int-jms:inbound-gateway id="jmsSampleService" request-destination-name="TEST_QUEUE_2" request-channel="inChannel"
connection-factory="qpidJmsConnectionFactory" extract-request-payload="true" error-channel="errorChannel" />
<int:service-activator input-channel="inChannel" ref="sampleService2" method="processMessage" />
public class SampleService2 {
public Response processMessage(Object obj) throws Exception {
LOG.info("Message received on sample service. ");
Thread.sleep(5000);
Response response = new ResponseImpl();
response.setPayload("Test response");
return response;
}
This works fine, i can see the service return a message back on the jmsReplyTo queue. However, this is a single threaded synchronous operation which means unless GUI1 was serviced, GUI2 's call will be blocked. I want to do this asynchronously since this is simply a method call on a class.
We were doing something similar in mule
<flow name="sampleServiceFlow">
<jms:inbound-endpoint queue="TEST_QUEUE" connector-ref="queryQpidConnector" />
<byte-array-to-object-transformer />
<component>
<spring-object bean="sampleService" />
</component>
<object-to-byte-array-transformer />
<expression-filter evaluator="groovy"
expression="message.getOutboundProperty('replyToQueueName') != null" />
<jms:outbound-endpoint queue="#[header:OUTBOUND:replyToQueueName]" connector-ref="queryQpidConnector" />
</flow>
Since the mule service does not have any txns, it is able to simply consume a message in auto-ack, and have the SampleService's method call service the call.
Is there a way of implementing something like this in SI? perhaps by using the message-driven-channel-adapter? Is there a way to propagate jms header properties between channels?
Simply use concurrency on the inbound gateway. concurrent-consumers is the min max-concurrent-consumers (if specified) is the max; the adapter's container with adjust the concurrency depending on demand.
I am not sure what you mean by
Is there a way to propagate jms header properties between channels?
The jms headers are mapped to integration headers and vice-versa.
Is there a way to test a choice router for the following scenario which is based on the http.status? I am seeking a way to test the first condition of the router
<flow>
<choice>
<when expression="#[message.inboundProperties['http.status'] !=201">
......
<otherwise>
.....
</otherwise>
</choice>
</flow>
I want to verify that a javax.ws.rs.core.Response with can be correctly handled by the HTTP endpoint.
The flow doesn't have an inbound endpoint (thus it's a private flow) so to test it
create a test flow in a test XML config file that you will load side by side with your other Mule configuration XML files,
add an inbound VM endpoint to this test flow and make it call the private flow you want to test,
in your functional test case, use the Mule Client to dispatch a test message over the VM endpoint, setting properties on this test message that will end-up as inbound properties in the private flow.
I have a simple Mule flow where I receive an XML message via an HTTP endpoint and then do some processing on it. One of the first steps is to send the message via another outbound HTTP endpoint to a web service. The service just saves the message and does no processing on it. Therefore I effectively want to ignore the return value of the outbound endpoint and continue processing the message that was originally received. I tried making the endpoint on-way, but then my current Mule message becomes empty.
How do I call a endpoint, but ignore any return and continue processing with my original message?
You could use a <wiretap>: http://www.mulesoft.org/documentation/display/current/Routing+Message+Processors#RoutingMessageProcessors-WireTap
Or use <async> scope: http://www.mulesoft.org/documentation/display/current/Async+Scope+Reference
Or use an <enricher> if you want store the response in a variable but leave the current payload alone: http://www.mulesoft.org/documentation/display/current/Message+Enricher
Note that wiretap and enricher are synchronous and will block further processing where async won't.
In this case Async should be a better option.
Async in Mule helps to continue with the processing ignoring the results of the message processors called inside the async.
ex:
<flow name="sample" >
<http:inbound-endpoint ...... />
.... Some processing.....
<async>
<http:outbound-endpoint ....... />
</async>
...... Continue with the processing with the original message....
</flow>
Hope this helps.
I am doing an integration poc to invoke a remote EJB servcie by ejb:connector and ejb:outbound-endpoint in component binding.
It works perfectly fine if I define methodArgumentTypes and method properties in ejb outbound endpoint
<flow name="ExternalServiceFlow" doc:name="ExternalServiceFlow">
<vm:inbound-endpoint exchange-pattern="request-response" path="serviceInput" doc:name="VM"/>
<ejb:outbound-endpoint connector-ref="weblogicEjbConnector" methodArgumentTypes="java.lang.String,com.fusa.ssg.datatype.Date,java.lang.String,com.fusa.ssg.datatype.AuditInfo" method="readAccountDetail" address="${external.ejb.service.address}"/>
</flow>
However, since I need to invoke other APIs in the same component binding, how can reuse the ExternalServiceFlow to invoke other methods besides readAccountDetail? I tried to remove the methodArgumentTypes and method properties, but the application started with exceptions
Element ejb:outbound-endpoint{address=${external.ejb.service.address}, connector-ref=weblogicEjbConnector, name=.ExternalServiceFlow:outbound-endpoint.32, protocol=ejb} must have all attributes for one of the sets: [ref] [method]
Please advise how I can reuse the same vm flow with different remote APIs call.