CORBA Web Server Assignment Part 3

This assignment is a follow-on to the second CORBA Web server assignment. In this version, you'll add the following two changes to the previous version: Since these are really two separate problems, I recommend writing two applications. However, you should try to reuse as much code as possible for each part of the assignment.


Design and Implementation Issues

CORBA IDL Interface

The first part of the assignment will require no changes to the existing IDL. As a result, there's an implicit assumption that only one AMI call will be pending for each server the client accesses since otherwise the responses could get out of order and we'd need to pass back the appropriate offset to the client.

The second part of the assignment, however, will require the following IDL specification:

// IDL schema definition for Web server interface.
module Web_Server
{
  typedef sequence<octet> Chunk_Type;

  interface Callback
  {
    // This operation is called back by the server to pass
    // the next <chunk> of the file starting at <offset>.  
    // If there are no more chunks, <last_chunk> is true.
    void next_chunk (in Chunk_Type chunk,
                     in unsigned long offset,
                     in boolean last_chunk);
  };

  exception Error_Result {
    // Status of the <register_callback> operation.  These
    // values should map onto the normal HTTP
    // status values, e.g., 200 means success, 404
    // means "file not found," etc.
    short status;
 };

  struct Metadata_Type 
  {
    // Modification date.
    string modification_date;
    
    // Type of content.
    string content_type;
  };

  interface Iterator_Factory
  {
    // This registration method passes a <Callback> that
    // the Web server uses to ``push'' data associated with
    // <pathname> one ``chunk'' at a time.  The <metadata>
    // reports information about the <pathname>. 
    Metadata_Type register_callback (in string pathname,
                                     in Callback client_callback)
      raises (Error_Result);
  };
};
The register_callback allows a client to pass a Callback that the Web server will use to ``push'' to the client the contents of the file associated with pathname. The register_callback operation returns a struct containing metadata that describes certain information, such as the MIME type and return status, about the pathname. If an error occurs, the Error_Result exception will be raised, its status_ field will contain a non-success value.

As the Web server reads the file, it will call the next_chunk operation to pass the file one chunk at a time to the client. I recommend passing the file in BUFSIZ chunks, i.e., the first call to next_chunk will contain offset 0 of the file, the next with offset 0 + BUFSIZ, etc. Naturally, the client will need to check the length of the sequence it gets back to know how much it got. It must also use the offset parameter to know where to write the chunk in the file. This parameter is necessary since there's no guarantee that the next_chunk callback operations will be called in a particular order on the client.

You will use a CORBA IDL compiler to translate this specification into client-side stubs and server-side skeletons. The client application (which you must write) will use the stubs as a proxy to request the server to download the content. In addition, you must also write the server, which implements the operation that downloads content to the client.


Server Functionality

On the server-side, you'll need to define a class that inherits from the skeleton generated by the IDL compiler. You can use the -GI option of TAO's IDL compiler to generate the skeletons for you. To implement the register_callback and next_chunk operations you'll need to use OS filesystem APIs, such as open(2), close(2), and read(2). I recommend that you check the UNIX manual pages for more details on using these functions.

In addition, you'll need to implement a main function that defines an instance of Web_Server_i, obtains and activates the RootPOA and then calls the ORB's run method to start its event loop.

To make your solution more scalable, the server should bind its IOR to an instance of the CORBA Naming Service that you have running. Too keep from interfering with each other's Naming Services, I recommend you add an entry to your .cshrc file that assigns your login uid number to an environment variable called NameServicePort. Here's how you can do this with csh or tcsh:


setenv NameServicePort 19850
or the following in your .profile file for Bourne shell compatible shells, e.g., sh, ksh, Bash:

NameServicePort 19850
export NameServicePort
Note that I got my uid via the id UNIX command. Remember that valid unprivileged ports on UNIX are greater than or equal to 1024 (@@ or is 1025) and less than or equal to 65535.


Client Functionality

The simple WWW client program should do the following activities:
  1. From the command-line, read the name of all the URL pathnames you want to download. Then initialize the client-side ORB and use resolve_initial_references to obtain a reference to your Naming Service (which must be running). This object reference will then be downcast via _narrow() to an object reference for a CosNaming::NamingContext interface, which you can then use to resolve the object reference that the Web server bound earlier. After you narrow this to the Web_Server interface, you can do the following actions, depending on whether you're implementing the AMI or Callback client:
  2. When next_chunk returns a chunk of the file, write the contents into a temporary file created in your WWW cache (e.g., /tmp/yourloginname) on the local host [creat,read/write].

  3. After all the chunks are returned, spawn an external viewer [fork/exec] to display the file. You can determine the type of viewer to spawn by examining the the content_type_ metadata returned by the server. Once you are done with the files, you might want to remove them from /tmp/ so that it doesn't fill up!
The client should simply print out the appropriate exception and exit with a return status of 1 if anything fails to work properly. If everything works correctly, the program should exit with a return status of 0.


Learning and Using CORBA

We will be using the TAO CORBA Object Request Broker (ORB) implementation. Please see the online help for information on how to setup your TAO development environment on ECE's computing system.


Concluding Remarks

This CORBA assignment is more complex, and you'll need learn new CORBA features, such as AMI and distributed callbacks.


Back to ECE 255 home page.