Error while request processing in mule application in tomcat 7 server - mule

While request processing mule application giving following exception:-
javax.servlet.ServletException: Property mule.context not set on ServletContext.
the flow snippet is like below :-
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
<dw:transform-message doc:name="Transform Message" me
</dw:transform-message>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
</flow>

Related

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"/>

Mule Flow Reference Component throwing TransformerMessagingException while passing json

I have two flow one receive the xml payload and another json. I am routing the xml call to json flow using mule flow reference component after converting the xml to json payload. and second flow returns the json payload that i need to convert back to xml and reply to client.
My mule flow reference is throwing TransformerMsgException while receiving the json response from second flow.
Failed to transform from "json" to "java.lang.String" (org.mule.api.transformer.TransformerException). Message payload is of type: String
Here are the code for your reference -
<flow name="post:/chkdb:application/json:chkd-config">
<logger message="========json payload==>>>>==== #[message.payload]" level="INFO" doc:name="Logger"/>
<set-variable variableName="GGG_Number" value="#[json:ggg]" doc:name="Variable"/>
<!-- db call returns the payload-->
<choice doc:name="Choice">
<when expression="#[message.payload.size()>0]">
<set-payload value="{"indicator":"True"}" mimeType="application/json" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="{"indicator":"False"}" mimeType="application/json" doc:name="Set Payload"/>
</otherwise>
</choice>
<logger message="=========after producing json output=======" level="INFO" doc:name="Logger"/>
</flow>
<flow name="post:/chkdb:application/xml:chkdb-config">
<logger message="========= xml payload======== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:xml-to-json-transformer mimeType="application/json" doc:name="XML to JSON"/>
<flow-ref name="post:/chkdb:application/json:chkdb-config" doc:name="post:/chkdb:application/json:chkdbapi-config"/> <!-- Getting exception here -->
<logger message=" after subflow call ==== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:json-to-xml-transformer mimeType="application/xml" doc:name="JSON to XML"/>
<logger message="after json to xml conversion" level="INFO" doc:name="Logger"/>
</flow>
XML Request -
<ggg>DeJmp03bkqALlRFYmgu4+A==</ggg>
How i should retrieve the json response from other flow to current flow.
There is something missing here
First flow name: post:/chkdb:application/json:chkdbapi-config
Second flow name: post:/chkdb:application/xml:chkdbapi-config
Flow ref in second flow: post:/chkdb:application/json:chkdb-config
You are not referencing First flow.
So from your flow posted I can find few issues as follows :-
1. You are using where is the flow post:/chkdb:application/json:chkdb-config doesn't exits and it should be post:/chkdb:application/json:chkdbapi-config instead
2. Right now in the flow you are using <when expression="#[message.payload.size()>0]"> where as the message payload is in String format right now.
So, you can either use <when expression="#[message.payload.length()>0]">, using length() instead of size() or put a <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object"/>before choice if you use #[message.payload.size()>0]
So the full code will be something as follows :-
<flow name="post:/chkdb:application/json:chkdbapi-config">
<logger message="========json payload==>>>>==== #[message.payload]" level="INFO" doc:name="Logger"/>
<!-- <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object"/> --> <!-- incase you use #[message.payload.size()>0] in your choice -->
<!-- db call returns the payload-->
<set-variable variableName="GGG_Number" value="#[json:ggg]" doc:name="Variable"/>
<choice doc:name="Choice">
<when expression="#[message.payload.length()>0]">
<set-payload value="{"indicator":"True"}" mimeType="application/json" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="{"indicator":"False"}" mimeType="application/json" doc:name="Set Payload"/>
</otherwise>
</choice>
<logger message="=========after producing json output=======" level="INFO" doc:name="Logger"/>
</flow>
<flow name="post:/chkdb:application/xml:chkdbapi-config">
<logger message="========= xml payload======== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:xml-to-json-transformer mimeType="application/json" doc:name="XML to JSON"/>
<flow-ref name="post:/chkdb:application/json:chkdbapi-config" doc:name="post:/chkdb:application/json:chkdbapi-config"/> <!-- Getting exception here -->
<logger message=" after subflow call ==== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:json-to-xml-transformer mimeType="application/xml" doc:name="JSON to XML"/>
<logger message="after json to xml conversion" level="INFO" doc:name="Logger"/>
</flow>

