Oracle Application Server (OAS) is Oracle’s enterprise web platform. While OAS performs all the functions of a normal web server, its main advantage is its tight integration with a backend Oracle database. After starting life with the name Oracle Webserver at version 1, then becoming Oracle Web Application Server at version 3, the Oracle Application Server, now at version 4, has steadily grown in size and features.
The resources required to run OAS have increased along with the new features. For example, the memory requirements (on NT, at least) went from 48 MB in version 3 to 128 MB in version 4.
In this chapter, we’ll look at the architectural components of OAS as they relate to PL/SQL application development. Be sure that you’ve read Chapter 2, which introduces the basic concepts behind the web infrastructure on which OAS is built. We’ll start with a discussion of how OAS returns web resources to a user’s browser. Then we’ll look at the PL/SQL cartridge, an OAS component we can use to develop PL/SQL applications.
OAS has three methods to return resources. The first simply uses a directory mapping system to send static files to the client’s browser. The next two methods return dynamic resources: one executes resources using the standard CGI interface, and the other, the Web Request Broker (WRB), executes resources using a program called a cartridge.
As we saw in the previous chapter, the HTTP listener (renamed the Web listener in OAS) receives incoming requests either as URLs or as
action attributes in an HTML form. If the virtual path maps to a CGI directory, the CGI interface is used. If it maps to a cartridge, the WRB method is used. Figure 4.1 shows the relationship between these components.
In the next three sections, we’ll look at how OAS handles requests for static files, CGI dynamic resources, and WRB dynamic resources.
A static file is the simplest type of resource the OAS can deliver. A static resource is just a file that resides in a directory on the filesystem. To make the files accessible from the Web, OAS maintains a list of mappings between physical directories and symbolic aliases called virtual directories. A URL uses these aliases, along with the resource name, to retrieve the requested file. Figure 4.2 shows the virtual directory mapping screen for the OAS administration system.
The common gateway interface (CGI), the earliest web technology for developing dynamic resources, allows you to execute any kind of server-side program, whether it’s written in a third-generation language like C, a scripting language like Perl, or a database language like PL/SQL. One of the advantages of CGI is that you can use it to do almost anything: create gateways between the Web and an email system, build a help system based on Unix’s manpages, or execute scripting programs to play tic-tac-toe. The execution of a CGI program follows these steps:
The web server spawns a new process under a separate user ID.
The program is started in the new execution space.
The program executes, sending its output to standard output. The listener sends this output back to the user’s browser.
The program terminates, and the process is destroyed.
There are a number of uses for even simple CGI programs. Suppose, for example, you have a table that holds user complaints about your systems. Here is a technique that saves you valuable web-surfing time, allowing you to purge old complaints by clicking on a hyperlink. The system requires two parts. The first is a SQL*Plus script called
msg_maint.sql that clears the table. The length of time new messages are kept is passed as a command-line argument:
set feedback off; delete from tbl_user_complaints where date_created < (sysdate - &1); commit;
The second part is a script named
clear_msg that executes the SQL*Plus script and returns a status. The operating system script is necessary because you cannot directly execute a SQL script without SQL*Plus:
#!/bin/ksh # # Print mandatory header info # print "Content-type: text/html\n\n" print "<html>" print "<title>All work and no play...</title>" print "<body>" print "<h1>Evaluating User Complaints</h1><p>" # # Execute sqlplus script msg_maint.sql # sqlplus scott/tiger @msg_maint.sql 2 # # Print results # print "<h2>User Complaints Resolved</h2>" print "</body>" print "</html>"
The script is saved in a directory that is marked as containing CGI scripts and mapped to a virtual directory, typically named
cgi-bin. Once these steps are completed, the user can execute the script with a URL. For example:
This extremely simplified example reveals some important limitations of the CGI interface:
Before CGI programs can do any real work, the system must create and maintain processes, allocate resources, and perform a host of other housekeeping activities. Even worse, a CGI program must establish a new connection to the database every time it is executed. This severely affects performance, especially when a series of CGIs is linked together to form an entire application.
The previous example, which embeds a username and password directly into the script, is guaranteed to infuriate almost any DBA. Unless you have a set of library routines you can use in every program, securely connecting a program to the correct account is a thorny problem. In addition to username/password problems, many scripting languages have a complex and subtle syntax that makes it far too easy to unwittingly create insecure programs. A single misplaced character in a Perl program, for instance, can potentially compromise the entire system.
As we’ve seen, parameters are passed to a CGI program using either the query string of a URL or input elements on a form. Additionally, any non-alphanumeric characters (in a query string, at least) must be encoded before they can be safely transmitted across the Web. Once they arrive at their destination, it is up to the CGI program to manually read and decode all of them before they can be used.
In the next section, we’ll look at how OAS’s Web Request Broker architecture alleviates the problems of CGI by using cartridges.
The Web Request Broker (WRB) is another way that OAS can return a dynamic resource, and it is a significant advance over CGI. The WRB architecture maintains a pool of processes that are already running and connected to the appropriate database, and WRB is therefore much faster than CGI. When a request to run a particular program comes in, the OAS simply hands it off to one of these processes, which executes it and returns the results.
Each process handles a specific type of dynamic resource, whether it’s created with Perl, PL/SQL, or Java, or even less traditional languages like VRML. OAS plug-in cartridges allow developers to use these different development languages. The WRB consists of the cartridges themselves, the executable engines that run the cartridges, and the dispatcher that selects a particular cartridge to execute a request.
OAS uses cartridges to execute, or cause to be executed, specific kinds of resources. When OAS receives a request for a resource, it simply passes it to the appropriate cartridge. Several cartridges come with OAS, including the PL/SQL cartridge for executing PL/SQL stored procedures, the Java cartridge for executing server-side Java programs, and the Perl cartridge for executing Perl scripts. However, cartridges are not limited to serving as gateways to development languages. The ODBC cartridge, for example, executes OBDC statements and returns the results directly to a user’s browser.
Each cartridge is installed on the web server and mapped to a virtual alias. When the web listener receives a URL that includes one of these virtual mappings, it knows that it must use that cartridge to execute the specified resource. As always, the path section of the URL specifies the virtual mapping, and the resource name section specifies the resource the cartridge is to execute. These two sections must be consistent: the PL/SQL cartridge cannot execute a Java program. Figure 4.3 shows how virtual directory names are mapped to the PL/SQL cartridge in the WRB configuration screen.
The number of commercially available cartridges is growing every day. Additionally, because cartridges are based on an open interface, you can develop your own custom cartridges if you cannot buy one from a vendor. For example, you could write a cartridge to Web-enable a backend COBOL system.
When OAS initializes, it starts a number of WRB Executable Engines (WRBXs), processes that run particular cartridges. OAS starts a relatively large number of each kind of process (which ones depends on a configuration setting) to make sure that individual WRBXs don’t become bottlenecks.
For example, the pool of WRBX processes might consist of 20 PL/SQL cartridges, 10 Java cartridges, and 5 Perl cartridges. This way, if one cartridge is busy when a request comes in, another WRBX is ready to handle it. This pool of running processes accounts for most of the performance gains of the WRB architecture over CGI. However, a cartridge does not make your dynamic resource itself run any faster. It simply minimizes the time it takes for the resource to begin executing.
The WRB dispatcher is the final element in the WRB architecture. It has two jobs: the first is to receive incoming requests from the web listener and assign them to free processes in the WRBX pool; the second is to manage the WRBX pool.
Like a dispatcher at a police station, the WRB dispatcher assigns incoming tasks to specific agents from a pool of available agents. Its main goal is to fill as many of these requests as possible in the shortest amount of time by managing the various WRBX processes. To do this efficiently, the dispatcher must maintain a list of available agents, what they are currently doing, and when they will finish their assigned tasks.
Additionally, the dispatcher conserves system resources by maintaining a proper mix among the different processes. For example, the dispatcher can create new processes or destroy existing ones based on the number and types of requests received by the web listener.
Figure 4.4 shows the relationship between the parts of the WRB architecture. The diagram illustrates how the dispatcher passes a request to just one of the many available WRBX processes.