Try OpenEdge Now
skip to main content
Messaging and ESB
Messaging Examples : Gateway sample application : Application files
 

Application files

The sample application manages a set of customer records loaded from the sports.customer table. For each country, there is one instance of the application that manages the subset of customers from that country. The country is specified as an application startup parameter.
The gateway sample application consists of three files:
*appDriver.p — Drives the publish and subscribe gateway example
*JMSgateway.p — Establishes a gateway between local and remote publish and subscribe events
*customers.p — Updates customer records from a specified country while keeping the other records identical to the master copy
The main loop of the application is in appDriver.p:
1. The user specifies the Customer.Cust–num value.
2. The application finds the customer and allows the user to update the record if the Customer.Country field matches the startup country.
3. If the Customer.Country field does not match the startup country, the user can only view the customer record.
4. Several applications, each managing one country, run concurrently. Each application is connected to a JMS server through a local JMS gateway object. The goal is to keep the records identical across the different locations.
5. When an application modifies a customer record, it publishes the new record through an ABL PUBLISH CustUpdate call.
6. The local JMS gateway object subscribes to the CustUpdate event. It packs the published parameters in a JMS MapMessage and publishes it to the JMS CustUpdate topic.
7. The other JMS gateway objects subscribe to the JMS CustUpdate topic. They receive the JMS MapMessage, unpack the parameters, and publish the updated record locally through an ABL PUBLISH CustUpdate call.
8. The application picks up the updated record and updates the local copy.
The procedure appDriver.p drives the publish and subscribe gateway example, as shown:

appDriver.p

/* appDriver.p: Drives the Pub/Sub gateway example. */
DEFINE INPUT PARAMETER cCountry AS CHARACTER NO-UNDO.
DEFINE VARIABLE hCustomers AS HANDLE  NO-UNDO.
DEFINE VARIABLE hGateway   AS HANDLE  NO-UNDO.
DEFINE VARIABLE iCustNum   AS INTEGER NO-UNDO.
/* Initialization */
RUN customers.p PERSISTENT SET hCustomers.
RUN loadCustomers IN hCustomers.
RUN JMSgateway.p PERSISTENT SET hGateway ("-H localhost -S 5162 ").
REPEAT:
  iCustNum = ?.
  UPDATE iCustNum LABEL "cust-num"
    WITH FRAME ff CENTERED TITLE "Find Customer".
  RUN updateCustInteractive IN hCustomers (iCustNum, cCountry).
END.
RUN deleteGateway IN hGateway.
The procedure JMSgateway.p establishes a gateway between local and remote publish and subscribe events, as shown:

JMSgateway.p

/* JMSgateway.p: A gateway between local and remote Pub/Sub events. */
DEFINE INPUT PARAMETER connectionParams AS CHARACTER NO-UNDO.
/* JMS objects */
DEFINE VARIABLE hPubSubSession AS HANDLE NO-UNDO.
DEFINE VARIABLE outMessage     AS HANDLE NO-UNDO.
DEFINE VARIABLE hConsumer      AS HANDLE NO-UNDO.
FUNCTION bufferToRaw RETURNS RAW (bufferH AS HANDLE) FORWARD.
/* Raw Transfer Declarations */
DEFINE TEMP-TABLE ttRaw NO-UNDO
  FIELD rValue AS RAW.
CREATE ttRaw.
/* Initializes the JMS server and subscribes to the CustUpdate topic */
RUN jms/pubsubsession.p PERSISTENT SET hPubSubSession (connectionParams).
RUN setBrokerURL IN hPubSubSession ("localhost:2506").
RUN beginSession IN hPubSubSession.
RUN createMapMessage IN hPubSubSession (OUTPUT outMessage).
RUN createMessageConsumer IN hPubSubSession
  (THIS-PROCEDURE, "handleRemoteEvent", OUTPUT hConsumer).
RUN subscribe IN hPubSubSession
  ("CustUpdate", /* topic name */
   ?,            /* not durable */
   ?,            /* no message selector */
   TRUE,         /* local events */
   hConsumer).
