User Manual for the FA-CORBA Infrastructure

(written by Isabelle Ravot with modifications by Diana Szentivanyi)


 0. In the home directory on the host where the infrastructure/application is running, a file called OpenORB.xml should be found. A sample OpenORB.xml file is provided with the rest of resources.

 

1.     Packets needed:

a)      Extended OpenORB distribution (OpenORB-1.2.0.zip):  contains all the modified (and extra) OpenORB core classes in a Java archive under the lib directory: openorb-1.2.0-fa.jar. The Java archive openorb-1.2.0.jar is also in lib – it contains the original OpenORB core classes. When the FA infrastructure is used, the classpath should contain the path to openorb-1.2.0-fa.jar , and not to openorb-1.2.0.jar. There is a zip file containing those OpenORB Java sources that were modified (NEW_EXT_ORB_Sources.zip). Note that OpenORB service packages (e.g. NamingService, TimeService, etc.) are not provided with this distribution. If those are needed, they should be downloaded from the OpenORB web page (http://www.exolab.org).

b)      Distribution with classes created as a result of implementing the universal construction algorithm: Classes.jar. Contains classes such as Consensus, Register , Leader, WriteMessage, ReadMessage, etc. A distribution of sources in the form Sources.zip is also available.

 

2.     Modification that the application writer should  make:

              example   replicas5.ref:
                                    mir52.ida.liu.se 1
                                    mir26.ida.liu.se 2
                                    mir13.ida.liu.se 3
                                    mir25.ida.liu.se 4
                                   mir14.ida.liu.se 5

For example:
    -the number of maximun replicas.
    -the frequence that a server sends th AmAlive messages to the others and to the client.
    -the frequence we check if a server is still alive.
    - the minmum number of request, we always have in the OutcomeStore.
    - the time after which a request doesn't need to be anymore in the OutcomeStore.
   - the size maximum of the update for the state.

 

·        When using the algorithm with pruning (this version of the algorithm is recommended to be used) this meaning that the proper interceptors are used, then the constants that give the pruning time period, or the number of requests to perform pruning after has to be changed (if wanted) in the file Utils.java. For the moment, the period is set to 5 seconds, while the number of requests is se to 20.

 

Example if your server has the 2 following method:
The method m1 :
  public void m1(int q,String s,boolean bl,org.omg.CORBA.CharHolder ch,org.omg.CORBA.DoubleHolder r,org.omg.CORBA.ShortHolder rr);
(update method)

The method m2:
  public  boolean m2(); (read-only method)


Your class MethTable should be:
public class MethTable
{
    /**
     *Array of the size of the number of method our application implement.
     *
     */
    public universal.MethSignStr methods[]=new universal.MethSignStr[2];
    /**
     * Contains the definition of each method
     */
    public MethTable(org.omg.CORBA.ORB orb)
    {
 
         //m1
         methods[0]=new universal.MethSignStr();
         methods[0].name="m1";
         methods[0].readMethod=false;
         methods[0].param_modes=new int[6];
         methods[0].param_modes[0]=org.omg.CORBA.ParameterMode._PARAM_IN;
         methods[0].param_modes[1]=org.omg.CORBA.ParameterMode._PARAM_IN;
         methods[0].param_modes[2]=org.omg.CORBA.ParameterMode._PARAM_IN;
         methods[0].param_modes[3]=org.omg.CORBA.ParameterMode._PARAM_INOUT;
         methods[0].param_modes[4]=org.omg.CORBA.ParameterMode._PARAM_OUT;
         methods[0].param_modes[5]=org.omg.CORBA.ParameterMode._PARAM_INOUT;
 
         methods[0].param_types=new org.omg.CORBA.TypeCode[6];
         methods[0].param_types[0]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long);
         methods[0].param_types[1]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_string);
         methods[0].param_types[2]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_boolean);
         methods[0].param_types[3]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_char);
         methods[0].param_types[4]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_double);
         methods[0].param_types[5]=orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_short);
         //m2
         methods[1]=new universal.MethSignStr();
         methods[1].name="m2";
         methods[1].readMethod=true:
}
 

3.     On the server side:

//Write the IOR of the server in the file
 try
      {
           String refFile = name.concat("Application.ref");
           FileOutputStream file = new FileOutputStream(refFile);
           PrintWriter out = new PrintWriter(file);

           out.println(reference);
           out.flush();
           file.close();

      }
  catch ( java.io.IOException ex )
      {
           System.out.println("File error");
      }
 
 

   rootPOA.the_POAManager().activate();
   org.openorb.CORBA.ORB orb1 =(org.openorb.CORBA.ORB)orb;
