dcsimg
 

Using ASP to communicate to a mainframe

by ServerWatch Staff

In this example I will expand upon the filesystem object along with session and application variables to commuicate with a terminal emulator to process mainframe transactions.

by Bob Dombroski

In this example I will expand upon the filesystemobject along with session and application variables to commuicate with a terminal emulator to process mainframe transactions.

I refer to two different transactions in this article, the first is what I call the secure transaction. This type of transaction has the security built within the transaction itself. This could mean a password or identifer is embedded in the transaction. The second type I refer to as a unsecure transaction. This type of transaction assumes a secured system protects the transaction. Both these terms are completely made up by me...if they resemble real documentes terms it is completely by coincedence. Another term I made up is port_files. What I mean by this is that files are used to port information between 2 applications.

Example : The XYZ insurance company has an office. Before an agent can process transactions he must he must successfully  sign into the system at the office. Once signed in he can process transactions. This is what I call unsecure transaction. Lets say the insurance company also has an internet site where its customers can log in and view their upcoming premiums. In the web site they build a transaction where the password the web surfer entered is actually part of the transaction. The first step in processing the transaction is to verify the supplied password is correct for the suppllied account number, if it is not then the transaction fails.

Okay now you know my interpretation of secure and unsecure transactions so lets move on.

The secure transaction

The first page: Premium_View.htm

We set up a web page that will  collect the account and user information for the premium view transaction. This is just a  post form that passes the variables to the port_file.asp page which does all the work.

Page 2: Port_file.asp

This page gathers up the information passed to it and creates a port_file transaction. The transaction I create contains a numeric value(represents which transaction) the policy number and the password. There is a bit of security built in this method. We could just as easily create the full transaction within the ASP page, but by having the terminal emulator build the transaction  we can limit the transactions to just those the emulator is coded for. Once we create the port_file transaction we must find the next available port_file.  If the transaction has heavy traffic this could be difficult if we just try to see if a file exists. With timing issues you could get a false on the file exists, but by the time you actually open the file another web user could have written that port_file. To get around this I use an application variable called port_nbr_open which is just a string = "0000000000". This example allows up to 10 ports open, you could increase or decrease this number if needed. Using the application lock method I can stop all other users from updating the string until the current user is done. Once locked I find the first "0" and change it to a "1", then unlock the application. All other attempts to find an open port number will see this port number is taken.

Once we have an open port_file we write the transaction to the file and close it.   Then the ASP page waits for a reply port_file for that port number. Once received it can reply with the information contained in the port_file and delete the port_file response. It also must unlock that port_number from the application variable.

Enough for the talk lets go to the code! Sorry there is no working example of this one.

I have posted a very bland input page. Just two inputs, a policy number and a password. In a real world situation you might want to add some client side scripts to verify a valid policy number has been entered and a password has been entered.

<HTML>

<TITLE>Premium Review</TITLE>

<BODY>

<FORM METHOD = "POST" ACTION = "PORT_FILE.ASP>

ENTER YOUR POLICY NUMBER:<INPUT TYPE = "TEXT" NAME = "POLICY_NBR" SIZE = "20"><BR>

ENTER YOUR PASSWORD:<INPUT TYPE = "PASSWORD" NAME = "PASS" SIZE = "20"><BR>

<INPUT TYPE = "SUBMIT" NAME = "SUB_BUTTON" VALUE = "SUBMIT">

</FORM>

</BODY>

</HTML>

 

 

 

<HTML>

<TITLE>PREMIUM RESULTS</TITLE>

<BODY>

<form METHOD="GET" >
<%
POLICY_NBR = REQUEST ("POLICY_NBR")
PASSWORD = REQUEST("PASS")

APPLICATION.LOCK     'Lock the application variable so no other user can access it
FREE_FILE = APPLICATION("PORT_NBR_OPEN")
I = 1
FOUND_ONE = 0  'FOUND_ONE will contain 1 or 2 out of loop, 2 is no open ports
DO WHILE FOUND_ONE > 0   
      IF MID(FREE_FILE, I, 1) = "0" THEN     'find the first open port(the first "0")
           MID(FREE_FILE, I, 1) = "1"
           FOUND_ONE = 1
      ELSE
           I = I + 1
           IF I > 10 THEN
               FOUND_ONE = 2
           END IF
      END IF
LOOP
APPLICATION("PORT_NBR_OPEN") = FREE_FILE  'reset the application var to show we
APPLICATION.UNLOCK                                              'have this port, then unlock the appl

IF FOUND_ONE = 2 THEN  'oops no open ports to use
    RESPONSE.WRITE("SERVER BUSY, TRY YOUR REQUEST AT A LATER TIME")
ELSE

FILE_NBR = I
ON ERROR RESUME NEXT  'we want to handle our own errors
SET FS = server.CREATEOBJECT("SCRIPTING.FILESYSTEMOBJECT")
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")

