Mule - test an http get request with choice component - http

I have the following flow :
<flow name="SOAPWebService" doc:name="SOAPWebService">
<http:inbound-endpoint address="http://localhost:8088/esb/" exchange-pattern="request-response" doc:name="HTTP">
</http:inbound-endpoint>
<choice doc:name="Choice">
<when expression="#[payload.contains('c22')]">
<set-variable variableName="paramCtr" value="#[message.inboundProperties['ctr']]" doc:name="conteneur"/>
<set-variable variableName="paramC" value="#[message.inboundProperties['c']]" doc:name="critere"/>
<component class="com.example.components.SampleComponent" doc:name="Java"/>
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="C:\MuleStudio\SandBox\resources\PrepareRequestXMLPort.xsl" doc:name="XSLT">
<mulexml:context-property key="paramCtr" value="#[flowVars['paramCtr']]"/>
<mulexml:context-property key="paramC" value="#[flowVars['paramC']]"/>
</mulexml:xslt-transformer>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/ClientsDB/port" doc:name="PortWS"/>
</when>
<otherwise>
<set-variable variableName="paramCtr" value="#[message.inboundProperties['ctr']]" doc:name="conteneur"/>
<set-variable variableName="paramC" value="#[message.inboundProperties['c']]" doc:name="critere"/>
<component class="com.example.components.SampleComponent" doc:name="Java"/>
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="C:\MuleStudio\SandBox\resources\PrepareRequestXMLDouane.xsl" doc:name="XSLT">
<mulexml:context-property key="paramCtr" value="#[flowVars['paramCtr']]"/>
<mulexml:context-property key="paramC" value="#[flowVars['paramC']]"/>
</mulexml:xslt-transformer>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/ClientsDB/douane" doc:name="DouaneWS"/>
</otherwise>
</choice>
<byte-array-to-string-transformer doc:name="Byte Array to String" />
<file:outbound-endpoint path="C:\MuleStudio\SandBox\output" outputPattern="#[function:datestamp:dd-MM-yy]_#[function:systime].xml " responseTimeout="10000" doc:name="Outgoing File"/>
I want to test if an http request like http://localhost:8088/esb/?type=xxxx&id=1234 if it contains the String xxxx in a way to route the request to the desired web service proxy.
I've tried withe the expression expression="#[string.contains['xxxxx']]" but it does not seem to work.
any idea?
thank you.

Two things: You will need to replace "string" with the property you want to execute on. Either a message property or payload etc. i.e #[payload.contains...].
"contains" is a Java method on java.lang.String so you need to use standard Java method invocation with () instead of [].
Working example:
<choice doc:name="Choice">
<when expression="#[payload.contains('xxxx')]">
<logger level="ERROR" message="YES" />
</when>
<otherwise>
<logger level="ERROR" message="NO" />
</otherwise>
</choice>
Or directly work off inbound properties for your query params:

After your http inbound use set-variable to store your query params into flow variables.
And then use the flow variales in your expression.
<set-variable value="#[message.inboundProperties['id']]" variableName="paramId"></set-variable>
<set-variable value="#[message.inboundProperties['type']]" variableName="paramType"></set-variable>
or you can directly use inbound property for comparision.
<when expression="#[message.inboundProperties['type']== 'XXXX']">

Related

Migration of code Mule 3 to Mule 4 and 'rest-router' is not supported in Mule 4

