The basic mechanism described in Running a 3270 transaction from BTS assumed a straightforward, "one
shot" transaction, where the 3270 transaction does an EXEC CICS® RECEIVE MAP,
followed by one or more EXEC CICS SEND MAP requests, and ends with an EXEC
CICS RETURN. In practice, things are not always so simple. For example, you
may want to run 3270 transactions that:
- Output intermediate messages
- Are conversational in design
- Are pseudoconversational.
For a non-conversational 3270 transaction, the bridge exit program could
be called to write an intermediate message for either of two reasons:
- The 3270 transaction has specified WAIT on the EXEC CICS SEND command.
- The output message buffer is full.
Under some bridge transport mechanisms, it makes sense for the bridge
exit program to write an intermediate message containing the data so far.
However, under BTS there is no point in trying to send an intermediate
message back to the user.
If the exit program is called because of the WAIT option, it can simply
do nothing and return.
If the exit program is called because the message buffer is full, it should:
- Obtain a new, larger output buffer (by issuing a GETMAIN command).
- Copy the contents of the original buffer into the new buffer.
- Release the original buffer (by issuing a FREEMAIN command).
Using this approach, all output from the 3270 transaction is sent to
the client at transaction end.
The sample bridge exit program, DFH0CBAE (see Sample programs) obtains
all its storage--including that for its output buffer--at the same
time. It saves the address of the output buffer in field BRXA-OUTPUT-MESSAGE-PTR of the bridge exit area (BRXA) user area. We recommend that your exit
programs do the same.
Note:
When the exit program is called because
the output buffer is full, field BRXA-FMT-RESPONSE of the BRXA
is set to BRXA-FMT-OUTPUT-BUFFER-FULL. The current size of the
storage is in field BRXA-OUTPUT-MESSAGE-LEN.
This section describes
how to run a conversational 3270 transaction.
A potential problem is that, at one or more stages, the 3270 transaction
requires further data to continue. The bridge exit program cannot obtain this
data from the client. That is, it cannot end its current activation, to be
reactivated with the required data--because the 3270 transaction has
not completed, issuing an EXEC CICS RETURN command would merely return control
to the latter. Nor can the exit program get information back to the client
by issuing an EXEC CICS SYNCPOINT command,
because this would
modify the 3270 transaction
.
One solution is for the bridge exit program itself to obtain (or compute)
the required data. Perhaps a better solution is for the exit program to create
a subtask to obtain the data. It could, for example, create a separate child
activity (a grandchild of the client) to deal with each request for data--each
intermediate map--sent by the 3270 transaction. (For convenience, we’ll
refer to such child activities as "conversational activities".) Figure 30 illustrates this approach.
One possible problem of creating a separate activity to deal with each
intermediate map is that the output message sent to the client by the exit
program at transaction end contains only the final 3270 map. If it’s important
that intermediate messages should be preserved, the conversational activities
could put them in other containers associated with the client.
Figure 31 contains example pseudocode for running a 3270 conversational
transaction.
Figure 31. Pseudocode for running a 3270 conversational transaction as a BTS activity. The bridge exit program creates a child activity to deal with
each map sent by the 3270 transaction.
Bridge exit program |
"Conversational" activity |
Read_Message.
encode conv-in-buffer from 3270-msg-out-buffer
EXEC CICS DEFINE ACTIVITY (next-conv-act-name)
TRANSID(conv-transaction-id)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Request')
ACTIVITY(next-conv-act-name)
FROM(conv-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS LINK ACTIVITY(next-conv-act-name)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS CHECK ACTIVITY(next-conv-act-name)
COMPSTATUS(status) ABCODE(a)
RESP(data-area) RESP2(data-area) END-EXEC
If status NOT = DFHVALUE(NORMAL)
EXEC CICS ABEND ABCODE(a)
NODUMP
RESP(data-area) RESP2(data-area) END-EXEC
End-If.
.
EXEC CICS GET CONTAINER('Request')
ACTIVITY(next-conv-act-name)
INTO(3270-msg-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
.
Write_Message.
Intermediate writes cannot be sent
to the client.
EXEC CICS NOOP
RESP(data-area) RESP2(data-area) END-EXEC
.
|
WHEN DFH-Initial
EXEC CICS GET CONTAINER('Request')
INTO(msg-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
decode msg-in-buffer
encode msg-out-buffer
.
EXEC CICS PUT CONTAINER('Request')
FROM(msg-out-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RETURN END-EXEC
|
Note that the exit program issues a LINK ACTIVITY, rather than a RUN ACTIVITY
SYNCHRONOUS, command to activate the "conversational" child activity.
This is necessary to ensure that the child executes in the same unit of work as the
exit program.
This
section describes how to run a pseudoconversational 3270 transaction.
A pseudoconversation is indicated by the fact that the output data returned
to the client by the exit program contains a bridge facility token (and possibly
a next-transaction ID). It is the client’s responsibility to check the
appropriate field in the output message and to start the next transaction.
Figure 32 contains example pseudocode for running a 3270 pseudoconversational
transaction.
Figure 32. Pseudocode for running a 3270 pseudoconversational transaction as a BTS activity
Client activity |
Bridge exit program |
When DFH-Initial
encode msg-in-buffer
EXEC CICS DEFINE ACTIVITY (3270-act-name)
TRANSID(transaction-id) EVENT(3270-Complete)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Message')
ACTIVITY(3270-act-name) FROM(msg-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY(3270-act-name)
ASYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RETURN END-EXEC
.
.
When 3270-Complete
EXEC CICS CHECK ACTIVITY(3270-act-name)
COMPSTATUS(status) ABCODE(a)
RESP(data-area) RESP2(data-area) END-EXEC
If status NOT = DFHVALUE(NORMAL)
EXEC CICS ABEND ABCODE(a)
NODUMP
RESP(data-area) RESP2(data-area) END-EXEC
End-If.
.
EXEC CICS GET CONTAINER('Message')
ACTIVITY(3270-act-name) INTO(msg-out-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
decode msg-out-buffer
If mqcih-facility = blank
EXEC CICS RETURN ENDACTIVITY END-EXEC
Else
encode msg-in-buffer
EXEC CICS DEFINE ACTIVITY (3270-act-name)
TRANSID(next-transaction-id)
EVENT(3270-Complete)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Message')
ACTIVITY(3270-act-name)
FROM(msg-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY(3270-act-name)
ASYNCHRONOUS
FACILITYTOKN(8-byte token)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RETURN END-EXEC
End-If.
|
Init.
pass userdata from the brdata to BRXA
.
.
Bind.
EXEC CICS GET CONTAINER('Message')
INTO(3270-msg-in-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
.
Term.
EXEC CICS PUT CONTAINER('Message')
FROM(3270-msg-out-buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RETURN END-EXEC
|
Note that:
- The client starts each transaction in the pseudoconversation by defining
and running a new child activity, rather than by reactivating the same child
activity with a different input event. This is necessary, in case the next-transaction
IDs returned by the 3270 application are different--that is, in case
each step of the pseudoconversation is implemented by a differently-named
transaction. (The variable next-transaction-id is
used to name the transaction that implements each new child activity.)
- In this example, the variable 3270-act-name is
used to name each child activity differently. An alternative approach might
be to delete the completed child activity before redefining it with a different
TRANSID.
- In this example, the variable 3270-Complete is
used to name each activity completion event differently. This is not strictly
necessary, because if the previous child activity completed normally its completion
event will have been deleted from the client’s event pool following the
CHECK ACTIVITY command.
- The output message returned by the bridge exit program should contain
an 8-byte token representing the bridge facility. So that the bridge facility
is reused for the next transaction in the pseudoconversation, the client uses
the FACILITYTOKN option of the RUN ACTIVITY command to pass the token to the
next child activity.
Transaction routing of pseudoconversations
The 3270 bridge does not support transaction routing of pseudoconversations.
If a 3270 transaction is pseudoconversational, and is started from BTS,
it is essential that all its constituent transactions run in the same CICS
region. If one of the transactions is routed to a different region, an ABRH
abend occurs.
One way to ensure that all the transactions execute in the same region
is for the client to run the child activities synchronously. Activities that
are run synchronously always run in the local region--they are never
routed.
However, although all the transactions in a pseudoconversation have to
run in the same region, they do not have to run in the same region as the
client; nor do they have to run in a specific region (though, of course, it
must be a CICS TS OS/390®, Version 1 Release 3 or later region). If you use CICSPlex® SM for routing purposes,
you can define all the 3270 transactions in a pseudoconversation as part of
the same transaction group. This gives you two options:
- You can define the transaction group to run on a specific named region.
- You can define the transaction group to run on whichever region the first
transaction within a BTS process runs on. This is the preferred option.
[[ Contents Previous Page | Next Page Index ]]