mule sequential flow to wait for another flow - mule

Main flow: or FLOW A
<mule>
<flow name="GetQBClassesFlow1" doc:name="GetQBClassesFlow1" processingStrategy="synchronous">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="${port}" path="getClasses" doc:name="HTTP"/>
<flow-ref name="Authenticate-QB" doc:name="Flow Reference"/>
<logger message="=========Acc Token==========#[sessionVars['accessToken']]" level="INFO" doc:name="Logger"/>
<flow-ref name="GetQBClassesFlow2" doc:name="Flow Reference"/>
</flow>
<flow name="GetQBClassesFlow2" doc:name="GetQBClassesFlow2" processingStrategy="synchronous">
<logger message="=========Acc Token 2==========#[sessionVars['accessToken']]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
Authentication: or FLOW B
<mule ...>
<quickbooks:config name="QBAuthenticate" consumerKey="${consumerKey}" consumerSecret="${consumerSecret}" doc:name="Quickbooks Online - Authenticate"/>
<flow name="Authenticate-QB" doc:name="Authenticate-QB" processingStrategy="synchronous">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="8989" doc:name="HTTP"/>
<quickbooks:auth-user config-ref="Authenticate"
accessTokenUrl="https://oauth.intuit.com/oauth/v1/get_access_token"
authorizationUrl="https://appcenter.intuit.com/Connect/Begin"
callbackUrl="http://${hostname}:8989/getQBAccessToken"
requestTokenUrl="https://oauth.intuit.com/oauth/v1/get_request_token"
doc:name="Authenticate user" requestTokenId="tenantId"/>
</flow>
<flow name="qbAccessToken" doc:name="getAccessToken" processingStrategy="synchronous">
<http:inbound-endpoint exchange-pattern="one-way" host="${hostname}" port="8989" path="getQBAccessToken" doc:name="Get Token"/>
<logger message="=========GET QB Accounts ============" level="INFO" doc:name="Logger"/>
<quickbooks:get-access-token config-ref="QBAuthenticate" doc:name="get access token"/>
<logger message="=========realmId==============#[message.payload.realmId]" level="INFO" doc:name="Logger"/>
<set-session-variable variableName="accessToken"
value="#[message.payload.accessToken]" doc:name="Set accessToken" />
<set-session-variable variableName="accessTokenSecret"
value="#[message.payload.accessTokenSecret]" doc:name="Set accessTokenSecret" />
<set-session-variable variableName="realmId"
value="#[message.payload.realmId]" doc:name="Set realmId" />
</flow>
</mule>
I have a FLOW called GetQBClassesFlow1(Main flow) which invokes another flow Authenticate-QB( authentication flow above), i.e.GetQBClassesFlow1 invokes Authenticate-QB, where Authenticate-QB waits for the user to enter details on login page, but before completion of Authenticate-QB flow, GetQBClassesFlow1 continues( suppose to wait to complete authenticate details page) which causes the issue. I want GetQBClassesFlow1 should wait for flow Authenticate-QB to complete. How can I handle this?
output:
INFO 2014-08-20 11:18:03,830 [[qbprojects].connector.http.mule.default.receiver.03] org.mule.api.processor.LoggerMessageProcessor: =========Acc Token==========null
INFO 2014-08-20 11:18:03,831 [[qbprojects].connector.http.mule.default.receiver.03] org.mule.api.processor.LoggerMessageProcessor: =========Acc Token 2==========null
INFO 2014-08-20 11:18:12,712 [[qbprojects].connector.http.mule.default.receiver.03] org.mule.api.processor.LoggerMessageProcessor: =========GET QB Accounts ============
INFO 2014-08-20 11:18:12,944 [[qbprojects].connector.http.mule.default.receiver.03] org.mule.api.processor.LoggerMessageProcessor: =========realmId==============1345020

The Authenticate-QB flow is designed to be called over HTTP by an end-user, in order to perform the OAuth2 dance.
Thus you can not invoke it with flow-ref. The authentication part is done out-of-band of whatever else your flows are doing.

Related

How can I find if URI parameter exists in Mule?

