How's Mule <object-to-string-transformer> different than message.getPatyloadAsString() - mule

I've a soap service flow which gets inbound request through <cxf:proxy-service>. I have a set payload right after it to get payload as String.
Here is my flow:
<flow name="soapService">
<http:inbound-endpoint address="${service.address}" exchange-pattern="request-response">
<cxf:proxy-service wsdlLocation="classpath:service.wsdl" namespace="http://pennmutual.com/services/mvi" service="MVIService" enableMuleSoapHeaders="false"/>
</http:inbound-endpoint>
<set-payload value="#[message.payloadAs(java.lang.String)]"/>
.
.
.
</flow>
<set-payload value="#[message.payloadAs(java.lang.String)]"/> works but if I replace it with <object-to-string-transformer>, it doesn't work.
How are these 2 inherently different?
UPDATE:
On replacing <set-payload value="#[message.payloadAs(java.lang.String)]"/> with <object-to-string-transformer> in my above flow, #[payload] gives com.ctc.wstx.sr.ValidatingStreamReader#429eb61a instead of the atcual XML

message.payloadAs(java.lang.String) relies on Mule's auto-transformation framework: I supposed it picks <xml:dom-to-xml-transformer> instead of <object-to-string-transformer> as the most appropriate transformer.

Related

Mule-Unable to access Session Variable value in another flow

I need to retrieve the value set in session variable in flow1 to flow2. The code I've written looks like this :
<flow name="demo1Flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="demo" doc:name="HTTP"/>
<set-session-variable variableName="name" value="balwant" doc:name="Session Variable"/>
<logger message="Inside demo1 #[sessionVars.name]" level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/test" method="GET" doc:name="HTTP"/>
</flow>
<flow name="demoFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<logger message="Inside demo flow #[sessionVars['name']]" level="INFO" doc:name="Logger"/>
</flow>
With the above code I'm not able to get the value from session variable which was set in demo1Flow to demoFlow. The output for this flow I'm getting is :
INFO 2017-03-07 12:55:28,455 [[demo].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Inside demo1 balwant
INFO 2017-03-07 12:55:28,536 [[demo].HTTP_Listener_Configuration.worker.02] org.mule.api.processor.LoggerMessageProcessor: Inside demo flow null.
As the documentation says that value in Session variable is accessible across the session in different flows, but here that is not happening :(. Not sure what is the reason.
Referring Session Variable Transformer Reference documentation, the Session Variable persist for the entire message lifecycle, regardless of transport barriers, except for the HTTP Connector which doesn’t propagate them.
They are two independent flows which process messages based on different input paths, although you are calling using http requester from flow1,second has its own scope.
For every flow it's scope begins with its inbound.
As there is no relationship between those two flows, you can't access anything from flow1 in the other. If you want that variable you can set as outbound property then it will become inbound property to the second flow. Otherwise you can set as uri parameters.
Regards,
Mallesh

How to convert org.glassfish.grizzly.utils.BufferInputStream to JSON in Mule?

On my first steps with Mule I'm writing a basic Http Proxy.
Currently I forward the request to the api server and what I'd like to do is reading the payload that I receive from it before responding to the client.
When I try to log it with #[payload] it prints
org.glassfish.grizzly.utils.BufferInputStream#2306df30
How can I print it properly in JSON format?
The full code:
<flow name="proxy">
<http:listener config-ref="http-lc-0.0.0.0-8081" path="![p['proxy.path']]" parseRequest="false"/>
<http:request config-ref="http-request-config" method="#[message.inboundProperties['http.method']]"
path="#[message.inboundProperties['http.request.path'].substring(message.inboundProperties['http.listener.path'].length()-2)]" parseResponse="false">
<http:request-builder>
<http:query-params expression="#[message.inboundProperties.'http.query.params']"/>
</http:request-builder>
<http:success-status-code-validator values="0..599" />
</http:request>
<logger doc:name="Logger" level="INFO" message="Payload #[payload]"/>
The payload after HTTP request is generally in stream format, ref:- https://docs.mulesoft.com/mule-user-guide/v/3.7/http-request-connector
There are two ways you can get the payload after http:request
1) <object-to-string-transformer doc:name="Object to String"/> after http:request
or
2) using a logger and use MEL expression <logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
Try #[message.payloadAs(java.lang.String)] which will log the expected output.
Hope this helps.
The http component will send as InputStream,So use byte array to string transformer after http component.If you just want to print you can use #[message.payloadAs(java.lang.String)] but you wanna do any operation just drag and drop a byte array to string transformer
Simplest way is to just use <object-to-string-transformer doc:name="Object to String"/> after http request component and then place a logger with #[payload].
One way to make sure that you get proper JSON response is to set payload as application/json mimetype.
<set-payload value="#[payload]" mimeType="application/json" doc:name="Set Payload"/>
Add this line after the HTTP Request. Just setting the payload value as #[payload] will convert it to json While converting it to string will just print it as string and not make it Json type.