FILE_NAME = "PORT_FILE" & FILE_NBR & ".INP" 'the file name will be PORT_FILE#.inp

SET A = FS.OPENTEXTFILE(FILE_NAME) 'as an added precaution see if the file exists
                                                                         'if we can open to read, it already exists


IF ERR.NUMBER = 0 THEN           'Oops a .inp file already exists for this port, even though the
    RESPONSE.WRITE("SERVER ERROR")  'the application variable said it was open
ELSE

ERR.CLEAR    'We wanted the error, so just clear it and go on
SET A = FileObject.CreateTextFile (FILE_NAME, True)  'Creates a new .inp file

'Using a *  as a delimiter between each field
LINE = "001*" & POLICY_NBR & "*" & PASSWORD

A.WRITELINE(LINE)      'write the line to the file and close it
SET A = NOTHING

FILE_NAME = "PORT_FILE" & FILE_NBR & ".OUT"  ' the response will be in the file
                                                                                         'PORT_FILE#.OUT


DONE = 0   'This loop will check for the file every 1 second.
START = NOW()
TOTAL_WAIT = 0    'used to limit the max wait for a response
MAX_WAIT = 10
DO WHILE DONE = 0
      SET INSTREAM= FileObject.OpenTextFile (file_name, 1, False, False)
      IF ERR.NUMBER <> 0 THEN     'If there is an error then the file is not present
         AGAIN = NOW()
         DONE2 = 0
         DO WHILE DONE2 = 0
                ERR.CLEAR
                AGAIN2 = NOW()
                SECS = DATEDIFF("S",START,AGAIN)  'DateDiff returns the difference between
                 IF ABS(SECS) > 1 THEN    '2 date/times, the"S" returns # of seconds
                     DONE2 = 1
                     TOTAL_WAIT = TOTAL_WAIT + 1
                     START = NOW()     'Reset the start time
                 END IF
          LOOP
          IF TOTAL_WAIT > MAX_WAIT   THEN 
               DONE = 2     'Max wait has passed lets get out and error
          END IF
      ELSE
         DONE = 1
      END IF
LOOP
IF DONE = 1 THEN
     RESPONSE.WRITE "<PRE>"    ' the response is preformatted
     WHILE NOT INSTREAM.AtEndOfStream    'Read thru the file and write it back out
                  RESPONSE.WRITE INSTREAM.READLINE & "<BR>"
     WEND
      RESPONSE.WRITE "</PRE>"
      INSTREAM.CLOSE
      SET INSTREAM = NOTHING
ELSE
     SET INSTREAM = NOTHING   'If we get here we never got a response
     RESPONSE.WRITE "Server ERROR pipe #"& file_nbr & "<br>"
END IF

FILE_NAME = "PIPE_NBR" & FILE_NBR & ".DNE" 'Now I write a done file to let
                                                                            'the application know I am done with this file

Set A = FileObject.CreateTextFile (file_name, True)
LINE = "DONE"

A.WRITELINE(LINE)
SET A = NOTHING
APPLICATION.LOCK   'now free up the port in the application
FREE_FILE = APPLICATION("PORT_NBR_OPEN")
MID(FREE_FILE, FILE_NBR, 1) = "0"
APPLICATION("PORT_NBR_OPEN") = FREE_FILE
APPLICATION.UNLOCK

END IF
END IF