I want to check if a URI parameter exists in the URL using Mule 3.8.3 and also need to make sure that inboundProperties is not empty either when using the Choice component in Anypoint Studio 6.2 and Mule 3.8.3.
I have tried:
#[message.inboundProperties.'http.uri.params'.code != empty]
#[org.mule.util.StringUtils.isNotEmpty(message.inboundProperties.'http.uri.params'.code)]
For both I get
org.mule.api.expression.ExpressionRuntimeException: Execution of the
expression
"org.mule.util.StringUtils.isNotEmpty(message.inboundProperties.'http.query.params'.code)"
failed.
Is there any other way to try?
There are two "Expression" in palate.
1.Expression-transformer
Example : <expression-transformer expression="#[message.inboundProperties.'http.uri.params'.param != empty]" doc:name="Expression"/>
2.Expression-component
Example : <expression-component doc:name="Expression"/>
Make sure you use "Expression-transformer" as shown below
Try below flow in Anypoint Studio.It works for me.
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8082" basePath="/testapi" doc:name="HTTP Listener Configuration"/>
<flow name="uri">
<http:listener path="uri/{param}/resource" config-ref="HTTP_Listener_Configuration" doc:name="HTTP"/>
<expression-transformer expression="#[message.inboundProperties.'http.uri.params'.param != empty]" doc:name="Expression"/>
<object-to-string-transformer doc:name="Object to String"/>
<set-payload value="#[payload]" doc:name="Set Payload"/>
</flow>
Test above with below url in your browser
http://localhost:8082/testapi/uri/testUriParam/resource
This could be used with Choice component component as well.
Try below code :
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8082" basePath="/testapi" doc:name="HTTP Listener Configuration"/>
<flow name="uri">
<http:listener path="uri/{param}/resource" config-ref="HTTP_Listener_Configuration" doc:name="HTTP"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties.'http.uri.params'.param != empty]">
<logger message="Found URI Param" level="INFO" doc:name="Logger"/>
<set-payload value="Found URI Param" doc:name="Set Payload"/>
</when>
<otherwise>
<logger level="INFO" doc:name="Logger" message="URI Param not found"/>
<set-payload value="URI Param not found" doc:name="Set Payload"/>
</otherwise>
</choice>
</flow>

Mule Http basic authentication - set username in variable

I have implemented HTTP Basic Authentication for my mule flow application.
It listens on HTTP and the URI is http://localhost:8082/login.
<flow name="wsGetReport">
<http:listener config-ref="HTTP_Listener_Configuration" path="${wsPath}" doc:name="HTTP"/>
<logger level="INFO" message="## received" doc:name="Logger"/>
<http:basic-security-filter realm="mule-realm"/>
<flow-ref name="doSubFlow" doc:name="doSubFlow"/>
<logger level="INFO" message="## passed security" doc:name="Logger"/>
<http:static-resource-handler resourceBase="${app.home}/classes" doc:name="HTTP Static Resource Handler" defaultFile="index.html"/>
</flow>
I would retrieve the username typed in the login by the user, and show it in the http Static resource (an html page).
How can I store the username used in authentication?
Thanks.
You can get the user and password of basic auth using mel as following and store it in a variable:-
<flow name="SpringBasicAuthExample">
<http:listener config-ref="HTTP_Listener_Configuration" path="/security" doc:name="HTTP"/>
<logger level="INFO" message="## received" doc:name="Logger"/>
<http:basic-security-filter realm="mule-realm"/>
<set-payload value="#[message.inboundProperties.'Authorization']" doc:name="Set Payload"/>
<set-payload value="#[message.payloadAs(java.lang.String).substring('Basic'.length()).trim()]" doc:name="Set Payload"/>
<expression-transformer expression="#[String credentials = new String(org.mule.util.Base64.decode(payload),java.nio.charset.Charset.forName('UTF-8')); String[] values = credentials.split(':',2); flowVars.user= values[0]; flowVars.pass=values[1];]" doc:name="Expression"/>
<set-payload value="#[['user':flowVars.user,'password':flowVars.pass]]" doc:name="Set Payload"/>
<parse-template location="index.html" doc:name="Parse Template"/>
<logger level="INFO" message="## passed security" doc:name="Logger"/>
</flow>
</mule>
And at the end you can store the username and password in a variable and pass the variable in an html file to display the username using parse-template dynamically:-
index.html:-
<html>
<body>
<b>UserName: #[flowVars.user]</b>
</body>
</html>
Pls note your index.html should be there in resource folder. Here once you get the username in variable you can store it or pass it anywhere you wish :)
take a look at BasicAuthenticationFilter.extractAndDecodeHeader(). this is how Spring Framework does it.
You can get username and password from basic auth Authentication as below:
<set-session-variable variableName="userInfo" value="#[org.mule.util.StringUtils.split(new String(org.mule.util.Base64.decode(message.inboundProperties.'Authorization'.substring('Basic'.length()).trim()), java.nio.charset.Charset.forName('UTF-8')), ':')]" doc:name="Session Variable"/>
<logger message="user name = #[sessionVars.userInfo[0]] ***** password= #[sessionVars.userInfo[1]]" level="INFO" doc:name="Logger"/>

Until-Successful Process for list of objects in a long running query not working

