Lab Deliverable 2 (Broker Pattern)

For this assignment, you will implement the rudiments of a basic inproc broker.  This will entail several activities.  Your final software deliverable will be a working broker that is fairly limited in terms of its immediate usefullness, but nevertheless, instructive as to the pattern's details and forces.  

The Broker pattern is by definition a distributed architecture pattern.  That is the primary reason for its existence.  However, writing even a simple broker is a non-trivial exercise.  It involves defining a common protocol for communication, implementing multiple language compilers (for idl), marshalling and demarshalling data, and above all, providing a remote messaging capability (by either building on top of an existing technology such as RPC or by writing your own from scratch using sockets).  And this is just the tip of the iceberg.  Again, not a trivial exercise.

One may nonetheless derive some benefit by implementing a simple broker as an in-proc (SINGLE process) solution.  The pattern will basically be the same, it's just that the details of remote communication are removed, and therefore much of the complexity in terms of protocol and transmission is abstracted.  

Your task is to implement the following:

A Client that talks to a ClientProxy by making calls on a common Interface
A ClientProxy that implements the common Interface and talks to a Broker
A Server that hosts a Servant object implementing the common Interface
A ServerProxy that implements the common Interface by delegating calls to the servant object's implementation
A Broker that communicates directly with the ClientProxy and the ServerProxy, by routing a CallMessage between the two
A standard CallMessage format that encapsulates the details of a given "remote" call and its return.

All of the above objects should be implemented within the same process space.  

The task of the ClientProxy is to intercept a call (say "getLength(String)") from the client, box that call up into a CallMessage object (the text of
the call, the content of the parameters, etc, typed), and then make a call on the Broker and pass it the "marshalled" CallMessage object.

The Broker in turn simply calls on the ServerProxy, essentially handing it the CallMessage object.  The ServerProxy "demarshalls" the
CallMessage object, and calls the appropriate implementation method on the Server's servant object implementation.  You may wish to incorporate the use of reflection at this point but that is not a requirement.  The Servant performs the call, and returns the return result through the ServerProxy, which "marshalls" the return into a CallMessage object, passes it through the Broker, which passes it back to the ClientProxy, which "demarshalls" the return result, and hands it back to the Client which originated the call.  The following assumptions are in play:

Everything is done inproc (within a single JVM, CLR, process, etc.)
The CallMessage class is generic enough to contain the target object reference, the name of the call to execute, the names and types of
all parameters as well as their content, etc.

To test your broker, you should define an interface that both the ClientProxy AND the ServerProxy implement.  Both implementations
will be one of delegation.  You should define two separate methods to be handled by the broker:

int addIntegers(int val1, int val2) which adds two integers together and returns an integer result

int getLength(string str) which returns the length of the string passed in

You do NOT have to define a formal Interface Definition Language (IDL) for this project.  You can assume that you can hardcode the
details of the format and protocol into the CallMessage object in lieu of a formal idl.