RUN startReceiveMessages IN hPubSubSession.
/* Subscribes to local CustUpdate events */
SUBSCRIBE TO "CustUpdate" ANYWHERE RUN-PROCEDURE "handleLocalEvent".
/* Publish locally a remote message from the CustUpdate topic. */
PROCEDURE handleRemoteEvent:
  DEFINE INPUT PARAMETER hMessage         AS HANDLE NO-UNDO.
  DEFINE INPUT PARAMETER hMessageConsumer AS HANDLE NO-UNDO.
  DEFINE OUTPUT PARAMETER hReply          AS HANDLE NO-UNDO.
  PUBLISH "CustUpdate"
   (DATE (DYNAMIC-FUNCTION('getChar':U IN hMessage, "updateDate")),
    DYNAMIC-FUNCTION('getInt':U IN hMessage, "custNum"),
    DYNAMIC-FUNCTION('getBytesToRaw':U IN hMessage, "rawCust")).
  RUN deleteMessage IN hMessage.
END PROCEDURE.
/* Publish remotely a local CustUpdate event. */
PROCEDURE handleLocalEvent:
  DEFINE INPUT PARAMETER dValue    AS DATE    NO-UNDO.
  DEFINE INPUT PARAMETER hCustomer AS HANDLE  NO-UNDO.
  DEFINE INPUT PARAMETER iCustNum  AS INTEGER NO-UNDO.
  RUN setString IN outMessage ("updateDate", STRING(dValue)).
  RUN setInt IN outMessage ("custNum", iCustNum).
  RUN setBytesFromRaw IN outMessage ("rawCust", bufferToRaw(hCustomer)).
  RUN publish IN hPubSubSession ("CustUpdate", outMessage, ?, ?, ?).
END PROCEDURE.
PROCEDURE deleteGateway:
  RUN deleteMessage IN outMessage.
  RUN deleteSession IN hPubSubSession.
  DELETE OBJECT THIS-PROCEDURE.
END PROCEDURE.
FUNCTION bufferToRaw RETURNS RAW (hBuffer AS HANDLE):
  /* Raw transfer variables */
  DEFINE VARIABLE rawBuf  AS HANDLE NO-UNDO.
  DEFINE VARIABLE rawCust AS HANDLE NO-UNDO.
  ASSIGN
    rawBuf  = BUFFER ttRaw:HANDLE
    rawCust = rawbuf:BUFFER-FIELD(1).
  hBuffer:RAW-TRANSFER(TRUE, rawCust).
  RETURN rawCust:BUFFER-VALUE.
END FUNCTION.
The procedure cusatomers.p updates customer records from a specified country while keeping the other records identical to the master copy, as shown:

customers.p

/* customers.p: Manages customer records of a specified country and keeps the
   other records identical to the master copy. */
DEFINE VARIABLE hTTCust AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO.
DEFINE TEMP-TABLE ttCustomer LIKE customer.
DEFINE BUFFER custtUpd FOR ttCustomer.
/* Getting a handle to a dynamic buffer. */
hTTCust = TEMP-TABLE ttCustomer:HANDLE.
hBuffer = hTTCust:DEFAULT-BUFFER-HANDLE.
/* Subscribes to CustUpdate events. */
SUBSCRIBE TO "CustUpdate" ANYWHERE RUN-PROCEDURE "updateCustFromRaw".
PROCEDURE loadCustomers:
  FOR EACH customer NO-LOCK:
    CREATE custt.
    BUFFER-COPY customer TO ttCustomer.
  END.
END PROCEDURE.
/* Updates a customer from the "correct" country, displays customers from
   other countries. */
PROCEDURE updateCustInteractive.
  DEFINE INPUT PARAMETER custNum     AS INTEGER   NO-UNDO.
  DEFINE INPUT PARAMETER custCountry AS CHARACTER NO-UNDO.
  FIND ttCustomer WHERE ttCustomer.custnum = custNum.
  IF ttCustomer.country = custCountry THEN DO:
    UPDATE ttCustomer WITH 2 COL.
    PUBLISH "CustUpdate" (TODAY, custNum, hBuffer).
  END.
  ELSE
    DISPLAY ttCustomer WITH 2 COL.
END.
/* Updates a customer record from a RAW value. */
PROCEDURE updateCustFromRaw:
  DEFINE INPUT PARAMETER dValue  AS DATE    NO-UNDO.
  DEFINE INPUT PARAMETER custNum AS INTEGER NO-UNDO.
  DEFINE INPUT PARAMETER rawCust AS RAW     NO-UNDO.
  FIND custtUpd WHERE custtUpd.custnum = custNum.
  RAW-TRANSFER rawCust TO custtUpd.
  MESSAGE custNum VIEW-AS ALERT-BOX TITLE "customer updated".
END PROCEDURE.