Mule

How to use our own response xml in transform message component.

In this below example,We want to create response without namespaces

1. Drag TransferMessage component.
2. Define metadata
3. Popup will be displayed as per screenshot


4. Select the input request you want.
5. For selection of customized output response -->click on +Add button



6. Select define metadata --> Create usertype as output response(Anything you name it) as per below screenshot



7. Select type as XML and example as customized response xml (Choose location of custom xml)
7. click on select button after customxml is selected

8.Here is sample custom response xml  in src/test/resources

<GetDeliverySchedule xmlns:tem="http://tempuri.org/">  
  <request>
    <DeliveryType>P</DeliveryType>  
    <EndDate>2017-11-07T04:00:00.000+00:00</EndDate>  
    <Region_StoreNo>970</Region_StoreNo>  
    <Region_zip>33647</Region_zip>  
    <StartDate>2017-08-09T00:00:00.000-04:00</StartDate>  
    <TransactionID>o1137420445|x9tD3fRHvbQ+CmQp74DcNPZN</TransactionID> 
  </request> 

</GetDeliverySchedule>

Here is how it shows in Configuration XML format


 <dw:transform-message doc:name="Transform Message" metadata:id="0df9516d-df4d-486a-97db-7cf98d1207fb">
            <dw:input-payload mimeType="application/xml"/>
            <dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 http://tempuri.org/
%namespace ns1 http://schemas.datacontract.org/2004/07/DotCom_Delivery
---
{
GetDeliverySchedule: {
request: {
DeliveryType: payload.ns0#GetDeliverySchedule.ns0#request.ns1#DeliveryType,
EndDate: payload.ns0#GetDeliverySchedule.ns0#request.ns1#EndDate,
Region_StoreNo: payload.ns0#GetDeliverySchedule.ns0#request.ns1#Region_StoreNo as :number,
Region_zip: payload.ns0#GetDeliverySchedule.ns0#request.ns1#Region_zip as :number,
StartDate: payload.ns0#GetDeliverySchedule.ns0#request.ns1#StartDate,
TransactionID: payload.ns0#GetDeliverySchedule.ns0#request.ns1#TransactionID
}
}
}]]></dw:set-payload>

        </dw:transform-message>


Set payload in temp variable and convert payload xml to Object


 <set-variable variableName="payloadVar" value="#[payload]" doc:name="Variable"/>
        <json:xml-to-json-transformer doc:name="XML to JSON"/>

        <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>

Create Flow var from objects stored in hashMap

<set-variable variableName="startDate" value="#[payload.GetDeliverySchedule.request.StartDate]" doc:name="setStartDateVariable"/>
        <set-variable variableName="endDate" value="#[payload.GetDeliverySchedule.request.EndDate]" doc:name="setEndDateVar"/>
        <set-variable variableName="transactionId" value="#[payload.GetDeliverySchedule.request.TransactionID]" doc:name="setTransactionId"/>
        <set-variable variableName="zipcode" value="#[payload.GetDeliverySchedule.request.Region_zip]" doc:name="setZipCode"/>


Create custom java component for business logic

  <custom-transformer class="com.deliveryservice.CustomOutFaultInterceptor" doc:name="FaultInterceptor"/>

Sample code in java for custom component

