Invoke Component in message Enricher and how to define the target value for Message Enricher - mule

I am practicing on salesforce to mulesoft connection. I am trying to query the account from salesforce, do some logic using Invoke Component and update the Account name in Salesforce. Please find the XML code below. I get the following error when i invoke..
Execution of the expression "Variable:Fname=__object_for_enrichment" failed. (org.mule.api.expression.ExpressionRuntimeException).
XML:
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8092" doc:name="HTTP Listener Configuration"/>
<sfdc:config name="Salesforce__Basic_Authentication" username="username" password="*******" securityToken="Token" doc:name="Salesforce: Basic Authentication" url="https://login.salesforce.com/services/Soap/u/38.0">
<reconnect-forever/>
</sfdc:config>
<spring:beans>
<spring:bean id="Bean" name="UpdateAcc" class="com.pack.salesforceconnect.SFJava"/>
</spring:beans>
<flow name="salesforceconnectFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/salesforce" doc:name="HTTP"/>
<sfdc:query-single config-ref="Salesforce__Basic_Authentication" query="dsql:SELECT Id,Name,ShippingCity FROM Account ORDER BY Name DESC" doc:name="Salesforce"/>
<dw:transform-message doc:name="Transform Message">
<dw:input-payload doc:sample="sample_data\Account.dwl"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
Id: payload.Id,
Name: payload.Name,
ShippingCity: payload.ShippingCity
}]]></dw:set-payload>
</dw:transform-message>
<enricher source="#[payload.Name]" target="#[Variable:Fname]" doc:name="Message Enricher">
<invoke name="Invoke" object-ref="UpdateAcc" method="ChangeSCity" methodArguments="#[payload.Name]" metadata:id="id"/>
</enricher>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
[{
Id: payload.Id,
Name: variable:FName,
ShippingCity: payload.ShippingCity
}]]]></dw:set-payload>
</dw:transform-message>
<set-payload value="#[payload]" doc:name="Set Payload"/>
</flow>
</mule>
Class:
package com.pack.salesforceconnect;
public class SFJava {
public String ChangeSCity(String Fname){
//String ShippingCity;
System.out.print("Account Name received : "+Fname);
if (Fname == null){
Fname = "New Account";
}else{
Fname = "Washington Industries Inc.,";
}
System.out.print("Account Name: "+Fname);
return Fname;
}
}

Syntax wrong .. it would be target="#[variable:Fname]" instead of target="#[Variable:Fname]"
Or simply you can use target="#[flowVars.Fname]"

Related

Add one more element to the object array inside for each loop in mule 3

I have Input as below
[{Name=ABC, ID=123},{Name=XYZ, ID=345}]
I would iterate over this collection in a for-each loop and add one more element Age to each object.
My expected output would be like
[{Name=ABC, ID=123, Age=23},{Name=XYZ, ID=345, Age=24}]
Any help would be highly appreciated. Thanks in advance.
HTH..
%dw 2.0
output application/json
var inp = [
{
"Name":"ABC",
"ID":"123"
},
{
"Name":"XYZ",
"ID":"345"
}
]
---
inp map {
($),
age: (23 + ($$)) // or your logic to derive age
}
It was not possible with DW as because payload inside for-each was modified. So I tried using Expression component. Below is my configuration XML.
<flow name="add-one-more-element-to-the-original-payload">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="30" timeUnit="SECONDS"/>
<logger message="Pooling Started" level="INFO" doc:name="Log"/>
</poll>
<dw:transform-message doc:name="Transform Payload">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
%var collection = [{"Name":"ABC","ID":123},{"Name":"XYZ","ID":345}]
---
collection]]></dw:set-payload>
</dw:transform-message>
<set-variable variableName="outputList" value="#[new java.util.ArrayList()]"
doc:name="Set Variable"/>
<foreach doc:name="For Each" collection="#[payload]">
<dw:transform-message doc:name="CurrentPayload">
<dw:set-variable variableName="currentPayload"><![CDATA[%dw 1.0
%output application/java
---
payload]]></dw:set-variable>
</dw:transform-message>
<flow-ref name="get-age-subflow" doc:name="Get Age"/>
<expression-component doc:name="Expression"><!
[CDATA[flowVars.currentPayload.Age=payload.Age;]]></expression-component>
<expression-transformer expression="#
[flowVars.outputList.add(flowVars.currentPayload)]" doc:name="Expression"/>
</foreach>
<logger message="#[flowVars.outputList]" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="get-age-subflow">
<dw:transform-message doc:name="Transform Age">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
Age:24
}]]></dw:set-payload>
</dw:transform-message>
</sub-flow>

