Even though its a relatively new concept for AS/400 shops, cross-platform computing is quite pervasive these days. Plenty of departments already exist in which no new development takes place without the staff giving thought as to how the new kid on the block will fit in with the networked neighborhood. Some departments are heading toward letting Java servlets be the glue that binds together various components of the
networkservlets that run on any Web server, access any database, and communicate with any client. Its a nice idea, but, as they say, the devil is in the details.
How is an AS/400 able to conform to the paradigm of cross-platform computing? Well, for starters, its become less dependent on its original SNA communication platform and has added more TCP/IP features with each OS/400 release. These TCP/IP features are important because TCP/IP is an absolute necessity for systems that have e-commerce aspirations.
The AS/400 found itself lagging behind other systems in this area but has quickly caught up. At home, I still have the OS/400 V2R3 Softcopy Library, which is the oldest AS/400 documentation to which I have readily available access. I can open up the AS/400 TCP/IP Guide manual and see that its dated November 1993 (three years after HTTP hit the Internet). I can find out how to configure TCP/IP support, configure the Telnet and FTP servers, use the Line Printer Daemon (LPD), and read how Simple Mail Transfer Protocol (SMTP) is so tied into Systems Network Architecture Distribution Services (SNADS) that it really isnt SMTP. And thats it. Oh, and there are instructions on how to PING and a definition of an internet (not the Internet but an internet). However, with the release of V4R4, OS/400 now boasts a rich set of TCP/IP applications that enable it to participate to the maximum extent in the networked economy.
TCP/IP Application Architecture
Ill use the popular FTP service as an example to illustrate how these applications work. When the AS/400 FTP server is started, it runs in the background, listening on its designated port for FTP client requests. Ports are the logical locations in the TCP/IP service through which TCP/IP sends and receives data. FTP servers are usually listening on port 21 for connection requests. There are 65,535 available ports to use, and many of them are so-called well known ports. Well-known ports are usually reserved for particular
services so that everybody doesnt use a different port for the same service and vice versa. Using the FTP example, suppose you start your FTP server and have it listen on a port, say 22, and I try to connect using the well-known port 21. I would be unable to connect my FTP client to your FTP server, even though my machine would recognize your IP address and yours would recognize mine.
Assume everything is running smoothly and your FTP server job is listening on port 21 for FTP client requests. What does that really mean? What happens when it receives a connection request? Heres where the concept of threads is introduced. If your FTP server did not implement threads, it would be able to handle only one FTP connection at a time. This restriction would mean that, if your AS/400 served MP3 files via FTP,
youd have to wait to download your Sinatra tune until I was done downloading the entire works of Van Halen. And you had better hope I log off before going away for the weekend. Thanks to threads, no FTP server would behave this way.
A server job must implement threads to accommodate as much or as little activity as necessary. When running, your FTP server is probably performing a loop to listen for and accept a connection request. Once a client has made a connection request, your server will create a new thread (called spawning a new thread, or forking) to service the connection and go back to listening for new connection requests while the newly connected client deals with the newly spawned thread. The server will continue to do this for all connection requests or until the machine runs out of resources. The concept of threads is fairly straightforward. Programming for them, however, can be tricky (although Java 2 makes great strides in simplifying things for developers).
Internet Illumination
Inevitably, once one understands how TCP/IP servers work, the light bulb comes on and it becomes evident that this concept would work great for just about anything. A person could think of plenty of reasons to have a background job running quietly and dutifully and have it increase or decrease its own activity level all by itself. For example, a transaction- based server job could receive transaction requests to update database files by several clients of unknown platforms. All you would have to do is write a program to do the same thing the FTP, Telnet, and HTTP servers do on your machine, only, instead of transferring files or sending out terminal emulation, youd receive the transactions and promise the client youd do the transaction for him. But this explanation is like saying all you have to do to be a millionaire is to go out and get a million bucks. There are a few extra steps involved.
As I mentioned, the idea of threads may be easy to understand, but it can get rather complicated pretty quickly. The more robust your server job is, the more likely it is that youll become painfully familiar with concepts such as thread pooling, lock starvation, thread scheduling, and race conditions. I wouldnt recommend that your first foray into programming with a language that supports threads be this type of scenario. So say youve checked out the details of what it would take to roll your own server and you decide that writing a threadsafe server would be a very daunting task. But, man, it sure would be nice to have that server job to process your transactions. Enter WebSphere Application Server and the servlet programming model.
Start Your Application Engines
One of the many functions of WebSphere Application Server is that it performs as a servlet engine. A servlet engine is simply software that supports the Java Servlet API reference implementationin other words, software that can do servlets the way Sun intends servlets to be done. Servlet engines come in standalone or embedded form, but they are usually an add-on to an existing Web server. In the AS/400s case, WebSphere Application Server is the servlet engine plug-in for IBMs HTTP Server for the AS/400.
Servlet engines evoke servlets and run them through their life cycle in much the same way a browser runs an applet through its life cycle. For example, the init() and destroy() methods of a servlet are called by the servlet engine automatically, just as applets have their init() and destroy() methods called automatically by the browser.
How does the servlet engine know when to evoke the servlet in the first place? The most common method is simply hitting a URL with a browseragain, as occurs with an applet. Your Web server notifies the servlet engine when it has received a request for a URL that is mapped to a servlet. When the servlet engine receives this notification, it will fire up the servlet by creating an instance of the servlet object in the Java Virtual Machine (JVM) of the servlet engine.
Where one really sees the benefits of servlets is in the way the servlet engine implements threading. A developer isnt entirely free of the worries of threads in the servlet world, but ensuring your servlet is threadsafe is a smaller beast to tame than creating your own server application. A servlet is said to be threadsafe when it acts the same way, no matter how many clients are requesting its services. For the most part, the servlet engine itself takes care of the bulk of concurrency, or multithreading. In the most common scenario, the Web servers servlet engine creates an instance of the servlet in the JVM when the servlet is evoked, as in the case of a browser hitting a URL. Once the servlet is active in the space of the JVM, the servlet engine simply channels all requests for that servlet to the single instance of the servlet. That is to say that one instance of, or one call to, a servlet is usually all that the Web server and servlet engine need to service an unlimited number of requests.
RPG as a Servlet Client
When I began writing this article, I thought Id write a servlet that would interact with client requests by receiving some data and sending some back to both an RPG and a Java client. Then I thought that, if I wrote a couple of clients to work with a servlet already on the Web, I could illustrate the power of servlets as well as drive home the point that TCP/IP is the cross-platform enabler. So here I go.
Most every servlet engine comes with a handful of examples. WebSphere has some, and their location in the AS/400 Integrated File System (AS/400 IFS) depends on which version of WebSphere youre using. For this example, though, Ill borrow a sample servlet from Suns Java Web Server Web site (jserv.javasoft.com/products/java-server/ documentation/webserver1.1/servlets/sample.html). Visit this site, and youll be able to find the source code for the servlet as well as other samples.
The specific sample Ill use is the Phone servlet. It simply takes a name parameter and returns the phone extension for that name. If you dont send any parameters, the servlet returns all the names and their extensions. Now, if you point your browser to the Phone servlet sample, youll see the URL http://jserv.javasoft.com/phone.html. Dont let this confuse you. Even though the URL has a suffix of .html, it is not a static HTML page. The HTML is dynamically generated by the servlet. Typically, servlets will have a URL with no suffix at all. Anyway, Figure 1 shows the RPG code necessary to accomplish the task. Ill spare you the details about setting up a Socket to which you can read and write data. What I do want to point out is that, thanks to TCP/IP, even RPG can be a client to a Java servlet.
In order for the servlet to understand my RPG clients request, my RPG client will have to sprechen sie HTTP (speak the language of the Web). Optionally, your servlet could extend GenericServlet; then, your client wouldnt have to speak HTTP. However, because most servlets extend HttpServlet, I coded my RPG client to use HTTP. HTTP is one of the easier TCP/IP protocols to get a handle on, as it has only a handful of commands. In fact, my RPG client has to use only one HTTP command: the GET method. And once you see how to set up Sockets in RPG, you can knock yourself out creating your own text browser, email client, Telnet client, and newsgroup readerall from RPG.
Figure 2 shows the Java client used to get the same end result achieved with the RPG client. I worded that last sentence carefully because I cheated. Java can create a Socket and perform I/O on it the same way the RPG client does, but why would I do that when I can take the easy way out and use the URL class?
RPG and Java Servlets: A Marriage of Convenience
Imagine, however, that the servlet was not written to send out its results in HTML format. Obviously, this sample servlet was written so that a Web browser could see its results. But what would happen if a servlet sent out its results in a different format, such as a data stream, that could be easily reconstructed by clients? Those clients need not be browsers. There is no law that says only HTML documents can be sent out over the HTTP port. I could just as well write a servlet that sent out non-HTML data that a client could use; if I did, I would be employing a concept known as HTTP tunneling. Even in the tightest of firewalls, HTTP traffic is customarily allowed, meaning that there is at least one port open, usually port 80.
Back to the Server
Ill wrap up by returning to the server side. If you take a look at the source code for the Phone servlet at the URL I gave, youll see that its an everyday, ordinary servlet. It doesnt concern itself with workload or how many or even what kind of clients might call upon its services. Ill bet that million bucks I mentioned that the author of the servlet never thought an RPG client on an AS/400 would come calling.
This is a concept that most AS/400 developers have no trouble at all understanding. Usually, when one writes an RPG program, he or she does so as if only one user would be using it at a time. OS/400 takes care of concurrency, object locks, and so forth. The same goes for comparing the server job model of servicing clients with the servlet model. Make life easier on yourself the next time you consider this type of application. Resist the urge to write your own server and let WebSphere Application Server do the heavy lifting for you.
REFERENCES AND RELATED MATERIALS
Sun Java Web Server Web site page: jserv.javasoft.com/products/ java-rver/documentation/webserver1.1/servlets/sample.html
* ... F-specs, D-specs, and subprocedure prototypes omitted
*
* Get the program parameters. If '*ALL' is specified, leave the query string
* and name values empty which will cause the servlet to return all entries.
C *entry plist
C parm parm1
C if parm1 '*ALL'
C eval name = parm1
C eval querystring = '/query?name='
C endif
* Get a socket descriptor to be used in other socket functions
C eval sockDesc = openSocket ( addrFam_a :
C addrType :
C protocol )
C if sockDesc = -1
C exsr close
C endif
* Convert a 'dotted format' IP address to a structure that connect()
* can use. A structure from a hostname would have to use gethostbyname()
* against a DNS server that recognized the hostname.
C eval ip = '204.160.241.104'
C eval addr = addrCvtr(ip)
* Connect to the address using the previously retrieved socket descriptor
C eval addrFam_b = 2
C eval addrPort = 80
C eval addrLength = %len(addrStruct)
C eval connResult = connSocket ( sockDesc :
C addrStruct :
C addrLength )
C if connResult = -1
C exsr close
C endif
* Gather data to send to the server, translate from EBCDIC to ASCII and send
C eval method = 'GET /phone.html'
C eval method = %trim(method) + trailer
C movel method xlatebuffer
C eval xlatebufflen = %len(%trim(method))
C callP xlate ( xlatebufflen :
C xlatebuffer :
C ebcdic2ascii )
*
C eval writeResult = writeData ( sockDesc :
C %addr(xlatebuffer) :
C xlatebufflen )
C if writeResult = -1
C exsr close
C endif
*
* Read in the initial message from the web server. If everything is OK,
* you'll receive an HTTP 200 message in the first reply before receiving
* what's really at the URL.
C exsr readIn
C if %subst(readBuffer:10:3) = '200'
C clear readBuffer
C exsr readIn
C endif
*
* Iterate through the received and translated buffer, parsing out lines between
* the carriage return character hex X'0D' (the same for both ASCII and EBCDIC).
* Write the parsed lines to a printer file and a database file.
*
C dou b = 0
C X'0D' scan readBuffer:a b
C if b = 0
C leave
C endif
C eval dbfld = %subst(readBuffer:a:(b-a))
C except
C eval a = b + 2
C enddo
*
* Close the socket descriptor which ends the TCP/IP connection
*
C eval closeResult = closeSocket ( sockDesc )
*
C eval *InLR = *on
* ... readIn and close subroutines omitted public static void main(String args[])
{
try
{
String urlString;
if(args.length > 0)
urlString = "http://jserv.javasoft.com/phone.html?name=" + args[0];
else
urlString = "http://jserv.javasoft.com/phone.html";
URL url = new URL(urlString);
DataInputStream dis = new DataInputStream(url.openConnection().
getInputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(dis));
String incoming;
while((incoming=in.readLine()) != null)
{
System.out.println(incoming);
}
Figure 1: With TCP/IP, RPG can be a client to a Java servlet.
import java.io.*;
import java.net.*;
public class JavaClient {
}
Figure 2: A Java client can speak to the servlet and receive data back, just as the RPG client in Figure 1 does.
}
catch(Exception e)
{
System.out.println(e);
}
}
LATEST COMMENTS
MC Press Online