I want to develop a flow that could allow me to make queries to an external system that could take a long time to return. I may have to make queries for multiple values in a list. I am using an until-successful scope in solving the problem. Unfortunately, the even though the request is run several times, the failed records never get put in the dead letter queue. Here is my attempt at solving the problem:
<!-- Dead Letter Queue for exhausted attempts-->
<vm:endpoint name="DLQ" path="DLQ_VM" doc:name="VM"/>
<flow name="StartFlow" processingStrategy="synchronous">
<!--Place a list of String errors to query for on this vm -->
<vm:inbound-endpoint path="request-processing-queue" "
exchange-pattern="one-way" doc:name="VM"/>
<vm:outbound-endpoint path="reprocessing-queue"
exchange-pattern="request-response" doc:name="VM"/>
<logger level="INFO" message="Data returned is #[payload]"/>
<catch-exception-strategy>
<logger level="ERROR" message="Failure During Processing"/>
</catch-exception-strategy>
</flow>
<flow name="RetryingProcess">
<vm:inbound-endpoint name="reprocessing-vm" exchange-
pattern="request-response"
path="reprocessing-queue" doc:name="VM"/>
<foreach collection="#[payload]" doc:name="For Each">
<vm:outbound-endpoint path="by-singles-vm" exchange-
pattern="request-response"/>
</foreach>
</flow>
<flow name="query-retry">
<vm:inbound-endpoint path="by-singles-vm" exchange-
pattern="request-response" doc:name="VM"/>
<until-successful objectStore-ref="objectStore"
failureExpression="#[groovy:(exception &&
exception in com.trion.CustomException)
||!(payload instanceof
com.trion.QueryResult])]"
maxRetries="5"
millisBetweenRetries="300000"
deadLetterQueue-ref="DLQ_VM" doc:name="Until
Successful">
<vm:outbound-endpoint path="try-again-vm" exchange-
pattern="request-response" doc:name="VM"/>
</until-successful>
</flow>
<flow name="GetQueryValue" >
<vm:inbound-endpoint path="try-again-vm" exchange-
pattern="request-response" doc:name="VM"/>
<flow-ref name="QueryRequest" />
</flow>
<!-- This never happens, i.e. the results are not put here... after retying
-->
<flow name="AttemptsExceededProcessing">
<inbound-endpoint ref="DLQ_VM" doc:name="Generic"/>
<logger level="DEBUG" message="Entering Final Destination Queue with
payload is #[payload]"/>
</flow>
<!-- Here I have a query to the external system... >
<flow name="QueryRequest">
...... Makes the long running query Here..
//returns com.trion.QueryResult
</flow>
</mule>
Please help!
There was no problem with the configuration. I had a millisSecondsBetweenRetry value set so small I wasn't seeing the log messages and assumed it wasn't working.

Until Successful returning an Boolean value in MULE ESB