//Read the name of the file which contains the list of the name of the machines where are running the replicated servers
   java.util.Vector temp=new java.util.Vector();
  for (int i=0;i<args.length;i++)
      {
           if(!args[i].startsWith("-ORB")){
               temp.addElement(args[i]);
           }
       }
  String[] args1=new String[temp.size()];
  temp.toArray(args1);

  if(args1.length>0)
      {
           String replicasNameFile = args1[0];
           int pid=-1;
 

  //search the pid attribute to this server
   String rep=null;
   try
       {
 

            FileInputStream repFile =new FileInputStream(replicasNameFile);
            BufferedReader inRep= new BufferedReader(new InputStreamReader(repFile));
             int i =0;

    do
        {
             rep=inRep.readLine();

             if(rep!=null)
             {

                  int index=rep.lastIndexOf("");
                  String rep1=rep.substring(0,index-2);
                  String rep2=rep.substring(index-1);
                  if((rep1.compareTo(name))==0)
                  {
                       pid = Integer.valueOf(rep2).intValue();
                       break;
                  }

          i++;
         }
        }while(rep!=null);

       repFile.close();
    }
   catch(IOException ex)
       {

            System.err.println("Can't read from `" +
             ex.getMessage() + "'");
            System.exit(1);
       }
   //Instantiate the UniversalCrashStop Object
   universal.UniversalCrashStop uni = new universal.UniversalCrashStop(pid,replicasNameFile);
   // Instantiate the object that contains the description of all the method of the applilcation server.
   universal.MethTable table=new universal.MethTable(orb);

                 //Set all the features

   orb1.setFeature("universal",uni);
   orb1.setFeature("application",amImpl);
   orb1.setFeature("methsign",table);

      }
//Trace the trip of the request in the serverInterceptor
  java.io.RandomAccessFile trace_file=null;
  try
      {
      trace_file=new java.io.RandomAccessFile("non_corba_cl%%"+orb+name,"rw");
      }catch(java.lang.Exception e){trace_file=null;}
  if(trace_file!=null)
      orb1.setFeature("trace_file",trace_file);
     }catch(java.lang.Exception e){e.printStackTrace();}

 

4.     On the client side :

  try
{
      OrbInitializer.initServer (args, null);
      orb = OrbInitializer.getOrb();
//Add the trace file
     java.io.RandomAccessFile trace_file=null;
      try
     {
         trace_file=new java.io.RandomAccessFile("non_corba_cl%%"+orb,"rw");
      }catch(java.lang.Exception e){trace_file=null;}
      if(trace_file!=null)
   ((org.openorb.CORBA.ORB)orb).setFeature("trace_file",trace_file);
      ((org.openorb.CORBA.ORB)orb).setFeature("request_duration",new Integer(10000));

// Read the arguments from the command line
java.util.Vector temp=new java.util.Vector();
 for (int i=0;i<args.length;i++)
   {
       if(!args[i].startsWith("-ORB"))
      {
          System.out.println("adding an argument");
         temp.addElement(args[i]);
      }
   }
   String[] args1=new String[temp.size()];
   temp.toArray(args1);
   System.out.println("args1 length "+args1.length);
//Create objects UniversalClientCrashStop
 if(args1.length!=0)
   {
       universal.UniversalClientCrashStop unicl[]=new universal.UniversalClientCrashStop[(args1.length)];
       for (int i=0;i<args1.length;i++)
       {
          System.out.println("loop for");
          unicl[i]=new universal.UniversalClientCrashStop(args1[i]);

       }

     org.openorb.CORBA.ORB orb1 =(org.openorb.CORBA.ORB)orb;
// Set the timeout
     Long timeout =new Long(20000);
// Set the feature
     orb1.setFeature("timeout",timeout);
     orb1.setFeature("universalClient",unicl);
     orb1.setFeature("argument",args1);
    }
}
catch(Exception e)
{
   //Could not initialise the ORB
    LogAgent.trace( FwTraceType.ERR_GENERAL,
     "Exception when initializing the ORB" + e);
 }

5.     How to run the replicated application (with or without time tracing)

Set the classpath to include the path where the OpenORB classes are, as well as the path where the infratructure classes are (where you places the .jar file), and the path where your application class files are (client and server).
You should work with Java 1.4 (it could work with an earlier version as well).

If you want to run experiments in order to compare timing values in the non-replicated case with the ones in the replicated case where the algorithm is run each time a request is processed, you have to define some profiles in the OpenORB.xml file to include the right initializers that create the right interceptors. In the OpenORB.xml file there are sample profiles for the
FA-CORBA infrastructure.

 
1. You should start the server :
java -Xbootclasspath:$CLASSPATH package.of.the.server.Server -ORBProfile= jmtup

2.You should the client :
java -Xbootclasspath:$CLASSPATH package.of.the.client.Client  -ORBProfile= nrup

 

1.You should start all your replicated servers :
 java -Xbootclasspath:$CLASSPATH package.of.the.server.Server -ORBProfile=prunepp replicas5.txt (if five replicas are to be used in the group)
Where replicas5.txt is the file that contains the list of the name of the machines where are running the replicated server and their pid.
This file should be in the current directory from where the replicas are started on those machines.

2.You should start the client :
java -Xbootclasspath:$CLASSPATH package.name.of.the.client.Client -ORBProfile=prunepp replicas5.txt

 

6.     Compiling the trace files

    Use the Compiler file (SampleTraceCompiler.java contains more info about command line arguments when running java Compiler) in order to process the trace files generated when running replicated or non-replicated scenarios including time tracing operations. After running java Compiler... a set of files corresponding to the different method calls and request travel segment are generated. These files contain the set of values for the times spent on those segments.
    The files can further be parsed and processed by using ComputeStatistics. This uses utilities provided in the file Statistics. Here, utilities for computing averages and standard deviations are devised. It is possible to compute averages by removing n largest or smallest values of the value set. Of course, both the Compiler.java file and the ComputeStatistics.java file can be modified so that they are tuned to new needs.