NonStop Software

The Stock Example

Previous Topic | Next Topic | Contents | Index
Getting Started Guide | Administration Guide | Reference Guide

Subtopics

Stock Object
Stock Interface Definition
Stock Interface Implementation
Client Application Program
Stock Makefile
Running the Stock Example on NonStop DOM
Running the Stock Example on Other ORBs
Source Code Files

The NonStop® Distributed Object Manager/MP (NonStop DOM) product provides a collection of sample programs that help demonstrate how to develop portable applications. The $NSDOM/samples/stock directory contains a sample program illustrating some of the basic concepts of CORBA programming with NonStop DOM.

The stock sample shows you:

In addition, the stock sample shows the portability of CORBA applications. The client application program can be built and run under NonStop DOM and other CORBA-compliant implementations. Scripts for building the client under two implementations (Visibroker by Visigenic and Orbix by IONA Technologies) are supplied.

The number of concepts introduced in this sample is intentionally limited. Powerful features of NonStop DOM such as scalable servers, Portable Object Adapter, Naming Service and Event Service are reserved for other sample programs.

Stock Object

The stock object is a resource for stock market information. An application can use this object to obtain stock market quotes.

To illustrate some CORBA programming concepts, this version of the stock sample is kept simple. For example, the stock object works from a fixed, unchanging database of stock market data. Later versions of the program build on this basic structure. The stock object is hosted by a server program running in a process. The object is used by a client application program running in another process. Communication between the client and server is achieved using CORBA-style method invocations.

As you will see from the example, the client and server do not need to run on the same machine. Further, the client and server can be hosted by different CORBA implementations. The client application program is unconcerned with the location or implementation of the stock object. It simply uses the interface defined in the interface definition. The central concepts shown by the sample carry over into "real" object definitions, implementations, and application programs.

Stock Interface Definition

The definition of the stock interface appears in the stock.idl file and it is repeated here:

The Stock Interface
interface Stock 
{
   // status for user defined exceptions
   enum operation_status {
      NOT_FOUND       // Stock symbol not found
   };	
 
   // user defined exception
   exception operationFailed {
      operation_status status;        // The type of failure
   };
 
   void quote( in string Symbol, out double Last, out double High, 
               out double Low, out unsigned long Volume )
        raises( operationFailed );
  
   void update( in string Symbol,
                in double Price, in unsigned long Volume ) 
        raises( operationFailed );
  };

This definition names the interface Stock. It also names the quote( ) and update( ) methods available to a user of a stock object. The parameters and return values for each method are given. The methods may detect exceptional conditions. These are defined by the exception and raises constructs.

Stock Interface Implementation

The C++ implementation files are:

The file stock_servmain.cpp holds the main program for the server. When compiled, it

As a result of these actions there is an instance of a stock object ready to accept requests. The identity and location of the object is encapsulated in the object reference written to the file. The POA waits for requests to arrive. When requests arrive, the POA invokes methods defined in stock.cpp.

The file stock.h holds the C++ class definition corresponding to the interface defined in stock.idl. The individual methods that constitute the public interface are declared. Also, the private instance variables holding the current stock data are defined.

The file stock.cpp holds the implementation of the methods defined in the stock interface. Looking at the file, you can see that the methods are uncomplicated. The constructor initializes the stored stock market data used by the quote( ) method. The quote( ) method accepts a stock symbol and returns the data associated with it. If the stock symbol is not defined, an operationFailed exception is raised. This exception is returned to the caller who should test for it.

Client Application Program

The C++ client application file is contained in the client.cpp file.

The client application program:

This client application exercises the quote( ) method provided by the stock object. For each stock symbol of interest, the quote( ) method is invoked. The results returned from the method are displayed. An undefined stock symbol is supplied to quote( ) causing the user exception to be raised.

Careful CORBA programming requires that one faithfully check for exceptions for each method invocation. Exceptions can occur for system reasons such as network unavailability, object unavailability, resource unavailability, and so on. Exceptions can also be generated by the object itself to communicate information about the method invocation. Only by checking conscientiously for exceptions can correct program behavior be achieved.

The CORBA standard provides for varying implementations of exception handling. This client application uses some macros (TRY, CATCH, and so on) to handle two available variations. When the C++ compiler used to compile the programs supports C++ style exceptions, the macros simply rename the native try and catch facilities. When the C++ compiler does not support C++ style exceptions, the macros encapsulate the CORBA-defined exception handling mechanism for this situation. Thus, the macros provide a means for portability to different exception handling environments.

Stock Makefile

