For this use case the AS/400 process needs to convert transaction amount from one currency to another using real time exchange rate web service.

AS/400 demo code

  1. Create the request and response data queues

  2. Create display file DEMO01D and a demo RPG program to implement the following screen:

A                                      DSPSIZ(24 80 *DS3)
A          R MAIN
A                                      CF03(03 'EXIT')
A                                 22  2'F3=Exit'
A                                      COLOR(BLU)
A                                  1 70DATE
A                                      EDTCDE(Y)
A                                  2 70TIME
A                                  1  3USER
A                                  2  3SYSNAME
A                                  2 27'AS/400 to Mule Demo'
A                                      COLOR(WHT)
A                                  9  4'From currency code:'
A                                 10  4'To currency code:'
A                                  8  4'Amount to convert:'
A                                 12  4'Mule response:'
A                                 13  4'Converted Amount:'
A            AMOUNT        11Y 2B  8 26EDTWRD('         .  ')
A                                      COLOR(WHT)
A            FROMCCY        3A  B  9 26COLOR(WHT)
A            TOCCY          3A  B 10 26COLOR(WHT)
A            MULERESP      50   O 12 26
A            TOAMOUNT      11Y 2O 13 26EDTWRD('         .  ')
  1. Create RPGLE maintenance program DEMO01R that

    1. Takes user input (from and to currency codes and amount to trans)

    2. Generates random transaction ID

    3. Places from and to currency codes into request data queue with key = transaction ID

    4. Waits for response data queue message with key = transaction ID

    5. Calculates amount based on received exchange rate, or displays error message

fdemo01d   cf   e             workstn

d sndDtaQ         pr                  ExtPgm( 'QSNDDTAQ' )
d  DQName                       10    Const
d  DQLibl                       10    Const
d  DQLength                      5  0 Const
d  DQData                      255    Const
d  DQKeyLength                   3p 0 options(*nopass) const
d  DQKey                        20    options(*nopass) const

d rcvDtaQ         pr                  ExtPgm('QRCVDTAQ')
d   Dtaqnam                     10a   const
d   Dtaqlib                     10a   const
d   Dtaqlen                      5p 0
d   Data                       255
d   WaitTime                     5p 0 const
d   Keyorder                     2a   options(*nopass) const
d   Keylen                       3p 0 options(*nopass) const
d   Key                         20    options(*nopass) const
d   Senderlen                    3p 0 options(*nopass) const
d   Sender                       1    options(*nopass) const
 * Prototype to C "rand" function
d Rand            PR            10I 0 ExtProc('rand')
 * Prototype to C "srand" function
d SRand           PR                  ExtProc('srand')
d   iSeed                       10U 0 VALUE
 * Prototype to C "clock" function
d GetTime         PR            10I 0 ExtProc('clock')
 * Prototype to C "atof" function
d atof            pr             8f   extproc('atof')
d   string                        *   Value Options(*String)
 * Rand variables
d RandomNumber    S             10I 0
d ClockTicks      S             10I 0
d SeedValue       S             10U 0
 * constants for this sample, replace with soft-coded parms
d c#reqDtaQ       s             10    inz('DEMO01REQ')
d c#reqDtaQLib    s             10    inz('MULE400DEV')
d c#resDtaQ       s             10    inz('DEMO01RES')
d c#resDtaQLib    s             10    inz('MULE400DEV')
d c#waitsec       s              5p 0 inz(15)
d msgOut          s            255
d msgIn           s            255
d msgKey          s             20
d msgInLen        s              5p 0

   exfmt main;
   dow *in03 = *off;
     exsr processSR;
     exfmt main;
   enddo; // *in03 = off
   *inlr = *on;

   begsr processsr;

     if (fromccy <> *blanks and toccy <> *blanks
       and amount <> 0);
       // Generate trans ID
       ClockTicks = GetTime;
       SeedValue = ClockTicks;
       RandomNumber = Rand();
       msgKey = %char(randomNumber);
       msgOut = fromccy + ',' + toccy;
       snddtaq (c#reqDtaQ : c#reqDtaQLib : %size(msgOut) : msgOut :
            %size(msgKey ) : msgKey );
       // Wait for the response from web service
       msgIn = *blanks;
       toamount = 0;
       rcvdtaq (c#resDtaQ: c#resDtaQLib: msgInLen : msgIn : c#waitsec :
            'EQ': %size(msgKey) : msgKey : 0 : ' ');
       if  msgInLen > 0;
         muleresp   = %subst(msgIn:1:50);
         if %subst(muleresp:1:9) = 'Status=OK';
             toamount = amount * atof(%subst(msgIn:11));
         muleresp = 'No response from Mule';
       endif; // msgInLen > 0
     endif; // fromccy <> *blanks ...