To create multiple records in salesforce using mule salescloud connector

I am trying to upload many records to salesforce via mule using (create bulk) operation.
I created the flow as below
<flow name="bulk_salesFlow1" doc:name="bulk_salesFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<sfdc:create-bulk config-ref="Salesforce12" type="BulkMule__c" doc:name="Salesforce">
<sfdc:objects>
<sfdc:object>
<sfdc:inner-object key="Component__c">Transformer</sfdc:inner-object>
<sfdc:inner-object key="Use__c">Transforms the payload</sfdc:inner-object>
</sfdc:object>
<sfdc:object>
<sfdc:inner-object key="Use__c">Iterator</sfdc:inner-object>
<sfdc:inner-object key="Component__c">ForEach</sfdc:inner-object>
</sfdc:object>
</sfdc:objects>
</sfdc:create-bulk>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
I am getting error "Element: Object is not allowed to be repeated". I would like to know if I'm trying in the right way, if so what is wrong in the above flow.
Thank you in advance
I think this is just a problem with Mule Studio, and you should be able to run your flow if you just ignore the warnings.
If the warnings bother you, you can always use <sfdc:objects ref="#[something]"/> with a list of maps with field names corresponding to your SF object.

put an information in a message mule esb

I have a flow in which I have inserted a flow reference component. The reference component flow will obviously send a message to my first flow with a result "xxx". I want this result to be put in the header of the message sent.
<flow name="CreateAccountFlow1" doc:name="CreateAccountFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" path="bank"/>
<cxf:jaxws-service doc:name="SOAP" serviceClass="com.essai2.AccountService"/>
<component class="com.essai2.AccountRequest" doc:name="Java"/>
<flow-ref name="Projet2Flow1" doc:name="Flow Reference"/>
<component class="com.essai2.AccountResponse" doc:name="Java"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
Flow-references do not "send messages" per se, so it's hard to understand what you're after. It seems you want the result of the execution of the flow-ref to be placed in a message property. If that's the case, you can do:
<set-variable variableName="result" value="#[message.payload]" />
This assumes that the result of the flow-ref is in the message payload and that having the result property in the invocation scope (aka flow variable) is OK for you. With the little information you provided, that's the most I can tell you.

How to log or handle original payload message in Mule

<flow>
<jms:inbound-endpoint queue="InputQueue"/>
<component class="MyComponent"/>
<choice>
<when expression="/Response/Status/Success" evaluator="xpath">
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="SuccessQueue"/>
</when>
<when expression="/Response/Status/Error" evaluator="xpath">
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="ErrorQueue"/>
</when>
<otherwise>
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="ExceptionQueue"/>
</otherwise>
</choice>
</flow>
In this flow, MyComponent returns either success message as a response or error response or exception?
I need to log the original message from InputQueue in LogInputQueue in all the cases. How do I achieve this in my flow?
Did you mean to create a log file? In that case, you have to implement log4j using slf4j and use the line
<logger level="log_level" category="your_category" message="#[message:payload]"/>
where log_level is your desired logging level- "error", "debug", "info" etc...
your_category is your category of log defined in the log4j.properties file (it is optional actually)
and message="#[expression:value]" is your message to be logged given as an expression:scope:key combination. Scope is optional here.
Using log4j or slf4j you can log the payload.
[payload],we have logger component using this log payload in console.
Since, you need to send original message from InputQueue to LogInputQueue in all the cases, as you mentioned, what you need to do is :-
1. Remove <jms:outbound-endpoint queue="LogInputQueue"/> from all the cases in choice block
2. Store the original payload from InputQueue in a variable by placing it just after the JMS inbound endpoint
3. At the end of the flow, after the choice router, set the payload in set payload component from variable you stored the original payload
4. Now put <jms:outbound-endpoint queue="LogInputQueue"/> after your set payload component.
In this way you will able to send the original payload to the LogInputQueue as per your requirement.