A make script named Makefile is provided that enables you to build the stock sample on NonStop DOM. The Makefile performs all the required steps to construct the executable components. Macros used in the makefile are defined in etc/macros.mk To build the sample, follow these steps:

  1. Make sure you are in the samples/stock directory of the NonStop DOM installation, or copy the files to a new directory
  2. Make sure you have executed the env.sh script that sets needed environment variables (see the NonStop DOM Administration Guide configuration instructions):
    . etc/env.sh
  3. Execute the make script with the following command:
    make

What the make script does

The make script:

The NonStop DOM IDL (NSDIDL) compiler, takes stock.idl as input and produces four files:

You do not need to view or understand the contents of these files. Simply put, they contain the CORBA specified "C++ language mapping" translation of the interface definition. Client programs use the stock_client components to use the interface. Server programs use the stock_server components to implement the interface.

The C++ compilation steps use the standard Tandem NonStop Kernel Open System Service (OSS) tools to compile and link the programs. The NonStop DOM ORB implementation files are held in a Shared Run-time Library (SRL). All NonStop DOM applications running in a processor share the ORB implementation code, thereby conserving memory resources.

Running the Stock Example on NonStop DOM

To run the stock sample you will need two OSS windows. Make sure each window is in the directory where the stock sample was built has the correct NonStop DOM environment (obtained by using env.sh as described above.)

In one window, start the server program:

server -ORBprofile tcp_server

In the other window, start the client program:

client -ORBprofile tcp_client

In the client window, you should see the following output:

   Quote for CPQ: Last=35.5, High=35.8125, Low=34.3875, Volume=18285500
   Quote for MOB: Last=70.5, High=70.5, Low=69.1875, Volume=1462200
   Quote for XON: Last=62.25, High=62.625, Low=61.875, Volume=1308200
   Quote for IBM: Last=102.875, High=103.188, Low=101.563, Volume=2810700
   Quote for MSFT: Last=158.375, High=158.938, Low=156.063, Volume=8613000
   Got operationFailed exception as expected.

Running the Stock Example on Other ORBs

If you have an installation of Visibroker by Visigenic or Orbix by IONA Technologies, you can witness CORBA interoperability. The client part of the stock sample can be built and executed under these ORBs. (Other CORBA-compliant ORBs may be used as well.) The server part of the stock sample continues to execute under NonStop DOM.

Two make scripts are provided to show interoperability:

If you have a different ORB implementation or a different platform, you can construct a make script based on those provided.

Copy the following files to the machine on which you want to run the client application:

Use the provided make scripts to modify the location of the ORB installation directory. Modify either VBROKERDIR in Makefile-visi or ORBIXDIR in Makefile-orbix. Execute the make script using the Microsoft nmake tool. The make script produces a client.exe program.

The make script performs actions analogous to those described earlier for building under NonStop DOM. As before, the interface definition in stock.idl is compiled to produce C++ language mappings used by the client program. The client program is compiled along with the language mappings to produce a client application executable.

Run the stock server program under NonStop DOM as described previously. Copy the stock.ior file from the NonStop DOM execution directory to the platform where the client application program has been built. (For example, you can use ftp, nfs, or something similar to transfer the file.)

Source Code Files

Stock Server Main Source Code

Contents of stock_servmain.cpp
// Copyright (C) 1998, Tandem Computers Incorporated.
// All Rights Reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for NON-COMMERCIAL purposes and without fee is hereby
// granted provided that this copyright notice appears in all copies.
//
// Tandem, a division of Compaq, MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT
// THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. Tandem, a division of Compaq, SHALL
// NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
// -------------------------------------------------------------------------

#include "stock.h"
#include "GetPutIOR.h"
#include "nsdorb/poa.h"

int main(int argc, char *argv[])
{
 
  // Initialize the ORB
  CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
 
  // Get object reference for POA Manager
  CORBA::Object_ptr pfobj =
    orb->resolve_initial_references("RootPOA");
 
  PortableServer::POA_ptr rootPOA;
  rootPOA = PortableServer::POA::_narrow(pfobj);
 
  // Create servant
  Stock_impl *lp_test_servant = new Stock_impl;
 
  // Let poa know about object, poa generates object ID
  //   (and creates "active object map" entry: oid, object)
  PortableServer::ObjectId_ptr oid
    = rootPOA->activate_object(lp_test_servant);
  delete oid;
 
  // create the stringified reference to the servant and write it to
  // file.
  char* lp_IOR_string = orb->object_to_string( lp_test_servant );

  if (!PutObjectReference("stock.ior", lp_IOR_string))
     return 1;

  // Activate the poa
  rootPOA->the_POAManager()->activate();
 
  // Service requests
  orb->run();
 
  return 0;
} // main

Stock Source Code