I have one application which is Mule 3, now I need to migrate it into Mule 4.
I implemented and changed some code but it through exceptions that tag not supported i.e 'rest-router' is not supported.
<rest-router:router templateUri="${igate.url}">
<!--Migration ERROR: The migration of 'rest-router' is not supported.-->
<!-- For more information refer to:-->
<!-- * https://docs.mulesoft.com/mule-runtime/4.1/migration-connectors>--
<!-- * https://beta.docs.stgx.mulesoft.com/beta-mule-migration-tool/mule-runtime/4.1/migration-tool.html#unsupported_connectors-->
<rest-router:post>
<ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" doc:name="JSON to Object">
<ee:message>
<ee:set-payload>%dw 2.0 output application/java --- payload as Object { class: 'com.ifi.igate.model.Transaction'}</ee:set-payload>
</ee:message>
</ee:transform>
<flow-ref name="igate-object-flow" doc:name="igate-object-flow" />
<ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" doc:name="Object to JSON" mimeType="application/json">
<ee:message>
<ee:set-payload>%dw 2.0 output application/json --- payload</ee:set-payload>
</ee:message>
</ee:transform>
</rest-router:post>
</rest-router:router>
Full XML file in Mule 3 which we need to migrate on Mule 4 -
<spring:beans>
<spring:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="ignoreUnresolvablePlaceholders" value="true"/>
<spring:property name="location" value="igate.properties"/>
</spring:bean>
<spring:bean id="validation" class="com.ifi.igate.integration.iclient.ValidationTransformer">
<spring:property name="transactionTypes">
<spring:list>
<spring:value>INQ-REQ</spring:value>
<spring:value>DEP-REQ</spring:value>
<spring:value>WIT-REQ</spring:value>
</spring:list>
</spring:property>
</spring:bean>
<spring:bean id="iGateStub" class="com.ifi.igate.stub.IGateStub">
<spring:property name="handlers">
<spring:map>
<spring:entry key="INQ-REQ">
<spring:bean class="com.ifi.igate.stub.handlers.InqHandler"/>
</spring:entry>
<spring:entry key="WIT-REQ">
<spring:bean class="com.ifi.igate.stub.handlers.WitHandler"/>
</spring:entry>
<spring:entry key="DEP-REQ">
<spring:bean class="com.ifi.igate.stub.handlers.DepHandler"/>
</spring:entry>
</spring:map>
</spring:property>
</spring:bean>
</spring:beans>
<rest-router:config/>
<http:connector name="httpConnector" doc:name="HTTP\HTTPS">
<receiver-threading-profile maxThreadsActive="10" />
</http:connector>
<flow name="igate-json-flow" doc:name="igate-json-flow">
<http:inbound-endpoint exchange-pattern="request-response" host="${igate.host}" port="${igate.port}" doc:name="HTTP"/>
<rest-router:router templateUri="${igate.url}">
<rest-router:post>
<json:json-to-object-transformer xmlns:json="http://www.mulesoft.org/schema/mule/json" returnClass="com.ifi.igate.model.Transaction" doc:name="JSON to Object"></json:json-to-object-transformer>
<flow-ref name="igate-object-flow" doc:name="igate-object-flow"/>
<json:object-to-json-transformer xmlns:json="http://www.mulesoft.org/schema/mule/json" doc:name="Object to JSON" mimeType="application/json"></json:object-to-json-transformer>
</rest-router:post>
</rest-router:router>
<rest-router:router templateUri="${igate-stub.url}">
<rest-router:post>
<json:json-to-object-transformer xmlns:json="http://www.mulesoft.org/schema/mule/json" returnClass="com.ifi.igate.model.Transaction" doc:name="JSON to Object"/>
<component doc:name="IGateStub">
<spring-object bean="iGateStub"/>
</component>
<json:object-to-json-transformer xmlns:json="http://www.mulesoft.org/schema/mule/json" doc:name="Object to JSON" mimeType="application/json"/>
</rest-router:post>
</rest-router:router>
</flow>
<sub-flow name="igate-object-flow" doc:name="igate-object-flow">
<transformer ref="validation"/>
<choice>
<when expression="#[message.payload.trxstatus == 0]">
<logger message="#[message.payload.trxreason]" level="ERROR" doc:name="Logger"/>
</when>
<otherwise>
<set-variable variableName="request" value="#[message.payload]" doc:name="save request"/>
<flow-ref name="promotions-flow" doc:name="Promotions Flow"/>
<flow-ref name="ifi-membership-flow" doc:name="Accumulate Spending"/>
<!-- logger message="Before backend" level="ERROR" doc:name="Logger"/-->
<flow-ref name="rewards-flow" doc:name="Rewards Flow"/>
<choice>
<when expression="#[message.payload.values['PTS']>0 || message.payload.trxtype=='INQ-REQ']">
<flow-ref name="${igate.membership}-membership-flow" doc:name="External Membership Flow"/>
</when>
<otherwise>
<vm:outbound-endpoint exchange-pattern="request-response" path="membership/ifi" />
</otherwise>
</choice>
<!-- logger message="After backend" level="ERROR" doc:name="Logger"/-->
<flow-ref name="promotions-flow" doc:name="Promotions Flow"/>
<flow-ref name="rewards-flow" doc:name="Rewards Flow"/>
<flow-ref name="ifi-membership-flow" doc:name="Manage balances"/>
<flow-ref name="pricing-flow" doc:name="Pricing Flow"/>
</otherwise>
</choice>
</sub-flow>
</mule>
'rest-router' is not supported in Mule 4 only need replacement for that tag or How I can migrate it into Mule 4.
rest-router seems to be an unsupported and unmaintained (last commit is from 2012) module for Mule 3. You best bet is to migrate from scratch and use APIKit instead. You will need to write a RAML specification for your API and Studio will create all the needed scaffolding from it.