How to handle if else nested statment in dataweave in mulesoft

OptIn: "Yes" when payload.country==true and payload.state==false otherwise "No" when payload.country==false and payload.state==true otherwise "NOT VALID" when payload.country==false and payload.state==false otherwise ""
This can be achieve through following example :-
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="DataweaveFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/poc" doc:name="HTTP"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[ %dw 1.0
%input payload application/json
%output application/json
---
{ value1: "Yes" } when payload.country==true and payload.state==false
otherwise (
{ value1: "No" } when payload.country==false and payload.state==true
otherwise (
{ value1: "NOT VALID" } when payload.country==false and payload.state==false
otherwise "your value"
))]]></dw:set-payload>
</dw:transform-message>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger" />
</flow>
Where I tested this with following input :-
case 1:-
{
"country":true,
"state":false
}
case 2:-
{
"country":false,
"state":true
}
case 3:-
{
"country":false,
"state":false
}
case 4:-
{
"country":true,
"state":"default value"
}

How to retrieve statusCode from ApiKit mapping in Mule

We want to process all of the exceptions we catch with the same process in our exception strategy. It is the one generated by apikit. We first send a lot with a custom component and then we generate json response. In the response with DataWeave we want to set the same statusCode. However, the statusCode do not seem to be a variable that is retrievable. Am I correct, or there is a good way to retrieve it?
<apikit:mapping-exception-strategy xmlns:apikit="http://www.mulesoft.org/schema/mule/apikit" name="svc0031_hotel-apiKitGlobalExceptionMapping">
<apikit:mapping statusCode="504">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
<apikit:mapping statusCode="404">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
</apikit:mapping-exception-strategy>
<sub-flow name="svc0031_manageErrors">
<set-payload value="#[groovy:message.exceptionPayload.rootException.message]" doc:name="Set BIP Payload"/>
<custom-transformer class="se.zystems.baseline.BaselineLogging" doc:name="Log BIP Outgoing">
<spring:property name="Level" value="ERROR"/>
<spring:property name="ObjectId" value="CatchErrors"/>
<spring:property name="TransactionStatus" value="failed"/>
</custom-transformer>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : 400,
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
<logger level="INFO" doc:name="Logger"/>
</sub-flow>
Good,
If you create a variable with the http.status then you can use it in the mapper:
<flow name="test">
<set-variable variableName="httpStatus" value="#[message.inboundProperties['http.status']" doc:name="Variable"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : flowVars.httpStatus,
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
</flow>
I found out where the statusCode value is stored thanks to the answer by Jesús Pablo Fernández
He was almost right in his answer, however, the statusCode is stored not in message.inboundProperties['http.status'], but in message.outboundProperties['http.status']. No need to even extract a variable, one can just access it in data transformer directly like this:
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : outboundProperties['http.status'],
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
Status codes defined in the APIKitExceptionStrategy will be those sent back in the response header as http.status given the corresponding exception to be raised.
For instance,
<apikit:mapping statusCode="504">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
means that when a org.mule.api.transformer.TransformerMessagingException exception is thrown and caught by this exception block, then a 504 status code is sent back as a response header.
If you want to bypass the statusCode attribute in the APIKit exception block, you should have another exceptionStrategy block to catch your desired exception, and then you could set your status code like that
<set-property name="http.status" value="<the_desired_status, e.g. 401>" />
Hope it helps.
/Tony
Good Stanislav Ivanov,
I have a flow implemented with the APIKit, which is the code that I attach and whether there is property in the inboundProperties http.status, review it because if it should contain the value, if you do not have your flow may modify the value in a previous step.
I pointed him to directly access the outboundProperties in the mapper, I was not aware, thank you very much.

aperak edi file in mule dataweaver