public class CustomOutFaultInterceptor extends AbstractMessageTransformer {
@Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
//Message consist of all flow var created before this component invokes.
if(message.getPayload() != null) {
System.out.println("startDate" +message.getInvocationProperty("startDate"));
System.out.println("endDate" +message.getInvocationProperty("endDate"));
System.out.println("transactionId" +message.getInvocationProperty("transactionId"));
System.out.println("zipcode" +message.getInvocationProperty("zipcode"));
System.out.println("message.getPayload()" +message.getPayload());
try{
HashMap obj = ( HashMap)(message.getPayload());
String startDate = message.getInvocationProperty("startDate");
String endDate = message.getInvocationProperty("endDate");
String transactionId = message.getInvocationProperty("transactionId");
String zipcode = message.getInvocationProperty("zipcode");

Convert final result in readable format using OOB  XmlPrettyPrinter java component


<custom-transformer class="org.mule.module.xml.transformer.XmlPrettyPrinter" doc:name="Java"/>

Best way to get data from xml payload is to convert XML to JSON to Object(HashMap)


<set-variable variableName="payloadVar" value="#[payload]" doc:name="Variable"/>
        <json:xml-to-json-transformer doc:name="XML to JSON"/>
        <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>

Below line is to create flowVars from payload hashmap object for further use in DB query

        <set-variable variableName="merchantReferenceCode" value="#[payload.'ns1:getProfileAuth'.arg0.merchantReferenceCode]" doc:name="Variable"/>

Below line is to pass flowVar in select DB query
  <db:select config-ref="Generic_Database_Configuration" doc:name="Database">
  <db:parameterized-query><![CDATA[select * from mock_auth_tracker where ORDER_ID=#[flowVars.merchantReferenceCode]]]></db:parameterized-query>

  </db:select>

Please find below screenshot



Below line is to retrieve resultset after select query execution. Retrieving first record data for column CARD_NUMBER


<set-variable variableName="cardNumber" value="#[payload[0].CARD_NUMBER]" doc:name="Variable"/>

Belowline is to set payload for payload which exists before query execution. This was stored in temp var(payloadVar)

<set-payload value="#[flowVars.payloadVar]" doc:name="Set Payload"/>

Setting the payload data in flow var's which are being used in DB query execution.


  <set-variable variableName="cardNumber" value="#[payload.card_number]" doc:name="Variable"/>
  <set-variable variableName="merchantReferenceCode" value="#[payload.merchantReferenceCode]" doc:name="Variable"/>

  <set-variable variableName="payloadVar" value="#[payload]" doc:name="Variable"/>

Delete and insert query execution

<db:delete config-ref="Generic_Database_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[delete from mock_auth_tracker where ORDER_ID=#[flowVars.merchantReferenceCode]]]></db:parameterized-query>
</db:delete>
<db:insert config-ref="Generic_Database_Configuration" doc:name="Database" >
<db:parameterized-query><![CDATA[insert into mock_auth_tracker values(#[flowVars.merchantReferenceCode],#[flowVars.cardNumber])]]></db:parameterized-query>
</db:insert>

Set the payalod which was created in temp var(payloadVar) before query execution

<set-payload value="#[flowVars.payloadVar]" doc:name="Set Payload"/>

Below line is to parse jsp template
Jsp Name: handleCybersourceSubmit.template

 <parse-template location="handleSubmit.template" doc:name="Parse Template"/>

Here is JSP:

<form novalidate="novalidate" role="form" action="#[payload['referer']]" accept-charset="UTF-8" method="post" id="id">

<input type="hidden" name="authenticity_token" value="EKmKb1gzCJxTY3Yoost+kVqGLuY4aF5lG25hlLV7NwnkObt1zJfARqxm4uTJUDv91FxJ6VELQlzWqKd1Lc7HUA==" />
<input type="hidden" name="session_uuid" id="session_uuid" value="fc90471bef284e8c9c0a9ec7ceec0dca" />

<input type="hidden" name="decision" id="decision" value="ACCEPT" />
<input type="hidden" name="reason_code" id="decision" value="100" />
<input name="merchantReferenceCode" id="merchantReferenceCode" type="hidden" value="#[payload['merchantReferenceCode']]"/>
<input name="city"  id="city" type="hidden" value="#[payload['city']]"/>
<input name="card_type"  id="card_type" type="hidden" value="#[payload['card_type']]"/>

</form>
For actual making webservice SOAP call.

Web_Service_Consumer component is being used for making real SOAP call 


 <ws:consumer-config name="Web_Service_Consumer" service="WebService" port="SourceWSPort" serviceAddress="http://10.100.100.100:8180/WSSource-WSSourceEJB/WSSource" wsdlLocation="http://10.100.100.100:8180/WSSource-WSSourceEJB/WSSource?wsdl" doc:name="Web Service Consumer"/>



Below screenshot is for Transfer Message component. Response got manipulated .
For EX: consumerLocalTime and authorizedDateTime updated as current time




Sample code Transfer Message component



<dw:transform-message doc:name="Transform Message" metadata:id="03540dee-4a13-40c5-8537-5547df4aeef9">
            <dw:input-payload mimeType="application/xml"/>
            <dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 http://webservice.cybersource.rtg/
---
{
ns0#getProfileAuthResponse: {
return: {
afsReply: {
afsFactorCode: "Z",
afsResult: "0",
consumerLocalTime: now as :string {format: "HH:mm:ss"},
hostSeverity: '1',
reasonCode: '100',
scoreModelUsed: "default"
},
ccAuthReply: {
amount: "866.90",
authorizationCode: "888888",
authorizedDateTime: now as :string {format: "yyyy-MM-dd HH:mm:ss"},
avsCode: "X",
avsCodeRaw: "I1",
processorResponse: "100",
reconciliationId: "75063590E5LGAMP6"
},
decision: "ACCEPT",
decisionReply: {
activeProfileReply: null,
casePriority: '3'
},
merchantReferenceCode: payload.ns0#getProfileAuth.arg0.merchantReferenceCode,
purchaseTotals: {
currency: "USD"
},

}

}
}]]></dw:set-payload>

        </dw:transform-message>

Below line is to pass flowVars to JSP and Parse JSP


<set-variable variableName="referelVar" value="${refererUrl}" doc:name="Variable"/>
<set-variable variableName="cancelVar" value="${cancelUrl}" doc:name="Variable"/>
<parse-template location="sourceForm.template" doc:name="Parse Template"/>

SourceForm.template :

<form novalidate="novalidate" autocomplete="off" role="form" action="/checkout_update" accept-charset="UTF-8" method="post" id="source">

<input name="merchantReferenceCode" id="merchantReferenceCode" type="hidden" value="#[payload['reference_number']]"/>
<input name="city"  id="city" type="hidden" value="#[payload['bill_to_address_city']]"/>
<input name="firstName"  id="firstName" type="hidden" value="#[payload['bill_to_forename']]"/>
<input name="lastName"  id="lastName" type="hidden" value="#[payload['bill_to_surname']]"/>
<input name="phoneNo"  id="phoneNo" type="hidden" value="#[payload['bill_to_phone']]"/>
<input name="currency"  id="currency" type="hidden" value="#[payload['currency']]"/>
<input name="rtgReferer"  id="rtgReferer" type="hidden" value="#[flowVars.referelVar]"/>

<input class="cButton" type="button" name ="Cancel" value="Cancel" onclick="submitForm('#[flowVars.cancelVar]')"/>

 <input type="submit" name="commit" value="Finish" class="button"/>
</form>
<script>
    function submitForm(action)
    {
        document.getElementById('source').action = action;
        document.getElementById('source').submit();
    }
</script>

Below screenshot for CXF component




HTTP connector for EndPoint URL





When String operations are performed in any component,Make sure payload object is in Object format . If payload is in other format like XML convert to Object format  using org.mule.module.xml.transformer.XmlPrettyPrinter and perform String operations.




Comments

Popular posts from this blog

how to generate classes from swagger

How to create new user/account in BCC