mule 3.5 follow redirects on outbound endpoint

I have the simple flows as following. When we hit one flow, it hits another flow and gets http.status 302 and Location , which means it must redirect to the location in Location header. But it is throwing exception.
<flow name="httpconnectorFlowRedirection">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9876" path="redirect" connector-ref="NoSessionEncodingConnector" doc:name="HTTP"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="9876" method="POST" doc:name="HTTP" path="temp" connector-ref="NoSessionEncodingConnector" contentType="text/plain"
followRedirects="true" />
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
<flow name="temp_flow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9876" path="temp" connector-ref="NoSessionEncodingConnector" doc:name="HTTP" />
<logger message="in temp flow" level="INFO" doc:name="Logger"/>
<set-property propertyName="http.status" value="307" doc:name="Property" />
<set-property propertyName="Location" value="http://localhost:9876/samplehttp" doc:name="Property" />
</flow>
Error I am getting is as follows
org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://localhost:9876/temp, connector=HttpConnector
{
name=NoSessionEncodingConnector
lifecycle=start
this=14c5f0c
numberOfConcurrentTransactedReceivers=4
createMultipleTransactedReceivers=true
connected=true
supportedProtocols=[http]
serviceOverrides=
session.handler=org.mule.session.NullSessionHandler
}
, name='endpoint.http.localhost.9876.temp', mep=REQUEST_RESPONSE, properties={exceptionOnMessageError=true, http.method=POST, followRedirects=true, Content-Type=text/plain}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: PostMethod
Type : org.mule.api.transport.DispatchException
Code : MULE_ERROR--2
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/Dispat chException.html
Payload : org.apache.commons.httpclient.methods.PostMethod#14efe2e
********************************************************************************
I am getting this error only when follow redirects set to true on outbound endpoint
I am using mule 3.5.
I got the answer. I need to use GET reqeust for successful redirection.
But if I use http listeners(since mule 3.6), I am able to redirect even for POST requests. Consider the following example.
<http:listener-config name="GlobalHTTPConnector" host="localhost" port="9876" doc:name="HTTP Listener Configuration" basePath="mulelearning"/>
<flow name="redirection-flow">
<http:listener config-ref="GlobalHTTPConnector" path="/requestredir" doc:name="HTTP"/>
<!--
When followRedirects is set to true, when http.status from called service is redirection(eg:301), it redirects to new location.
In this case /redFlow1 sends a redirection code 301 and location header. Hence it redirects to /redFlow2 (see the flows below) and gives us the response 'payload from red-flow2'
-->
<http:request config-ref="HTTP_Request_Configuration" path="/redFlow1" method="POST" followRedirects="true" doc:name="HTTP" />
</flow>
<flow name="red-ser1">
<http:listener config-ref="GlobalHTTPConnector" path="/redFlow1" doc:name="HTTP"/>
<logger level="INFO" doc:name="Logger" message="I am in red-flow1"/>
<set-payload value="payload from red-flow1" />
<set-property propertyName="http.status" value="301" doc:name="Property" />
<set-property propertyName="Location" value="http://localhost:9876/mulelearning/redFlow2" doc:name="Property" />
</flow>
<flow name="red-ser2">
<http:listener config-ref="GlobalHTTPConnector" path="/redFlow2" doc:name="HTTP"/>
<set-payload value="payload from red-flow2" />
<logger level="INFO" doc:name="Logger" message="I am in red-flow2"/>
</flow>

