(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);
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.