JAXB with HTTP inbounds throws exception An invalid return type "class [B" was specified for transformer "JAXBMarshallerTransformer"

When I have XML payload from JMS inbound, XML to JAXB works as expected. But when I have same XML payload from HTTP inbound it throws an exception
An invalid return type "class [B" was specified for transformer "JAXBMarshallerTransformer" (org.mule.api.transformer.TransformerException)
Is it not a fair expectation from "XML to JAXB" component to have a XML payload from HTTP inbound? Please let me know what I am missing here.
Flow xml with with JMS and HTTP inbound. Only JMS inbound works as expected,
<flow name="productdemoFlow">
<jms:inbound-endpoint queue="my.test" connector-ref="Active_MQ" doc:name="JMS">
<jms:transaction action="NOT_SUPPORTED"/>
</jms:inbound-endpoint>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<mulexml:jaxb-xml-to-object-transformer returnClass="com.chc.model.Product" jaxbContext-ref="JAXB_Context" doc:name="XML to JAXB Object"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
<flow name="productdemoFlow1">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" allowedMethods="POST" doc:name="HTTP" />
<logger message="#["Payload ---------->" + payload.getClass().getName()]" level="INFO" doc:name="Logger"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="#["Payload ---------->" + payload]" level="INFO" doc:name="Logger"/>
<mulexml:jaxb-xml-to-object-transformer encoding="windows-1252" mimeType="application/xml" jaxbContext-ref="JAXB_Context" doc:name="XML to JAXB Object"/>
</flow>
If I am not wrong, what you see is what you would expect.
The JMS inbound endpoint follows (by default, as in your case) a "one way" pattern, there is no response message to the client so there is no special requirement for the payload at the end of the flow.
The HTTP inbound endpoint follows (by default, as in your case) a "request-response" pattern so the payload, before sending the response to the client, should be of a type managed by the endpoint. In your case it is a java object instance of a not managed type, it must be converted to a correct type (String, InputStream, byte[], ...). For example:
<mulexml:jaxb-object-to-xml-transformer />

How to catch exceptions in the Mule foreach scope but keep the process going?

I am new to Mule ESB. I have created a simple flow that loops through a list of orders and calls the Magento API to update the order statuses one by one. My problem is that if there are any exception occurs in the foreach scope, the whole process tops. I tried to use the Exception Strategy to capture the exception and it did capture the exception. But how to resume the process? I didn't find much info with google search. Maybe I was doing something wrong with the flow. How do we normally handle this in Mule?
Here is my flow in xml.
<flow name="Update_Magento_Order_Status_AU" doc:name="Update_Magento_Order_Status_AU" initialState="started">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="10" timeUnit="MINUTES"/>
<jdbc-ee:outbound-endpoint exchange-pattern="request-response" queryKey="GET_ORDERS_BY_STATUS_QUERY" queryTimeout="-1" connector-ref="DSEDatabase" doc:name="Get Orders By Status"/>
</poll>
<flow-ref name="ProcessOrderStastusUpdate" doc:name="Process Order Status Update"/>
</flow>
<flow name="ProcessOrderStastusUpdate" doc:name="ProcessOrderStastusUpdate">
<foreach collection="#[payload]" doc:name="For Each">
<component doc:name="Set Magento Order Status for Update">
<singleton-object class="com.dse.esb.component.OrderStatusMapperComp">
<property key="as400OrderStatuses" value="${as400.orderstatuses}"/>
<property key="magentoOrderStatuses" value="${magento.orderStatuses}"/>
</singleton-object>
</component>
<logger message="About to update Magento Order Status" level="INFO" doc:name="Logger"/>
<magento:add-order-comment config-ref="Magento" comment="Updated by Mule ESB with AS400 order status: #[payload.TRNSTS]" orderId="#[payload.EPGORDNBR]" status="#[flowVars['magentoOrderStatus']]" doc:name="Update Magento Order Status"/>
</foreach>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy doc:name="default">
<logger message="Handle default exception" level="INFO" category="==============>>>>>>>>>>>>" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
Use a private flow for the content of the for-each with its own exception strategy. THe exception will be handled in the private flow and the parent flow should be able to continue. Something like:
<flow name="ProcessOrderStastusUpdate">
<foreach collection="#[payload]" doc:name="For Each">
<flow-ref name="privateFlow" />
</foreach>
</flow>
<flow name="privateFlow">
<component doc:name="Set Magento Order Status for Update">
<singleton-object class="com.dse.esb.component.OrderStatusMapperComp">
<property key="as400OrderStatuses" value="${as400.orderstatuses}"/>
<property key="magentoOrderStatuses" value="${magento.orderStatuses}"/>
</singleton-object>
</component>
<logger message="About to update Magento Order Status" level="INFO" doc:name="Logger"/>
<magento:add-order-comment config-ref="Magento" comment="Updated by Mule ESB with AS400 order status: #[payload.TRNSTS]" orderId="#[payload.EPGORDNBR]" status="#[flowVars['magentoOrderStatus']]" doc:name="Update Magento Order Status"/>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy doc:name="default">
<logger message="Handle default exception" level="INFO" category="==============>>>>>>>>>>>>" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>