How to encrypt a single element if a JSON response in Mule?

I have a JSON message say
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
I would want to encrypt on the Id field in the JSON like below.
{"menu": {
"id": "98jshr0837#",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
I use the below code for encryption:
<flow name="hf-eai-crm-plan-search-detail-api-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="#[message.payload.menu.id]" level="INFO" doc:name="Logger"/>
<encryption:decrypt config-ref="Encryption" doc:name="Encryption"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
Let me know how this can be achieved?
I have modified your flow a bit and able to get encrypted value of a single element as follows :-
<flow name="hf-eai-crm-plan-search-detail-api-flow" doc:name="hf-eai-crm-plan-search-detail-api-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>
<logger message="before encryption #[message.payload.menu.id]" level="INFO" doc:name="Logger"/>
<encryption:encrypt config-ref="Encryption" doc:name="Encryption" using="JCE_ENCRYPTER" input-ref="#[message.payload.menu.id]"/>
<logger message="After encryption #[message.payload]" level="INFO" doc:name="Logger"/>
<encryption:decrypt config-ref="Encryption" using="JCE_ENCRYPTER" doc:name="Decrypt the xml payload" />
<logger message="Element After Decryption :- #[message.payload]" level="INFO" category="NormalEncryption" doc:name="Logger"/>
</flow>
You can see in the below screenshots for your reference :-
I have also decrypted to show you the value of element
EDITED Solution
Well, there is an attribute xpath in <encryption/> which can be used to encrypt an element in XML. But unfortunately, I didn't find anything for JSON that can parse it and encrypt an element from it... So I created the following 2 solutions for you :-
Solution1:-
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<encryption:config name="Encryption" enableLanguage="true" doc:name="Encryption">
<encryption:jce-encrypter-config algorithm="CAST5" key="poso123456789lal" />
</encryption:config>
<flow name="hf-eai-crm-plan-search-detail-api-flow" >
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>
<set-variable doc:name="Variable" value="#[message.payload.menu.value]" variableName="value"/>
<set-variable doc:name="Variable" value="#[message.payload.menu.popup]" variableName="popup"/>
<logger message="before encryption #[message.payload.menu.id]" level="INFO" doc:name="Logger"/>
<encryption:encrypt config-ref="Encryption" doc:name="Encryption" using="JCE_ENCRYPTER" input-ref="#[message.payload.menu.id]"/>
<set-variable doc:name="Variable" value="#[message.payload]" variableName="id"/>
<logger message="Encryption #[message.payload]" level="INFO" doc:name="Logger"/>
<expression-transformer
expression="#[[
'menu':[
'id': flowVars.id,
'value': flowVars.value,
'popup': flowVars.popup
]
]
]" doc:name="Expression"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="After encryption #['\n' + message.payload]" level="INFO" doc:name="Logger"/>
</flow>
Here you can see I have parsed the JSON payload and saved each element value in variables, and then using the variables I am able to construct the JSON you required dynamically using Expression Transformer and also included the encrypted element in it.
Alternate Solution :-
<flow name="hf-eai-crm-plan-search-detail-api-flow" >
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>
<set-variable doc:name="Variable" value="#[message.payload]" variableName="myPayload"/>
<logger message="before encryption #[message.payload.menu.id]" level="INFO" doc:name="Logger"/>
<set-variable doc:name="Variable" value="#[message.payload]" variableName="id"/>
<encryption:encrypt config-ref="Encryption" doc:name="Encryption" using="JCE_ENCRYPTER" input-ref="#[message.payload.menu.id]"/>
<logger message="Encryption #[message.payload] " level="INFO" doc:name="Logger"/>
<expression-transformer expression="#[flowVars.myPayload.menu.id=message.payload;flowVars.myPayload]" />
<json:object-to-json-transformer doc:name="Object to JSON"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>​
Here you can see, using Expression transformer, I am able to update only the element I required to encrypt
So using any of the above solution you will get to encrypt the element you require in the JSON as below :-
Hope this help :)
To keep the payload we can utilize Message Enricher. Please refer to the following configuration, it might meet your purpose:
<flow name="hf-eai-crm-plan-search-detail-api-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/encrypt" doc:name="HTTP" allowedMethods="POST" />
<json:json-to-object-transformer returnClass="java.util.Map" doc:name="JSON to Object" />
<logger message="The JSON before encryption: #[payload]" level="INFO" doc:name="Logger - initial" />
<enricher source="#[payload]" target="#[payload.menu.id]" doc:name="Message Enricher">
<encryption:encrypt config-ref="Encryption" input-ref="#[message.payload.menu.id]" using="JCE_ENCRYPTER" doc:name="Encryption"/>
</enricher>
<logger message="The JSON after encryption: #[payload]" level="INFO" doc:name="Logger - id encrypted" />
<enricher source="#[payload]" target="#[payload.menu.id]" doc:name="Message Enricher">
<encryption:decrypt config-ref="Encryption" input-ref="#[payload.menu.id]" using="JCE_ENCRYPTER" doc:name="Decryption"/>
</enricher>
<logger message="The JSON after decryption: #[payload]" level="INFO" doc:name="Logger - decrypted (back to original)" />
</flow>
The result of this configuration is:
Without JSON to Object transformer, just modifying your configuration and add a little bit tricky String manipulation:
<flow name="hf-eai-crm-plan-search-detail-api-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/encrypt" doc:name="HTTP" allowedMethods="POST" />
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="The JSON before encryption: #[payload]" level="INFO" doc:name="Logger - initial" />
<set-variable variableName="jsonOriginal" value="#[payload]" doc:name="Keep the original JSON"/>
<set-payload value="#[json:menu]" doc:name="Set Payload with JSON menu"/>
<set-variable variableName="idValue" value="#[json:id]" doc:name="Get value of id"/>
<encryption:encrypt config-ref="Encryption" input-ref="#[flowVars.idValue]" using="JCE_ENCRYPTER" doc:name="Encryption"/>
<logger message="The id after encryption: #[payload]" level="INFO" doc:name="Logger - id encrypted" />
<set-payload value="#[flowVars.jsonOriginal.replaceAll("\"id\": \"" + flowVars.idValue + "\"", "\"id\": \"" + payload + "\"")]" doc:name="Set Payload"/>
<logger message="The JSON after encryption: #[payload]" level="INFO" doc:name="Final JSON" />
</flow>
Following is the result:

