The protocol is based on java object serialization streams using the
serialization stream format of JDKTM 1.2.
This document does not define the object serialization protocol.
The reader should refer to
http://java.sun.com/j2se/1.3/docs/guide/serialization/index.html.
Accordingly, in the description of the protocol java types will be used
as primitives.
These types should be written and read using the above mentioned java
serialization streams through a socket connection.
The objects in the stream must not be null except when it is
explicitly allowed.
A session always starts with an initiation when the protocol versions understood by the peers and the group names are exchanged and the type of the session is identified by the initiator. This is followed by the actual data exchange. In the following the initiation will be described followed by the detailed description of the different types of sessions.
The following table contains definitions of terms used throughout the document.
Client | The initiator of the communication. Only temporary role, the same application can be server too. |
---|---|
Server | The passive party that accepts communication requests. Only temporary role, the same application can be client too. |
This document contains strictly technical information, further documentation of the classes mentioned here can be found elsewhere. All constants are given in unsigned decimal format.
Client | int VERSION |
String GROUP |
byte TYPE |
- |
---|---|---|---|---|
Server | - | - | - | int ANSWER |
For this version the VERSION
value is 1.
If ANSWER
equals GROUP_MISMATCH(=-1)
then
the peer is from a different group and the communication will be closed.
Otherwise ANSWER
equals the protocol version spoken by the peer.
The following table gives the values of the known session types:
TYPE |
meaning |
---|---|
0 |
MESSAGE (message sending) |
1 |
AGENT (agent sending) |
123 |
ISALIVE (are you alive?) |
Client | - |
---|---|
Server | java.lang.String BASE-NAME |
In words: the server simply replies by sending a String object. This string contains the name of the server.
Client | Server |
---|---|
String RECIPIENT |
- |
- |
byte STATUS_1 |
drm.agentbase.Message MESSAGE |
- |
- |
byte STATUS_2 |
When the message has a reply, it looks like this:
Client | Server |
---|---|
String RECIPIENT |
- |
- |
byte STATUS_1 |
drm.agentbase.Message MESSAGE |
- |
- |
byte STATUS_2=0 |
- |
Object REPLY |
The interpretation of the status info is the following:
STATUS_1 |
meaning |
---|---|
101 |
OK: The recipient is here, send message. |
102 |
NOT_OK: The recipient is not here, don't
send message. The connection is
interrupted by the server. |
STATUS_2 |
meaning |
---|---|
101 |
OK: The message was delivered to the
recipient successfully, and the recipient does not
send a reply. |
102 |
NOT_OK: There was a problem
with delivering or handling the message. |
0 |
REPLY: The message was handled and a
reply is on the way. |
drm.agentbase.Message
is a class with serial version uid
static final long serialVersionUID = 49323201182294530L;Its serialized fields are
drm.agentbase.Address sender; drm.agentbase.Address recipient; java.lang.String type; byte[] contbin;The serial version of drm.agentbase.Address is
static final long serialVersionUID = 2145788465305611890L;Its serialized fields are
java.net.InetAddress host int port java.lang.String nameIt is also part of the low level protocol that the
host
field of
the sender
address in the message must be set to the client
side IP of the socket after deserialization.
The reason for this is that the sender entity is
not required to know its own IP address.
For this reason the sender IP must be determined on the recipient side.
drm.agentbase.IAgent
and it may need several other
classes to run.
For the API of drm.agentbase.IAgent
please refer to version 2
of the DRM (see
http://sourceforge.net/projects/dr-ea-m/).
The agent also belongs to a job that has a name.
When loading the agent the server checks if it has the class files
for running the agent using the job name. Thus the job name identifies
the resources used by the agent.
Here we can have two scenarios. In the first case the class files needed to run the agent are already at the node. In the second case they are not. The first table shows the communication in the first case.
Client | Server |
---|---|
java.lang.String JOBNAME |
- |
- |
byte STATUS=101 |
drm.agentbase.IAgent AGENT |
- |
drm.agentbase.Address SENDER_BASE |
- |
- |
byte STATUS |
JOBNAME
is the name of the job the agent is a part of.
It can be used by the server to check if the resources for the agent
are accessible locally.
This is why it is important that every job must have a unique
name (at least with a high probability) that is suitable to identify
the presence of specific optional classes.
AGENT
can be of any type but it must implement the
drm.agentbase.IAgent
interface from DRM.
The agentbase will communicate with the agent trough this interface.
Just like in the case of MESSAGE the
IP address in the addr
field
of SENDER-BASE
must be set to the client side IP of the socket by
the server.
The second table shows the communication if the class files of the agent are not at the server.
Client | Server |
---|---|
java.lang.String JOBNAME |
- |
- |
byte STATUS=100 |
int SIZE |
- |
DATA |
- |
- |
byte ACK |
drm.agentbase.IAgent AGENT |
- |
drm.agentbase.Address SENDER_BASE |
- |
- |
byte STATUS |
Everything is the same only here we also have an uploading phase
inserted.
If SIZE
is positive than DATA
contains a jar file of
SIZE
bytes. These bytes are simply written to the stream
sequentially.
If SIZE
is negative then DATA
is an object of
type java.util.File
describing an absolute directory name.
The resources of the job must be in that directory on the server.
ACK
can have any value. It indicates that the jar file has been
read.
The interpretation of the closing status report of the server is the following:
STATUS |
meaning |
---|---|
101 |
OK. The agent was successfully installed. |
102 |
NOT_OK. There was a problem with installing the
agent. |
The most problems come from the fact that we are dealing with mobile
code (agents).
There are two sides of this question: the DRM-agent and the agent-DRM
interface. In other words the agent should be able to talk to the system
and the way round.
And the versions of the agent and the DRM may not match.
(see drm.agentbase.IAgent.version()
and Base.RELEASE_VERSION
in the DRM release).
The system talks to the agent through the
drm.agentbase.IAgent
interface.
If methods are deleted from it then the old system version
will not be able to call these
methods, and if methods are added then the new system version will miss them
when talking to an old agent.
(Changing a method signature is equivalent to an addition and a removal.)
Removing methods is unlikely and also unnecessary (since they can be
given an empty implementation).
The case when we add methods can be solved by wrapping the lower version
agent into an object that propagates the old
method calls to the agent and gives default implementations to the new
ones. When sending such an agent on of course only the original wrapped
object should be sent.
The agent can use any publicly accessible part of the DRM. The problems come when an agent of a newer version goes to a base which implements an old DRM version. The agent will miss the methods that are present only in its version. There is no real solution to this beside the clear documentation of new methods and avoiding deleting old ones just like it is done in the standard java packages. Indicating that a field or method is present only from a given version will allow the developer of the agent to decide whether the agent should remain compatible. Another possibility is reflection, i.e. the agent can first check if a given method is implemented before calling it.
Of course the compatibility of the system classes w.r.t. serialization can also be maintained without great difficulties: if we only add new fields to the classes they remain compatible: this is guaranteed by the serialization stream specification.
Changes in the protocol can also be handled by later versions as the protocol itself is versioned too (see the initiation section).