'Note: the above method is not full proof. An inp file could be left not processed on a session 'abandon. More security would need to be added in a real world release. Some examples would be 'to write the requesting IP address in the inp file and rewrite it in the out file. If the IP address does 'not match the user waiting for the out file we would not show the results to that user. Also could put 'some code in the global.asa file for Session_OnEnd to free up any port files the user may have in 'their possession. You could also add another application variable to track the time when a port_file 'was taken, then if a user gets a no open port error then check to see if a port has been taken for a 'long time(since we only allow 10 seconds for a response, a long time should mean anything over 10 'seconds) and free it up for reuse.

%>
</FORM>

</BODY>

</HTML>

<HTML>

<TITLE>PREMIUM RESULTS</TITLE>

<BODY>

<form METHOD="GET" >
<%
POLICY_NBR = REQUEST ("POLICY_NBR")
PASSWORD = REQUEST("PASS")

APPLICATION.LOCK     'Lock the application variable so no other user can access it
FREE_FILE = APPLICATION("PORT_NBR_OPEN")
I = 1
FOUND_ONE = 0  'FOUND_ONE will contain 1 or 2 out of loop, 2 is no open ports
DO WHILE FOUND_ONE > 0   
      IF MID(FREE_FILE, I, 1) = "0" THEN     'find the first open port(the first "0")
           MID(FREE_FILE, I, 1) = "1"
           FOUND_ONE = 1
      ELSE
           I = I + 1
           IF I > 10 THEN
               FOUND_ONE = 2
           END IF
      END IF
LOOP
APPLICATION("PORT_NBR_OPEN") = FREE_FILE  'reset the application var to show we
APPLICATION.UNLOCK                                              'have this port, then unlock the appl

IF FOUND_ONE = 2 THEN  'oops no open ports to use
    RESPONSE.WRITE("SERVER BUSY, TRY YOUR REQUEST AT A LATER TIME")
ELSE

FILE_NBR = I
ON ERROR RESUME NEXT  'we want to handle our own errors
SET FS = server.CREATEOBJECT("SCRIPTING.FILESYSTEMOBJECT")
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")

FILE_NAME = "PORT_FILE" & FILE_NBR & ".INP" 'the file name will be PORT_FILE#.inp

SET A = FS.OPENTEXTFILE(FILE_NAME) 'as an added precaution see if the file exists
                                                                         'if we can open to read, it already exists


IF ERR.NUMBER = 0 THEN           'Oops a .inp file already exists for this port, even though the
    RESPONSE.WRITE("SERVER ERROR")  'the application variable said it was open
ELSE

ERR.CLEAR    'We wanted the error, so just clear it and go on
SET A = FileObject.CreateTextFile (FILE_NAME, True)  'Creates a new .inp file

'Using a *  as a delimiter between each field
LINE = "001*" & POLICY_NBR & "*" & PASSWORD

A.WRITELINE(LINE)      'write the line to the file and close it
SET A = NOTHING

FILE_NAME = "PORT_FILE" & FILE_NBR & ".OUT"  ' the response will be in the file
                                                                                         'PORT_FILE#.OUT


DONE = 0   'This loop will check for the file every 1 second.
START = NOW()
TOTAL_WAIT = 0    'used to limit the max wait for a response
MAX_WAIT = 10
DO WHILE DONE = 0
      SET INSTREAM= FileObject.OpenTextFile (file_name, 1, False, False)
      IF ERR.NUMBER <> 0 THEN     'If there is an error then the file is not present
         AGAIN = NOW()
         DONE2 = 0
         DO WHILE DONE2 = 0
                ERR.CLEAR
                AGAIN2 = NOW()
                SECS = DATEDIFF("S",START,AGAIN)  'DateDiff returns the difference between
                 IF ABS(SECS) > 1 THEN    '2 date/times, the"S" returns # of seconds
                     DONE2 = 1
                     TOTAL_WAIT = TOTAL_WAIT + 1
                     START = NOW()     'Reset the start time
                 END IF
          LOOP
          IF TOTAL_WAIT > MAX_WAIT   THEN 
               DONE = 2     'Max wait has passed lets get out and error
          END IF
      ELSE
         DONE = 1
      END IF
LOOP
IF DONE = 1 THEN
     RESPONSE.WRITE "<PRE>"    ' the response is preformatted
     WHILE NOT INSTREAM.AtEndOfStream    'Read thru the file and write it back out
                  RESPONSE.WRITE INSTREAM.READLINE & "<BR>"
     WEND
      RESPONSE.WRITE "</PRE>"
      INSTREAM.CLOSE
      SET INSTREAM = NOTHING
ELSE
     SET INSTREAM = NOTHING   'If we get here we never got a response
     RESPONSE.WRITE "Server ERROR pipe #"& file_nbr & "<br>"
END IF

FILE_NAME = "PIPE_NBR" & FILE_NBR & ".DNE" 'Now I write a done file to let
                                                                            'the application know I am done with this file

Set A = FileObject.CreateTextFile (file_name, True)
LINE = "DONE"

A.WRITELINE(LINE)
SET A = NOTHING
APPLICATION.LOCK   'now free up the port in the application
FREE_FILE = APPLICATION("PORT_NBR_OPEN")
MID(FREE_FILE, FILE_NBR, 1) = "0"
APPLICATION("PORT_NBR_OPEN") = FREE_FILE
APPLICATION.UNLOCK

END IF
END IF

'Note: the above method is not full proof. An inp file could be left not processed on a session 'abandon. More security would need to be added in a real world release. Some examples would be 'to write the requesting IP address in the inp file and rewrite it in the out file. If the IP address does 'not match the user waiting for the out file we would not show the results to that user. Also could put 'some code in the global.asa file for Session_OnEnd to free up any port files the user may have in 'their possession. You could also add another application variable to track the time when a port_file 'was taken, then if a user gets a no open port error then check to see if a port has been taken for a 'long time(since we only allow 10 seconds for a response, a long time should mean anything over 10 'seconds) and free it up for reuse.

%>
</FORM>

</BODY>

</HTML>

This article was originally published on Tuesday Oct 27th 1998
Home
Mobile Site | Full Site