|
Topics: |
The IWAYEVT2 sample program (iwayevt2.cobol) is a sample program that tests request/response event handling in the iWay Transaction Adapter for IMS. It sends out a message, prefixed by a 4-byte length, and expects the exact same message as the response.
|
Topics: |
The IWAYEVT2 sample program and related program files are located in the following directory:
<iway_home>\etc\samples\ims\iwayevt2
where:
Is the location on your system where iWay Service Manager is installed.
The following subdirectories are included for the IWAYEVT2 sample program:
|
Reference: |
The cobolfd subdirectory contains the COBOL copybook (IWAYEVT0_IN.CBL) to map the data that is sent from, and returned to, IMS.
The following is the structure of the IWAYEVT0_IN.CBL COBOL copybook:
05 ALPHA01 PIC X(8). 05 INT01 PIC S9(4) BINARY. 05 PACK01 PIC S9(15) PACKED-DECIMAL. 05 ZONE01 PIC 9(4).
|
Reference: |
The java subdirectory contains the message-driven Java Bean (InboundEchoBean.java) that actually performs the echo.
The following is the structure of the Java Bean (InboundEchoBean.java):
/* * Created on Feb 11, 2005 * * Copyright (C) 2003-2004, iWay Software/Information Builders, Inc. * All Rights Reserved. */ package com.iwaysoftware.afjca15.samples; import javax.ejb.EJBException; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Enumeration; import java.util.Iterator; import java.util.Properties; import java.util.logging.*; import javax.naming.*; import javax.resource.cci.MessageListener; import javax.resource.cci.Record; import com.ibi.common.IContext; import com.iwaysoftware.afjca15.IIWAFRecord; import com.iwaysoftware.afjca15.CCIRecordFactory; /** * A simple message-driven bean. The code illustrates the requirements of a * message-driven bean class: * <ul> * <li>It implements the <code>MessageDrivenBean</code> and * <code>CCI MessageListener</code> interfaces. * <li>The class is defined as <code>public</code>. * <li>The class cannot be defined as <code>abstract</code> or * <code>final</code>. * <li>It implements one <code>onMessage</code> method. * <li>It implements one <code>ejbCreate</code> method and one * <code>ejbRemove</code> method. * <li>It contains a public constructor with no arguments. * <li>It must not define the <code>finalize</code> method. * </ul> * * Unlike session and entity beans, message-driven beans do not have the remote
* or local interfaces that define client access. Client components do not
* locate message-driven beans and invoke methods on them. Although
* message-driven beans do not have business methods, they may contain helper
* methods that are invoked internally by the onMessage method.
*
*/
public class InboundEchoBean implements MessageDrivenBean, MessageListener {
static final Logger logger = Logger
.getLogger("com.iwaysoftware.afjca15.samples");
private transient MessageDrivenContext mdc = null;
private Context context;
/**
* Default constructor. Creates a bean.
*/
public InboundEchoBean() {
logger.info("<MDB> In InboundEchoBean.InboundEchoBean()");
}
/**
* Sets the context for the bean.
*
* @param mdc the message-driven-bean context
*/
public void setMessageDrivenContext(MessageDrivenContext mdc) {
logger.info("<MDB> In InboundMessageBean.setMessageDrivenContext()");
this.mdc = mdc;
}
/**
* Creates a bean. Required by EJB spec.
*/
public void ejbCreate() {
logger.info("<MDB> In InboundEchoBean.ejbCreate()");
}
/**
* When the IWAF Channel receives a record, the EJB container invokes the
* <code>onMessage</code> method of the message-driven bean. The
* <code>onMessage</code> method displays data from the record
*
* @param record incoming record
*/
public Record onMessage(Record record) {
if (!(record instanceof IIWAFRecord)){
throw new EJBException("Received 'Record' must be of type 'IWAFRecord'");
}
IIWAFRecord iwafRecord = (IIWAFRecord)record;
try {
logger.info("<MDB> ---- Got a message ");
//Event context
IContext iCtx = iwafRecord.getIContext();
if (iCtx == null) {
logger.info("IContext is null");
} else {
StringBuffer buf = new StringBuffer();
buf.append("IContext is [");
Iterator i = iCtx.attributeNames();
while (i.hasNext()) {
String key = (String)i.next();
Object value = iCtx.getAttribute(key);
buf.append(" ");
buf.append(key);
buf.append("=");
buf.append(value);
buf.append(" ");
}
buf.append("]");
logger.info(buf.toString());
}
//Event record
String xmlData = iwafRecord.getRootXML();
if (xmlData != null) {
logger.info("<MDB> XML DATA: " + xmlData);
} else if (iwafRecord.getChars() != null) {
logger.info("<MDB> CHAR[] DATA: " + new String(iwafRecord.getChars()));
} else if (iwafRecord.getBytes() != null) {
logger.info("<MDB> BYTE[] DATA: " + iwafRecord.getBytes());
}
//Reply record
String reply = xmlData;
//Reply context
Properties replyContextProperties = new Properties();
InputStream replyContextStream = this.getClass().getClassLoader().getResourceAsStream("reply_context.properties");
if (replyContextStream != null) {
replyContextProperties.load(replyContextStream);
}
logger.info("Reply properties: " + replyContextProperties);
IIWAFRecord replyRecord = (new CCIRecordFactory()).createIWAFRecord("output");
replyRecord.setRootXML(reply);
IContext replyContext = replyRecord.getIContext();
if (iCtx != null) {
Enumeration e = replyContextProperties.keys();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = replyContextProperties.getProperty(name);
replyContext.setAttribute(name, value);
}
}
//return
return replyRecord;
} catch (Exception e) {
logger.throwing(this.getClass().getName(), "OnMessage", e);
throw new EJBException(e.getMessage());
}
} // onMessage
/**
* Removes the bean. Required by EJB specification.
*/
public void ejbRemove() {
logger.info("<MDB> In InboundMessageBean.remove()");
}
} // class|
Reference: |
The src subdirectory contains the COBOL program (IWAYEVT2.COBOL).
The following is the structure of the COBOL program (IWAYEVT2.COBOL):
CBL TRUNC(BIN)
ID DIVISION.
PROGRAM-ID. IWAYEVT2.
***************************************************************
* IWAYEVT2 - THIS SAMPLE PROGRAM DEMONSTRATES SENDING A *
* RECORD TO THE IWAY IMS ADAPTER USING CICS SOCKETS, AND *
* THEN RECEIVING THE SAME DATA BACK (ECHO). THE DATA RECORD, *
* MAPPED BY A COPYBOOK, MUST BE PRECEEDED BY A 4 BYTE BINARY *
* LENGTH. *
* *
* THE IMS ADAPTER MUST BE CONFIGURED WITH AN EVENT TO *
* RECEIVE THIS DATA. SELECT "IS LENGTH PREFIX", SYNCHRON- *
* IZATION TYPE "REQUEST", AND USE IWAYEVT0.CBL AS THE *
* PREPARSER AND PREEMITTER FD. *
* *
* HOST AND PORT MUST BE SET BELOW (PROCEDURE DIVISION) *
* *
* THE EZASOKET INTERFACE IS DOCUMENTED IN THE Z/OS *
* COMMUNICATIONS SERVER IP IMS SOCKETS GUIDE. *
* *
* USES: IWAYEVT0_IN.CBL (INPUT RECORD) *
* *
***************************************************************
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 GU PIC X(04) VALUE 'GU '.
77 CHNG PIC X(04) VALUE 'CHNG'.
77 ISRT PIC X(04) VALUE 'ISRT'.
01 SOCKET-GROUP.
05 SOC-FUNCTION PIC X(16) VALUE SPACES.
05 ERRNO PIC 9(8) BINARY VALUE ZEROES.
05 RETCODE PIC S9(8) BINARY VALUE ZEROES.
05 AF PIC 9(8) BINARY VALUE 2.
05 SOCTYPE PIC 9(8) BINARY VALUE 1.
05 PROTO PIC 9(8) BINARY VALUE 0.
05 NAMELEN PIC 9(8) BINARY.
05 HOSTNAME PIC X(255).
05 HOSTENT POINTER.
05 NAME.
10 FAMILY PIC 9(4) BINARY VALUE 2.
10 PORT PIC 9(4) BINARY. 10 IP-ADDRESS PIC 9(8) BINARY.
10 IP-ADDRESS-ALPHA REDEFINES IP-ADDRESS PIC X(4).
10 RESERVED PIC X(8) VALUE LOW-VALUES.
05 FLAGS PIC 9(8) BINARY VALUE 0.
05 SOCKET PIC 9(4) BINARY.
05 NBYTE PIC 9(8) BINARY.
05 CMD PIC 9(8) BINARY.
05 REQARG PIC 9(8) BINARY.
01 WORKAREA.
05 LLEN PIC 9(8) BINARY VALUE 4.
05 ERRMSG PIC X(41)
VALUE 'ERROR ENCOUNTERED DURING '.
05 TMSG PIC X(44)
VALUE 'IWAYEVT2: DATA SENT SUCCESSFULLLY. '.
05 RMSG PIC X(44)
VALUE 'IWAYEVT2: DATA RECEIVED SUCCESSFULLY '.
***************************************************************
* SAMPLE INBOUND DATA RECORD WITH VARIOUS COBOL TYPES. *
***************************************************************
01 INBOUND-RECORD.
05 ALPHA01 PIC X(8)
VALUE 'ABCDEFGH'.
05 INT01 PIC S9(4) BINARY VALUE 25.
05 PACK01 PIC S9(15) PACKED-DECIMAL VALUE 50.
05 ZONE01 PIC 9(4) VALUE 75.
***************************************************************
* ECHO RESPONSE. *
***************************************************************
01 RESPONSE-BUF.
02 RESPONSE-LEN PIC 9(8) BINARY.
02 RESPONSE REDEFINES RESPONSE-LEN
PIC X OCCURS 4 TIMES.
02 OUTBOUND-RECORD.
05 ALPHA01 PIC X(8).
05 INT01 PIC S9(4) BINARY.
05 PACK01 PIC S9(15) PACKED-DECIMAL.
05 ZONE01 PIC 9(4).
01 MSG-OUT.
05 IMS-LL PIC 9(4) BINARY VALUE 70.
05 IMS-ZZ PIC 9(4) BINARY.
05 MSG PIC X(70).
01 PARM-IN.
05 SLEN PIC S9(4) BINARY.
05 SCRN-IOA PIC X(255).
01 USED PIC 9(8) BINARY.
LINKAGE SECTION.
01 HOSTENT-STRUCT.
05 HOSTNAME-PTR POINTER.
05 HOSTALIASL-PTR POINTER.
05 HOSTFAMILY PIC S9(8) BINARY.
05 HOSTADR-LEN PIC S9(8) BINARY.
05 HOSTADRL-PTR POINTER.
01 HOST-ENTRY-PTR POINTER.
01 HOST-ENTRY PIC 9(8) BINARY. *********************************************************
* I/O PCB *
*********************************************************
01 IOPCB.
05 LTERM PIC X(08).
05 FILLER PIC X(02).
05 IOPCB-STATUS PIC X(02).
05 FILLER PIC X(28).
PROCEDURE DIVISION.
MAINLINE.
ENTRY 'DLITCBL' USING IOPCB
PERFORM GETPARM
***************************************************************
* CHANGE HOSTNAME AND PORT TO SITE SPECIFIC LOCATION OF THE *
* IMS ADAPTER. *
***************************************************************
MOVE 'INFORMAT-16C9AB.ibi.com' TO HOSTNAME
MOVE 4773 TO PORT
PERFORM GETSOCK
PERFORM GETHOSTBYNAME
PERFORM SETBLOCK
PERFORM CONNECTTOHOST
PERFORM SENDDATA
MOVE SPACE TO MSG
MOVE TMSG TO MSG
CALL 'CBLTDLI' USING ISRT, IOPCB, MSG-OUT
PERFORM RECVDATA
PERFORM CLOSESOCK
MOVE RMSG TO MSG
CALL 'CBLTDLI' USING ISRT, IOPCB, MSG-OUT
MOVE SPACE TO MSG
MOVE ALPHA01 OF OUTBOUND-RECORD TO MSG
MOVE INT01 OF OUTBOUND-RECORD TO MSG(10:4)
MOVE PACK01 OF OUTBOUND-RECORD TO MSG(16:15)
MOVE ZONE01 OF OUTBOUND-RECORD TO MSG(34:4)
CALL 'CBLTDLI' USING ISRT, IOPCB, MSG-OUT
GOBACK.
GETPARM.
CALL 'CBLTDLI' USING GU, IOPCB, SCRN-IOA
IF IOPCB-STATUS NOT = SPACES
PERFORM WRITERR-EXIT
END-IF
* DISPLAY 'INPUT PARM: ' SCRN-IOA
.
GETSOCK.
MOVE 'SOCKET ' TO SOC-FUNCTION
CALL 'EZASOKET' USING SOC-FUNCTION,
AF,
SOCTYPE,
PROTO,
ERRNO,
RETCODE
MOVE RETCODE TO SOCKET
IF RETCODE < 0
PERFORM WRITERR-EXIT
END-IF. GETHOSTBYNAME.
MOVE 'GETHOSTBYNAME ' TO SOC-FUNCTION
MOVE LENGTH OF HOSTNAME TO NAMELEN
CALL 'EZASOKET' USING SOC-FUNCTION NAMELEN HOSTNAME
HOSTENT RETCODE
IF RETCODE EQUAL ZERO
SET ADDRESS OF HOSTENT-STRUCT TO HOSTENT
SET ADDRESS OF HOST-ENTRY-PTR TO HOSTADRL-PTR
SET ADDRESS OF HOST-ENTRY TO HOST-ENTRY-PTR
ELSE
PERFORM WRITERR-EXIT
END-IF.
SETBLOCK.
MOVE 'FCNTL ' TO SOC-FUNCTION
MOVE 4 TO CMD
MOVE 0 TO REQARG
CALL 'EZASOKET' USING SOC-FUNCTION, SOCKET, CMD, REQARG,
ERRNO, RETCODE.
CONNECTTOHOST.
MOVE HOST-ENTRY TO IP-ADDRESS
MOVE 'CONNECT ' TO SOC-FUNCTION
CALL 'EZASOKET' USING SOC-FUNCTION,
SOCKET,
NAME,
ERRNO,
RETCODE
IF RETCODE = 0
CONTINUE
ELSE
PERFORM WRITERR-EXIT
END-IF.
SENDDATA.
***************************************************************
* PRECEDE THE RECORD WITH 4 BYTE BINARY RECORD LENGTH *
***************************************************************
MOVE 'SEND ' TO SOC-FUNCTION
MOVE LENGTH OF INBOUND-RECORD TO NBYTE
MOVE 4 TO LLEN
MOVE 0 TO RETCODE
CALL 'EZASOKET' USING SOC-FUNCTION,
SOCKET,
FLAGS,
LLEN,
NBYTE,
ERRNO,
RETCODE
IF RETCODE = -1
PERFORM WRITERR-EXIT
END-IF ***************************************************************
* SEND THE ACTUAL RECORD *
***************************************************************
CALL 'EZASOKET' USING SOC-FUNCTION,
SOCKET,
FLAGS,
NBYTE,
INBOUND-RECORD,
BY REFERENCE ERRNO,
RETCODE
IF RETCODE = -1
PERFORM WRITERR-EXIT
END-IF
.
RECVDATA.
***************************************************************
* RECEIVE A RESPONSE *
***************************************************************
MOVE LOW-VALUES TO RESPONSE-BUF.
MOVE LENGTH OF RESPONSE-BUF TO NBYTE.
MOVE 1 TO USED.
*
PERFORM READ-BYTES UNTIL NBYTE < 1.
*
READ-BYTES.
MOVE 'READ ' TO SOC-FUNCTION
CALL 'EZASOKET' USING SOC-FUNCTION,
SOCKET,
NBYTE,
RESPONSE(USED),
ERRNO,
RETCODE.
IF RETCODE < 0
PERFORM WRITERR-EXIT
END-IF
*
IF RETCODE = 0
MOVE 0 TO NBYTE
ELSE
ADD RETCODE TO USED
SUBTRACT RETCODE FROM NBYTE
END-IF
.
CLOSESOCK.
MOVE ZEROES TO RETCODE ERRNO
MOVE 'CLOSE ' TO SOC-FUNCTION
CALL 'EZASOKET' USING SOC-FUNCTION,
SOCKET,
ERRNO,
RETCODE
IF RETCODE < 0
PERFORM WRITERR-EXIT
END-IF.
WRITERR-EXIT.
MOVE SOC-FUNCTION TO ERRMSG(26:15)
DISPLAY 'ERROR IN PROGRAM FUNCTION: ' ERRMSG.
GOBACK.