I am using an until successful scope for my outbound endpoint. Am getting a proper response but when it comes out of until successful am getting boolean value my flow is given below
<flow name="testFlow1" doc:name="testFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="test" doc:name="HTTP"/>
<until-successful maxRetries="5" failureExpression="#[message.inboundProperties['http.status'] != 200]" synchronous="true" doc:name="Until Successful">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="www.example.com" doc:name="HTTP"/>
</until-successful>
<logger message="`From outbound #[payload]`" level="INFO" doc:name="Logger"/>
</flow>
</mule>
But am getting output in logger as
From outbound true
Hi there not sure what could be happening but here is a example run in 3.6.0 and it works properly:
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="9090" doc:name="HTTP Listener Configuration"/>
<spring:beans>
<spring:bean id="objectStore" class="org.mule.util.store.SimpleMemoryObjectStore"/>
</spring:beans>
<http:request-config name="HTTP_Request_Configuration" host="localhost" port="9090" doc:name="HTTP Request Configuration"/>
<flow name="zzzFlow1" >
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-payload value="#['laleros']" doc:name="Set Payload"/>
<logger message="*************************** #[payload]" level="INFO" doc:name="Logger"/>
<until-successful maxRetries="5" doc:name="Until Successful" synchronous="true">
<http:request config-ref="HTTP_Request_Configuration" path="/t" method="POST" doc:name="HTTP"/>
</until-successful>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="*************************** #[payload]" level="INFO" doc:name="Logger"/>
</flow>
<flow name="tFlow1" >
<http:listener config-ref="HTTP_Listener_Configuration" path="/t" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
Here is the output I'm getting:
*******************************************************************************************************
* - - + APPLICATION + - - * - - + DOMAIN + - - * - - + STATUS + - - *
*******************************************************************************************************
* zzz * default * DEPLOYED *
*******************************************************************************************************
INFO 2015-02-23 14:10:17,540 [[zzz].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: *************************** laleros
INFO 2015-02-23 14:10:17,593 [[zzz].HTTP_Listener_Configuration.worker.02] org.mule.api.processor.LoggerMessageProcessor: laleros
INFO 2015-02-23 14:10:17,670 [[zzz].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: *************************** laleros
And just FYI, I reckon you need the transformer after the the http request to serialise the response for it usually returns the stream as payload.
HIH
your definition of until-successful scope requires additional configuration need to be done.
give glance over the below link
UntilSuccessful component to poll http endpoint till condition is met

Mule: How to use until successfull processor for service calls

Please help me on this logic. I have to call the service and get the response back.If the service is down or something have to retry 3 times and once exhausted need to log in DLQ.I'm using until successful processor.For success scenario i'm getting only null payload in logger.But i tried keeping the HTTP outbound end point without until successfull able to get the response from the service. Please find my xml config.
<flow name="Flow" doc:name="eFlow" tracking:enable-default-events="true">
<wmq:inbound-endpoint queue="InputQ" tracking:enable-default-events="true" connector ref="WMQ_Connector" doc:name="connector">
<wmq:transaction action="NONE"/>
</wmq:inbound-endpoint>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<set-session-variable variableName="originalPayload" value="#[payload]" doc:name="Store_Payload"/>
<choice tracking:enable-default-events="true" doc:name="Choice">
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Master']">
<data-mapper:transform config-ref="Master_grf" doc:name="Master"/>
</when>
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Request']">
<data-mapper:transform config-ref="Request_grf" doc:name="Bulk"/>
</when>
<otherwise>
<scripting:component doc:name="Throw_Exception">
<scripting:script engine="Groovy"><![CDATA[throw new IllegalArgumentException ('requests invalid') ]]>
</otherwise>
</choice>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<flow-ref name="Invoke_Service" doc:name="Flow Reference"/>
</flow>
<flow name="Invoke_Service" doc:name="Invoke_Service" tracking:enable-default-events="true">
<cxf:jaxws-client enableMuleSoapHeaders="true" doc:name="SOAP" operation="Request" serviceClass="com.valid.ICase"/>
<until-successful objectStore-ref="objectStore" maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="VM" doc:name="UntilSuccessful_SymboticService">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" address="http://localhost:1112/symbotic"/>
</until-successful>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="**********success***Payload: #[payload]*****" level="INFO" doc:name="Logger"/>
But incase of failure scenario until success retry 3 times ( works fine). I have tried request reply processor inside until also transactional processor. It is not working. Using Mule version 3.4.kindly suggest me.
Retried the same with request -reply processor as per the suggestion
<flow name="Flow" doc:name="eFlow" tracking:enable-default-events="true">
<wmq:inbound-endpoint queue="InputQ" tracking:enable-default-events="true" connector- ref="WMQ_Connector" doc:name="connector">
<wmq:transaction action="NONE"/>
</wmq:inbound-endpoint>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<set-session-variable variableName="originalPayload" value="#[payload]" doc:name="Store_Payload"/>
<choice tracking:enable-default-events="true" doc:name="Choice">
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Master']">
<data-mapper:transform config-ref="Master_grf" doc:name="Master"/>
</when>
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Request']">
<data-mapper:transform config-ref="Request_grf" doc:name="Bulk"/>
</when>
<otherwise>
<scripting:component doc:name="Throw_Exception">
<scripting:script engine="Groovy"><![CDATA[throw new IllegalArgumentException('requests other then Master andRequest') ]]>
</otherwise>
</choice>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<request-reply timeout="10000">
<vm:outbound-endpoint path="request"/>
<vm:inbound-endpoint path="reply"/>
</request-reply>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="**********success***Payload: #[payload]*****" level="INFO" doc:name="Logger"/>
</flow>
<flow name="Invoke_Service" doc:name="Invoke_Service" tracking:enable-default-events="true">
<vm:inbound-endpoint path="request" doc:name="VM"/>
<cxf:jaxws-client enableMuleSoapHeaders="true" doc:name="SOAP" operation="Request" serviceClass="com.valid.ICase"/>
<until-successful objectStore-ref="objectStore" maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="VM" doc:name="UntilSuccessful_Service">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" address="http://localhost:1112/symbotic"/>
</until-successful>
</flow>
Even then getting the null payload. Kindly suggest is this is the way your were directing me. Please correct me if im wrong.
until-successful is an asynchronous processor. It does not return response from service call.
Success or failure are defined as:
If the child message processor throws an exception, this is a failure.
If the child message processor does not return a message (e.g. is a one-way endpoint), this is a success.
If a 'failure expression' (see below) has been configured, the return message is evaluated against this expression to determine failure or not.
Otherwise:
If the child message processor returns a message that contains an exception payload, this is a failure.
If the child message processor returns a message that does not contain an exception payload, this is a success.
http://www.mulesoft.org/documentation/display/current/Routing+Message+Processors#RoutingMessageProcessors-UntilSuccessful