I am trying to create aperak-edifact file from mule data weaver component.
Here is my piece of code
<edifact-edi:config name="EDIFACT_EDI" delimiterUsage="USE_SPECIFIED_FOR_WRITES" doc:name="EDIFACT EDI" interchangeIdPartner="YYYY" interchangeIdSelf="XXXX">
<edifact-edi:schemas>
<edifact-edi:schema>/edifact/d98b/APERAK.esl</edifact-edi:schema>
</edifact-edi:schemas>
</edifact-edi:config>
<flow name="new1Flow">
<file:inbound-endpoint path="C:\Users\Desktop" responseTimeout="10000" doc:name="File">
<file:filename-regex-filter pattern="aperak.xml" caseSensitive="true"/>
</file:inbound-endpoint>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
Messages: {
D98B: {
APERAK: [{
Interchange: {
UNB0201: "XXX",
UNB0301: "YYYY"
},
MessageHeader: {
UNH01: "1"
},
Heading: {
"0020_BGM": {
BGM0101: "7"
}
}
}]
}
}
}]]></dw:set-payload>
</dw:transform-message>
<edifact-edi:write config-ref="EDIFACT_EDI" doc:name="EDIFACT EDI"/>
<file:outbound-endpoint path="C:\Users\Desktop" outputPattern="out.json" responseTimeout="10000" doc:name="File"/>
</flow>
Output
UNB+UNOB:4+XXX+YYY+05042016:0948+1'UNH+2+APERAK:D:98B:UN'BGM+7'UNT+3+2'UNZ+1+1'
But the output created is all in one line where I want it to be appeared line by line. So how can I introduce new line for edifact
Any help is appreciated
Expected Output
UNB+UNOB:4+XXX+YYY+05042016:0948+1'
UNH+2+APERAK:D:98B:UN'
BGM+7'
UNT+3+2'UNZ+1+1'
Set the lineEnding configuration attribute of edifact-edi:config to output a CRLF.

Generating random numbers in mule dataweave

I have to concatenate randomly generated number with the field from request in dataweave.
NUMBR: "AA" ++ $.Load.Reference.*Reference ++ RandomNumber
How to achieve this in Mule Dataweave
Not sure what you can do in Datawevae to do this, but you can you set a Random number in a flowVariable and invoke it from your Dataweave script like so:
<set-variable variableName="random"
value="#[new java.util.Random().nextInt(100)]" doc:name="Variable" />
<dw:transform-message doc:name="Transform Message">
<dw:input-variable doc:sample="unknown.dwl" variableName="random" />
<dw:set-payload>
<![CDATA[%dw 1.0
%output application/dw
---
{
"data": ("22" as :number + flowVars.random)
} ]]>
</dw:set-payload>
</dw:transform-message>
You can also use Expression Component to assign it to Payload or variables and then concatenate
<flow name="random-numbersFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/random" allowedMethods="GET" doc:name="HTTP"/>
<expression-component doc:name="Expression"><![CDATA[payload = new java.util.Random().nextInt(100)]]></expression-component>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
data: payload
}]]></dw:set-payload>
</dw:transform-message>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>
You can't do this in pure DataWeave but you could use two methods to generate the number elsewhere in the application:
You could call a global MEL function from DataWeave: https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-reference-documentation#global-mel-functions
You could call a flow that returns the value: https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-reference-documentation#expressions-that-call-external-flows
Just set a random value generated by Java into a Flow Variable
<set-variable variableName="Random_Variable" value="#[java.util.Random().nextInt(10)]" doc:name="Random Variable"/>
Then Use that Flow Variable in your Dataweave Transform.
<dw:transform-message doc:name="Transform Message" metadata:id="8098b24c-30c1-4e9e-a3ce-9e8aaaec7bd1">
<dw:input-variable mimeType="application/java" variableName="Random_Variable"/>
<dw:set-payload><![CDATA[%dw 2.0
%output application/json
---
{
NUMBR: "AA" ++ $.Load.Reference.*Reference ++ flowVars.Random_Variable
}]]></dw:set-payload>
</dw:transform-message>
In Mule 4 Dataweave 2 function random()
Returns a pseudo-random number greater than or equal to 0.0 and less than 1.0
MULE 4 DOC:
https://docs.mulesoft.com/dataweave/2.3/dw-core-functions-random
Example:
%dw 2.0
output application/json
{ price: random() * 1000 }