Mule demo code

  1. Create Mule application that:

    1. listens to AS/400 data queue for requests

    2. calls external currency exchange rate web service

    3. sends the call status and exchange rate back to AS/400 response data queue

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:dw="" xmlns:metadata="" xmlns:json=""
	xmlns:as400="" xmlns:ws=""
	xmlns="" xmlns:doc=""
	xmlns:spring="" version="EE-3.7.0"
	<http:listener-config name="HTTP_Listener_Configuration"
		host="" port="8081" doc:name="HTTP Listener Configuration" />
	<ws:consumer-config name="Web_Service_Consumer"
		service="CurrencyConvertor" port="CurrencyConvertorSoap"
		doc:name="Web Service Consumer" />
	<as400:config name="AS400__Configuration_type_strategy"
		endpoint="${endpoint}" userid="${userid}" password="${password}"
		doc:name="AS400: Configuration type strategy" libraryList="${libl}">
        <as400:connection-pooling-profile initialisationPolicy="INITIALISE_ALL" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
   <flow name="demo04-as400-calls-mule-dataweaveFlow">
        <as400:read-data-queue config-ref="AS400__Configuration_type_strategy" dtaq="${req.dtaq}" library="${library}" dtaqKey="''" dtaqKeySearchType="GREATER_THAN_OR_EQUAL" doc:name="AS400 (Streaming)"/>
			message="Request #[payload], Key=#[message.inboundProperties.'as400.dataqueue.key']"
			level="INFO" doc:name="Logger" />
		<set-variable variableName="key"
			value="#[message.inboundProperties.'as400.dataqueue.key']" doc:name="Variable" />
		<expression-transformer expression="#[message.payload.split(',')]"
			doc:name="Expression" mimeType="application/csv"/>
        <set-payload value="#['{&quot;FromCurrency&quot;:' + '&quot;'+payload[0] + '&quot;,&quot;ToCurrency&quot;:' + '&quot;'+payload[1]+'&quot;}']" doc:name="Set Payload"/>
        <json:object-to-json-transformer metadata:id="702c4706-b957-4295-9b0c-ee3b8ae10f57" doc:name="Object to JSON"/>
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 http://www.webserviceX.NET/
	ns0#ConversionRate: {
		ns0#FromCurrency: payload.FromCurrency,
		ns0#ToCurrency: payload.ToCurrency
		<ws:consumer config-ref="Web_Service_Consumer" doc:name="Web Service Consumer"
			operation="ConversionRate" />
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/java
%namespace ns0 http://www.webserviceX.NET/
        <logger message="Response: Status=OK;#[payload]" level="INFO" metadata:id="fb354e1f-2d50-42b0-8140-9ca3b374bd6e" doc:name="Logger"/>
		<as400:write-data-queue config-ref="AS400__Configuration_type_strategy"
			dtaq="${res.dtaq}" library="${library}" dqEntry="Status=OK;#[payload]"
			doc:name="AS400" dtaqKey="#[flowVars['key']]" />
		<catch-exception-strategy doc:name="Catch Exception Strategy">
			<logger message="Status=FAILED;#[exception]" level="ERROR"
				doc:name="Logger" />
			<as400:write-data-queue config-ref="AS400__Configuration_type_strategy"
				dtaq="${res.dtaq}" library="${library}"
				dqEntry="Status=FAILED;Errors while executing the flow"
				doc:name="AS400" dtaqKey="#[flowVars['key']]" />