Mule and java.lang.reflect.Method cannot be cast to java.lang.String in flow-ref

I have a sub-flow to invoke a soap service (req:String , response:String)
<sub-flow name="vinculaValidaServiceClienteFlow" doc:name="vinculaValidaServiceClienteFlow">
<cxf:jaxws-client operation="vinculaServicioIngreso" serviceClass="...VinculaValidaService" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8070/pic/vinculaValidaService" doc:name="HTTP"/>
</sub-flow>
I have a simple service that I'm calling from a test flow. This service can be invoked well with MuleClient:
<flow name="vinculacionFlow2" doc:name="vinculacionFlow2">
<vm:inbound-endpoint exchange-pattern="request-response" path="test2" doc:name="VM"/>
<logger level="INFO" doc:name="Logger"/>
<flow-ref name="vinculaValidaServiceClienteFlow" doc:name="Flow Reference"/>
</flow>
When I include the flow-ref in a main flow, can not be invoked, although the unit test was successful.
<flow name="vinculaServiceFlow" doc:name="vinculaServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" doc:name="vinculaServiceHTTP" ref="vinculaServiceHTTPEndpoint"/>
<logger level="INFO" doc:name="Logger" message="luna es #[payload]"/>
<cxf:jaxws-service doc:name="vinculaServiceSOAP" serviceClass="...service.VinculaService"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="marte es #[payload]" level="INFO" doc:name="printpayload"/>
<set-variable variableName="cedula" value="#[message.payload]" doc:name="Variable"/>
<logger message="jupiter es #[flowVars['cedula']]" level="INFO" doc:name="printVar"/>
<set-payload value="#[message.payloadAs(java.lang.String)]" doc:name="Set Payload"/>
<logger message="sol es #[payload]" level="INFO" doc:name="printpayload"/>
<flow-ref name="vinculaValidaServiceClienteFlow" doc:name="Flow Reference"/>
<scripting:transformer doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[import ec.gob.presidencia.tecnologia.pic.vincula.service.VinculaResponse def responseVincula = new VinculaResponse("54545366644","12063139", "se puede vincular") return responseVincula ]]>
</scripting:script>
</scripting:transformer>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<set-payload value="Error durante el procesamiento del servicio de vinculacion" doc:name="Set mensejae error"/>
</catch-exception-strategy>
</flow>
The resulting exception is:
Exception stack is:
1. java.lang.reflect.Method cannot be cast to java.lang.String(java.lang.ClassCastException)
org.mule.module.cxf.CxfOutboundMessageProcessor:338 (null)
2. java.lang.reflect.Method cannot be cast to java.lang.String. Failed to route event via endpoint: org.mule.module.cxf.CxfOutboundMessageProcessor. Message payload is of type: String (org.mule.api.transport.DispatchException)
org.mule.module.cxf.CxfOutboundMessageProcessor:150 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to service.VinculaResponse
at ec.gob.presidencia.tecnologia.pic.vincula.service.jaxws_asm.VinculaServicioIngresoResponse_WrapperTypeHelper1.createWrapperObject(Unknown Source)
at org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor.handleMessage(WrapperClassOutInterceptor.java:100)
... 97 more
This exception can not understand it, since the payload into a string before invoking the service (flow-ref). Could give me an idea to identify where this point at correcting?
Thanks.
Could be a duplicate of this? Mule method cannot be cast to string
You might also want to consider using proxying if your purpose is to map inbound SOAP calls to outbound SOAP calls: http://www.mulesoft.org/documentation/display/current/Proxying+Web+Services+with+CXF