Contents of stock.cpp
// Copyright (C) 1998, Tandem Computers Incorporated.
// All Rights Reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for NON-COMMERCIAL purposes and without fee is hereby
// granted provided that this copyright notice appears in all copies.
//
// Tandem, a division of Compaq, MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT
// THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. Tandem, a division of Compaq, SHALL
// NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
// -------------------------------------------------------------------------

#include "stock.h"
#include 

Stock_impl::Stock_impl()
{
  CountOfStocks = 5;
  StockList[0].Symbol = "MOB";
  StockList[0].Last   = 70.5;
  StockList[0].High   = 70.5;
  StockList[0].Low    = 69.1875;
  StockList[0].Volume = 1462200;
  StockList[1].Symbol = "IBM";
  StockList[1].Last   = 102.875;
  StockList[1].High   = 103.1875;
  StockList[1].Low    = 101.5625;
  StockList[1].Volume = 2810700;
  StockList[2].Symbol = "CPQ";
  StockList[2].Last   = 35.5;
  StockList[2].High   = 35.8125;
  StockList[2].Low    = 34.3875;
  StockList[2].Volume = 18285500;
  StockList[3].Symbol = "MSFT";
  StockList[3].Last   = 158.375;
  StockList[3].High   = 158.9375;
  StockList[3].Low    = 156.0625;
  StockList[3].Volume = 8613000;
  StockList[4].Symbol = "XON";
  StockList[4].Last   = 62.25;
  StockList[4].High   = 62.625;
  StockList[4].Low    = 61.875;
  StockList[4].Volume = 1308200;
}

// Given a stock symbol, return a stock quote
void Stock_impl::quote(const char* Symbol,
		       CORBA::Double_out Last,
		       CORBA::Double_out High,
		       CORBA::Double_out Low,
		       CORBA::ULong_out Volume, 
		       CORBA::Environment &pr_env)
{
  // Search for the given stock symbol
  for (unsigned int i=0; i < CountOfStocks; i++)
    {
      if (!strcmp(Symbol, StockList[i].Symbol))
	{ // Found the stock symbol in list of stocks.
	  // Return the stock information.
	  Last = StockList[i].Last;
	  High = StockList[i].High;
	  Low = StockList[i].Low;
	  Volume = StockList[i].Volume;
	  cout << "Returning quote information" << endl;
	  return;
	}
    }

  // Could not find the stock symbol, inform caller via exception
  pr_env.exception(new Stock::operationFailed(NOT_FOUND));
}

// Given a stock simple, update the price and volume
void Stock_impl::update(const char* Symbol,
			CORBA::Double Price,
			CORBA::ULong Volume, 
			CORBA::Environment &pr_env)
{
  // Search for the given stock symbol
  for (unsigned int i=0; i < CountOfStocks; i++)
    {
      if (!strcmp(Symbol, StockList[i].Symbol))
	{ // Found the stock symbol in list of stocks.
	  // Update the stored information
	  if (Price > StockList[i].High) StockList[i].High = Price;
	  else if (Price < StockList[i].Low) StockList[i].Low = Price;
	  StockList[i].Last = Price;
	  StockList[i].Volume += Volume;
	}
    }

  // Could not find the stock symbol, inform caller via exception
  pr_env.exception(new Stock::operationFailed(NOT_FOUND));
}

Stock Header File

Contents of stock.h
// Copyright (C) 1998, Tandem Computers Incorporated.
// All Rights Reserved.
//
// Permission to use, copy, modify, and distribute this software and its
// documentation for NON-COMMERCIAL purposes and without fee is hereby
// granted provided that this copyright notice appears in all copies.
//
// Tandem, a division of Compaq, MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT
// THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. Tandem, a division of Compaq, SHALL
// NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
// -------------------------------------------------------------------------

#include "stock_server.h"

class Stock_impl: public POA_Stock
{
public: 
  Stock_impl();
  ~Stock_impl(){}

  void quote(const char* Symbol,
	     CORBA::Double_out Last,
	     CORBA::Double_out High,
	     CORBA::Double_out Low,
	     CORBA::ULong_out Volume, 
	     CORBA::Environment &pr_env);

  void update(const char* Symbol,
	      CORBA::Double Price,
	      CORBA::ULong Volume, 
	      CORBA::Environment &pr_env);

private:
  enum {MaxStocks=20};
  struct StockInfo
    {
      char * Symbol;
      CORBA::Double Last;
      CORBA::Double High;
      CORBA::Double Low;
      CORBA::ULong Volume;
    };
  CORBA::ULong CountOfStocks;
  StockInfo StockList[MaxStocks];
};

Previous Topic | Next Topic | Contents | Top
Getting Started Guide | Administration Guide | Reference Guide
Bibliography | Glossary | Index
© Tandem, a division of Compaq. All rights reserved. Legal notices.