Mule ESB HTTP POST Request with URL-Form-Encoded Body

I'm new in Mule ESB and trying to send a post request to a REST Service. The body of the request is in String form and the request should be x-www-form-urlencoded. I set the payload to my parameters and send the request to the REST Service but I get an exception:
Failed to invoke REST service "http://username:password#192.168.10.252/api/rest/session/login.json". Message payload is of type: String
My Rest URL is: (#[restURL]) ${dms.host}/api/rest/session/login.json
My parameter is (set as payload #[restBody]): username=user&password=pass
<sub-flow name="RESTrequestToDMS" doc:name="RESTrequestToDMS" processingStrategy="synchronous">
<set-variable variableName="originalMessage" value="#[payload]" doc:name="Backup original message"/>
<logger message="#[restBody]" level="INFO" doc:name="Logger"/>
<choice doc:name="Choice">
<when expression="restHTTPmethod == 'POST'">
<processor-chain>
<set-payload value="#[restBody]" doc:name="Set Payload"/>
<http:rest-service-component httpMethod="POST" serviceUrl="http://${dms.user}:${dms.pass}##[restURL]"></http:rest-service-component>
</processor-chain>
</when>
<when expression="restHTTPmethod == 'GET'">
<processor-chain>
<http:rest-service-component httpMethod="GET" serviceUrl="http://${dms.user}:${dms.pass}##[restURL]?#[restBody]"></http:rest-service-component>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="Unknown http method type is provided! " level="ERROR" doc:name="Logger"/>
</processor-chain>
</otherwise>
</choice>
<json:json-to-object-transformer returnClass="java.util.Map" doc:name="JSON to Object"/>
<echo-component doc:name="Echo"/>
<set-variable variableName="RESTResponse" value="#[payload]" doc:name="set RESTResponse"/>
<set-payload value="#[flowVars['originalMessage']]" doc:name="Restore Original Message"/>
</sub-flow>
Can somebody help me figure this out please?
Thanks a lot in advance.
Note: Updated according to David's reply.
-------------------UPDATE--------------------
So now, for testing purposes, I have modified the flow like this:
<set-payload value="#[restBody]" doc:name="Set Payload"/>
<custom-transformer class="de.mfg.osii.http.StringToURIParametersMapTransformer" doc:name="String To URI Parameters"/>
<http:rest-service-component httpMethod="POST" serviceUrl="http://${dms.user}:${dms.pass}##[restURL]">
<http:requiredParameter key="username" value="#[payload.get('username')]" />
<http:requiredParameter key="password" value="#[payload.get('password')]" />
</http:rest-service-component>
So now the payload is: {username=user, password=pass}
But now when I try to run this, I get the following error:
1. Failed to invoke REST service "http://user:pass#192.168.10.252/api/rest/session/login.json". Message payload is of type: LinkedHashMap (org.mule.transport.http.components.RestServiceException)
Update: The above problem, the exception, has just been solved by adding a message-property "Content-Type" with the value "application/x-www-form-urlencoded".
Still the last part, below, remains a mystery for me :)
The other thing is, as I stated in the comment to David's answer, can I add the required parameters for the rest component in an adaptive way? To be more clearer, I do not want to create different flows for every different request. I have the parameter map in the payload, so I want to iterate over them and put them in the required parameters. Is something like this possible?
Thanks a lot in advance!
-------------------UPDATE--------------------
So, I've modified my flow and used David's suggestions. However, now, I'm getting an HTTP 405 error (Method not allowed). But I'm sure I'm posting to the correct address with correct content-type. What is the reason for this? Does anybody have an idea?
My payload coming into this flow is a string (url encoded parameters) such as ->
sessionId=9eub9gm7k7oc1ub81dhef6t46q&xml=%3CObjectList%3E%3CFolderObject%3E%3CAddToFolder%20RefType%3D%22Path%22%20ClassName%3D%22FolderObject%22%3E%3C!%5BCDATA%5B%2FfolderPath%5D%5D%3E%3C%2FAddToFolder%3E%3CName%3E%3C!%5BCDATA%5Baaa%5D%5D%3E%3C%2FName%3E%3CDescription%3E%3C!%5BCDATA%5BRequests%20from%20user%20aaa%20are%20stored%20in%20this%20folder%5D%5D%3E%3C%2FDescription%3E%3CNoErrorIfExist%2F%3E%3C%2FFolderObject%3E%3C%2FObjectList%3E
<flow name="RESTrequestToDMS" doc:name="RESTrequestToDMS" processingStrategy="synchronous">
<set-variable variableName="originalMessage" value="#[payload]" doc:name="Backup original message"/>
<choice doc:name="Choice">
<when expression="restHTTPmethod == 'POST'">
<processor-chain>
<set-payload value="#[restBody]" doc:name="Set Payload"/>
<logger message="The payload before http post is: #[message.payload]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" doc:name="HTTP" address="http://#[restURL]" user="${dms.user}" password="${dms.pass}" contentType="application/x-www-form-urlencoded">
</http:outbound-endpoint>
</processor-chain>
</when>
<when expression="restHTTPmethod == 'GET'">
<processor-chain>
<http:outbound-endpoint method="GET" exchange-pattern="request-response" doc:name="HTTP" address="http://#[restURL]?#[restBody]" user="${dms.user}" password="${dms.pass}" contentType="application/x-www-form-urlencoded">
</http:outbound-endpoint>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="Unknown http method type is provided! " level="ERROR" doc:name="Logger"/>
</processor-chain>
</otherwise>
</choice>
<echo-component doc:name="Echo"/>
<choice doc:name="Choice">
<when expression="payload != null && payload != empty && payload != ''">
<processor-chain>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="java.util.Map"/>
<set-variable variableName="RESTResponse" value="#[payload]" doc:name="set RESTResponse"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="The payload is null or empty! HTTP response code is: #[message.inboundProperties['http.status']]" level="INFO" doc:name="Logger"/>
<set-variable variableName="RESTResponse" value="#[message.inboundProperties['http.status']]" doc:name="Set HTTP Status Code"/>
</processor-chain>
</otherwise>
</choice>
<set-payload value="#[flowVars['originalMessage']]" doc:name="Restore Original Message"/>
</flow>
Here is how you pass parameters to be URL encoded with the rest-service-component:
<http:rest-service-component httpMethod="POST"
serviceUrl="http://${dms.user}:${dms.pass}##[restURL]">
<http:requiredParameter key="username" value="user" />
<http:requiredParameter key="password" value="pass" />
</http:rest-service-component>

Mule - choice component issue

When I run my flow, I get the following error `
<org.apache.cxf.staxutils.DepthXMLStreamReader>
<reader class="org.mule.module.cxf.support.StreamClosingInterceptor$1">
<reader class="com.ctc.wstx.sr.ValidatingStreamReader">
<mXml11>false</mXml11>
<mInputBuffer>xmlns:ns2="http://wsdouane/"><return><douanePK><idConteneurId>ctr1</idConteneurId><idCritereId>C11</idCritereId></douanePK><valeurId>oui</valeurId></return></ns2:findResponse></S:Body></S:Envelope>.................
we can see the correct soap response starting from the <mInputBuffer>, is there a way to get only the soap response??
here is my flow
<flow name="SOAPWebService" doc:name="SOAPWebService">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:8088/esb" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<choice doc:name="Choice">
<when expression="#[payload.contains('C22')]">
<set-variable variableName="paramCtr" value="#[message.inboundProperties['ctr']]" doc:name="conteneur"/>
<set-variable variableName="paramC" value="#[message.inboundProperties['c']]" doc:name="critere"/>
<component class="com.example.components.SampleComponent" doc:name="Java"/>
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="C:\MuleStudio\SandBox\resources\PrepareRequestXMLPort.xsl" doc:name="XSLT">
<mulexml:context-property key="paramCtr" value="#[flowVars['paramCtr']]" />
<mulexml:context-property key="paramC" value="#[flowVars['paramC']]" />
</mulexml:xslt-transformer>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/ClientsDB/port" doc:name="PortWS"/>
<byte-array-to-string-transformer doc:name="Byte Array to String" />
</when>
<otherwise>
<set-variable variableName="paramCtr" value="#[message.inboundProperties['ctr']]" doc:name="conteneur"/>
<set-variable variableName="paramC" value="#[message.inboundProperties['c']]" doc:name="critere"/>
<component class="com.example.components.SampleComponent" doc:name="Java"/>
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="C:\MuleStudio\SandBox\resources\PrepareRequestXMLDouane.xsl" doc:name="XSLT">
<mulexml:context-property key="paramCtr" value="#[flowVars['paramCtr']]" />
<mulexml:context-property key="paramC" value="#[flowVars['paramC']]" />
</mulexml:xslt-transformer>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" address="http://localhost:8080/ClientsDB/douane" doc:name="DouaneWS"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
</otherwise>
</choice>
<xm:object-to-xml-transformer doc:name="Object to XML"/>
<file:outbound-endpoint path="C:\MuleStudio\SandBox\output" outputPattern="#[function:datestamp:dd-MM-yy]_#[function:systime].xml " responseTimeout="10000" doc:name="Outgoing File"/>
</flow>
thank you.
This expression #[payload.contains('c22')] can't work because the payload is an InputStream. Aren't you seeing stack traces in Mule's logs?
In any case, try adding <object-to-string-transformer /> before the choice and see if it fixes the issue.
EDIT:
The problem is that you're using XStream (in xm:object-to-xml-transformer) to serialize the CXF response object (org.apache.cxf.staxutils.DepthXMLStreamReader) into XML. The CXF response should not be messed with and should be handled by the cxf:proxy-client in the response phase of the flow. The xm:object-to-xml-transformer and file:outbound-endpoint after the choice router are probably disturbing this mechanism. Try to wrap them in a response element above the choice router to they execute after it in the response phase.
Note that I have already given you this advice in your other question https://stackoverflow.com/a/16615537/387927 but you did not react to it.
Also I don't think byte-array-to-string-transformer does anything: the message payload after the http:outbound-endpoints should be org.apache.cxf.staxutils.DepthXMLStreamReader, preventing this transformer to fire.

Resources