aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog2
-rw-r--r--build.xml14
-rw-r--r--src/After.java8
-rw-r--r--src/BindType.java5
-rw-r--r--src/Ghost.java2
-rwxr-xr-xsrc/Ivy.java25
-rwxr-xr-xsrc/IvyApplicationListener.java4
-rw-r--r--src/IvyBindListener.java6
-rwxr-xr-xsrc/IvyClient.java115
-rw-r--r--src/IvyDaemon.java15
-rwxr-xr-xsrc/IvyException.java3
-rw-r--r--src/IvyHttpGatewayClient.java6
-rw-r--r--src/IvyHttpGatewayServlet.java8
-rwxr-xr-xsrc/IvyMessageListener.java3
-rwxr-xr-xsrc/IvyWatcher.java7
-rw-r--r--src/PingCallback.java6
-rw-r--r--src/Protocol.java54
-rw-r--r--src/ProxyClient.java4
-rw-r--r--src/ProxyMaster.java4
-rw-r--r--src/Puppet.java34
-rw-r--r--src/SelfIvyClient.java5
-rw-r--r--src/Waiter.java1
-rw-r--r--src/WaiterClient.java4
23 files changed, 208 insertions, 127 deletions
diff --git a/Changelog b/Changelog
index a056b50..2ef12a6 100644
--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,8 @@
Internals:
- switched to a lot of synchronized connections, in order to avoid
concurrent modifications Exceptions I was unable to prevent so far
+ - switched to an Enum for protocol numbers. Not needed really, but
+ more java-like, and it provides better error checking.
--------------------------------------------------------------------
1.2.15
diff --git a/build.xml b/build.xml
index 0ec7c84..68558fe 100644
--- a/build.xml
+++ b/build.xml
@@ -4,8 +4,10 @@
<property name="defaultbus" value="-DIVYBUS=224.5.6.7:8910" />
<property name="src.dir" value="src"/>
+ <property name="testsrc.dir" value="tests"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
+ <property name="testclasses.dir" value="${build.dir}/testclasses"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="fr.dgac.ivy.tools.Probe"/>
<property name="lib.dir" value="lib"/>
@@ -24,13 +26,18 @@
<property name="servlet.jar" value="servlet25-api.jar "/>
<path id="classpath">
- <fileset dir="${lib.dir}" includes="**/*.jar"/>
+ <fileset dir="${jar.dir}" includes="**/*.jar"/>
<fileset dir="${jars.home}" includes="**/${servlet.jar}"/>
</path>
+ <path id="myjar">
+ <fileset dir="${jar.dir}" includes="**/*.jar"/>
+ </path>
+
<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes.dir}"/>
+ <mkdir dir="${testclasses.dir}"/>
<mkdir dir="${jar.dir}"/>
<mkdir dir="${build.dir}/doc/api"/>
</target>
@@ -43,6 +50,10 @@
<javac includeantruntime="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
</target>
+ <target name="tests" depends="jar">
+ <javac includeantruntime="true" srcdir="${testsrc.dir}" destdir="${testclasses.dir}" classpathref="myjar"/>
+ </target>
+
<target name="style">
<java fork="true" classname="com.puppycrawl.tools.checkstyle.Main">
<arg value="-c"/>
@@ -65,6 +76,7 @@
<zips><fileset dir="lib" includes="**/java-getopt-1.0.13.jar"/></zips>
</archives>
<fileset dir="." includes="README,COPYING.LIB,BUGS,Changelog"/>
+ <fileset dir="src" includes="**/*.java"/>
</jar>
</target>
diff --git a/src/After.java b/src/After.java
index 0ca78ca..7b5af07 100644
--- a/src/After.java
+++ b/src/After.java
@@ -1,5 +1,11 @@
/**
- * an utility waiting for a message to come, then exiting.
+ * an utility waiting for a message to come, then exiting
+ * the typical use is to stop a script execution flow until a message has been
+ * received in a shell script the following way
+ *
+ * echo "waiting for Toto"
+ * java -classpath ivy-java.jar fr.dgac.ivy.tools.After -b 224.5.6.7:8910 "Toto READY"
+ * echo "Toto is here, continuing".
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
diff --git a/src/BindType.java b/src/BindType.java
index 7eb1bdc..6784725 100644
--- a/src/BindType.java
+++ b/src/BindType.java
@@ -1,5 +1,8 @@
/**
- * a software bus package
+ * Ivy software bus package Enum helper utility, used to choose whether the
+ * callbacks will be performed in the same thread of the ivy protocol
+ * handling, or in the the Swing Thread, or in a newly created thread.
+ * @see Ivy.bindAsyncMsg
*
* @author Yannick Jestin <a
* href="mailto:yannick.jestin@enac.fr">yannick.jestin&enac.fr</a>
diff --git a/src/Ghost.java b/src/Ghost.java
index b96de8a..70f72af 100644
--- a/src/Ghost.java
+++ b/src/Ghost.java
@@ -1,5 +1,5 @@
/**
- * the Ghost peers on the bus ( Proxy scheme )
+ * the Ghost peers on the bus ( Proxy scheme ), not finished yet, do not use !
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
diff --git a/src/Ivy.java b/src/Ivy.java
index 2a0a6d5..6f00062 100755
--- a/src/Ivy.java
+++ b/src/Ivy.java
@@ -1,5 +1,5 @@
/**
- * a software bus package
+ * The Ivy software bus main class
*
* @author Yannick Jestin <a
* href="mailto:yannick.jestin@enac.fr">yannick.jestin&enac.fr</a>
@@ -16,6 +16,8 @@
*
* CHANGELOG:
* 1.2.16
+ * - fixes a concurent exception in the stop() method (no more
+ * removeClient , triggered in the SendNow test)
* - now uses the synchronized wrappers of the Java API for all collections
* 1.2.15
* - allows the fine tuning of the IvyClient socket buffersize using
@@ -139,12 +141,6 @@ import java.util.StringTokenizer;
public class Ivy implements Runnable {
/**
- * the protocol version number.
- */
- public static final int PROTOCOLVERSION = 3;
- public static final int PROTOCOLMINIMUM = 3;
- private static final int GRACEDELAY = 200; // in milliseconds
- /**
* the port for the UDP rendez vous, if none is supplied.
*/
public static final int DEFAULT_PORT = 2010;
@@ -165,7 +161,13 @@ public class Ivy implements Runnable {
* invoked with -DIVY_DEBUG
*/
public static final String LIBVERSION ="1.2.16";
- public static final int TIMEOUTLENGTH = 1000;
+
+ /*
+ * private fields
+ */
+ private static final int GRACEDELAY = 200; // in milliseconds, the time to wait if we want to join a bus, send a message, and quit
+ static final int TIMEOUTLENGTH = 1000;
+
private String appName;
private int applicationPort; /* Application port number */
@@ -344,7 +346,7 @@ public class Ivy implements Runnable {
} catch (IOException e) {
throw new IvyException("can't open TCP service socket " + e );
}
- traceDebug("lib: " + LIBVERSION + " protocol: " + PROTOCOLVERSION + " TCP service open on port " + applicationPort);
+ traceDebug("lib: " + LIBVERSION + " protocol: " + Protocol.PROTOCOLVERSION + " TCP service open on port " + applicationPort);
Domain[] d = parseDomains(db);
if (d.length == 0) throw new IvyException("no domain found in " + db);
@@ -353,6 +355,7 @@ public class Ivy implements Runnable {
for (Domain dom: d) watchers.addElement(new IvyWatcher(this , dom.domainaddr , dom.port));
serverThread = new Thread(this);
serverThread.setName("Ivy TCP server Thread");
+ serverThread.setDaemon(true);
serverThread.start();
// sends the broadcasts and listen to incoming connexions
for (IvyWatcher iw: watchers) iw.doStart();
@@ -421,7 +424,7 @@ public class Ivy implements Runnable {
for (IvyClient c : clients.values()) {
if (c != null) {
c.close(true);
- removeClient(c);
+ // removeClient(c); // useless ?
}
}
}
@@ -488,7 +491,7 @@ public class Ivy implements Runnable {
traceDebug("sending "+message);
String msg = message;
if (doProtectNewlines) msg = IvyClient.encode(message);
- else if ( (msg.indexOf(IvyClient.newLineChar) != -1)||(msg.indexOf(IvyClient.endArgChar) != -1))
+ else if ( (msg.indexOf(Protocol.NEWLINE) != -1)||(msg.indexOf(Protocol.ENDARG) != -1))
throw new IvyException("newline character not allowed in Ivy messages");
synchronized (clients) {
for ( IvyClient client : clients.values()) if (client != null) count += client.sendMsg(msg);
diff --git a/src/IvyApplicationListener.java b/src/IvyApplicationListener.java
index f4894bf..1f4303e 100755
--- a/src/IvyApplicationListener.java
+++ b/src/IvyApplicationListener.java
@@ -1,7 +1,6 @@
-package fr.dgac.ivy;
-
/**
* this interface specifies the methods of an ApplicationListener
+ * @see IvyApplicationAdapter
*
* @author Francois-Rzgis Colin
* @author Yannick Jestin
@@ -17,6 +16,7 @@ package fr.dgac.ivy;
* - sendDie now requires a String argument ! It is MANDATORY, and could
* impact your implementations !
*/
+package fr.dgac.ivy;
public interface IvyApplicationListener extends java.util.EventListener {
/**
diff --git a/src/IvyBindListener.java b/src/IvyBindListener.java
index 1316a8a..3ac011a 100644
--- a/src/IvyBindListener.java
+++ b/src/IvyBindListener.java
@@ -1,7 +1,6 @@
-package fr.dgac.ivy;
-
/**
- * this interface specifies the methods of a BindListener
+ * this interface specifies the methods of a BindListener; it is only useful if you want
+ * to develop a bus monitor (Ivy Probe, spy, ivymon)
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -10,6 +9,7 @@ package fr.dgac.ivy;
* 1.2.8
* - removed the public abstract modifiers, which are redundant
*/
+package fr.dgac.ivy;
public interface IvyBindListener extends java.util.EventListener {
diff --git a/src/IvyClient.java b/src/IvyClient.java
index 441013f..8e20d2d 100755
--- a/src/IvyClient.java
+++ b/src/IvyClient.java
@@ -1,5 +1,7 @@
/**
- * the peers on the bus.
+ * the local handle to a peer on the bus, a Thread is associated to each
+ * instance, performing the socket handling, the protocol parsing, and the
+ * callback running.
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -91,34 +93,17 @@ package fr.dgac.ivy ;
import java.lang.Thread;
import java.net.*;
import java.io.*;
+import java.util.SortedMap;
+import java.util.TreeMap;
import java.util.Map;
import java.util.HashMap;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;
import java.util.regex.*;
import java.util.Collection;
public class IvyClient extends Thread {
-
- /* the protocol magic numbers */
- final static int Bye = 0; /* end of the peer */
- final static int AddRegexp = 1;/* the peer adds a regexp */
- final static int Msg = 2 ; /* the peer sends a message */
- final static int Error = 3; /* error message */
- final static int DelRegexp = 4;/* the peer removes one of his regex */
- final static int EndRegexp = 5;/* no more regexp in the handshake */
- final static int SchizoToken = 6; /* avoid race condition in concurrent connexions, aka BeginRegexp in other implementations */
- final static int DirectMsg = 7;/* the peer sends a direct message */
- final static int Die = 8; /* the peer wants us to quit */
- final static int Ping = 9; // from outer space
- final static int Pong = 10;
- final static String MESSAGE_TERMINATOR = "\n"; /* the next protocol will use \r */
- final static String StartArg = "\u0002";/* begin of arguments */
- final static String EndArg = "\u0003"; /* end of arguments */
- final static String escape ="\u001A";
- final static char escapeChar = escape.charAt(0);
- final static char endArgChar = EndArg.charAt(0);
- final static char newLineChar = '\n';
// private variables
private final static int MAXPONGCALLBACKS = 10;
@@ -126,8 +111,8 @@ public class IvyClient extends Thread {
private static int pingSerial = 0;
private static final Object lock = new Object();
private static int clientSerial=0; /* an unique ID for each IvyClient */
- private Map <Integer,PingCallbackHolder>PingCallbacksTable =
- Collections.synchronizedMap(new HashMap<Integer,PingCallbackHolder>());
+ private SortedMap <Integer,PingCallbackHolder>PingCallbacksTable =
+ Collections.synchronizedSortedMap(new TreeMap<Integer,PingCallbackHolder>());
private Ivy bus;
private Socket socket;
@@ -138,6 +123,7 @@ public class IvyClient extends Thread {
private Integer clientKey;
private boolean discCallbackPerformed = false;
private String remoteHostname="unresolved";
+ private static ThreadGroup clientsThreadGroup = new ThreadGroup("Ivy clients threadgroup");
// protected variables
String appName="none";
@@ -167,7 +153,7 @@ public class IvyClient extends Thread {
}
}
remoteHostname = socket.getInetAddress().getHostName();
- clientThread = new Thread(this); // clientThread handles the incoming traffic
+ clientThread = new Thread(clientsThreadGroup, this); // clientThread handles the incoming traffic
clientThread.setName("Ivy client thread to "+remoteHostname+":"+remotePort);
}
@@ -186,10 +172,10 @@ public class IvyClient extends Thread {
traceDebug("sending our service port "+bus.getAppPort());
Map<Integer,String> tosend=bus.getSelfIvyClient().regexpsText;
synchronized (tosend) {
- sendString(SchizoToken,bus.getAppPort(),bus.getAppName());
+ sendString(Protocol.SCHIZOTOKEN,bus.getAppPort(),bus.getAppName());
for (Map.Entry<Integer,String> me : tosend.entrySet())
sendRegexp( me.getKey().intValue() , me.getValue() );
- sendString( EndRegexp,0,"");
+ sendString( Protocol.ENDREGEXP,0,"");
}
}
@@ -219,7 +205,7 @@ public class IvyClient extends Thread {
* The content is not modifyable because String are not mutable, and cannot
* be modified once they are create.
*/
- public Collection<String> getRegexps() { return regexpsText.values(); }
+ public Collection<String> getRegexps() { return new ArrayList<String>(regexpsText.values()); }
/**
* allow an Ivy package class to access the list of regexps at a
@@ -239,9 +225,9 @@ public class IvyClient extends Thread {
* @param message the string that will be match-tested
*/
public void sendDirectMsg(int id,String message) throws IvyException {
- if ( (message.indexOf(IvyClient.newLineChar)!=-1)||(message.indexOf(IvyClient.endArgChar)!=-1))
+ if ( (message.indexOf(Protocol.NEWLINE)!=-1)||(message.indexOf(Protocol.ENDARG)!=-1))
throw new IvyException("newline character not allowed in Ivy messages");
- sendString(DirectMsg,id,message);
+ sendString(Protocol.DIRECTMSG,id,message);
}
/* closes the connexion to the peer */
@@ -257,7 +243,7 @@ public class IvyClient extends Thread {
* @param message the message that will be carried
*/
public void sendDie(String message) {
- sendString(Die,0,message);
+ sendString(Protocol.DIE,0,message);
}
/**
@@ -267,7 +253,7 @@ public class IvyClient extends Thread {
*/
public void ping(PingCallback pc) throws IvyException {
PCHadd(pingSerial,pc);
- sendString(Ping,pingSerial,"");
+ sendString(Protocol.PING,pingSerial,"");
incSerial();
}
@@ -279,11 +265,11 @@ public class IvyClient extends Thread {
//
///////////////////////////////////////////////////
- static String decode(String s) { return s.replace(escapeChar,'\n'); }
- static String encode(String s) { return s.replace('\n',escapeChar); }
+ static String decode(String s) { return s.replace(Protocol.ESCAPE,'\n'); }
+ static String encode(String s) { return s.replace('\n',Protocol.ESCAPE); }
Integer getClientKey() { return clientKey ; }
- protected void sendRegexp(int id,String regexp) {sendString(AddRegexp,id,regexp);}
- protected void delRegexp(int id) {sendString(DelRegexp,id,"");}
+ protected void sendRegexp(int id,String regexp) {sendString(Protocol.ADDREGEXP,id,regexp);}
+ protected void delRegexp(int id) {sendString(Protocol.DELREGEXP,id,"");}
protected int sendMsg(String message) {
int count = 0;
@@ -293,7 +279,7 @@ public class IvyClient extends Thread {
Matcher m = regexp.matcher(message);
if (m.matches()) {
count++; // match
- sendResult(Msg,key,m);
+ sendResult(Protocol.MSG,key,m);
}
}
}
@@ -323,7 +309,8 @@ public class IvyClient extends Thread {
return (clnt.socket.getPort()-socket.getLocalPort());
}
- protected boolean equals(IvyClient clnt) {
+ //FIXME !!!! @override ? Object ?
+ protected boolean myEquals(IvyClient clnt) {
if (clnt==this) return true;
// TODO go beyond the port number ! add some host processing, cf:
// IvyWatcher ...
@@ -412,25 +399,25 @@ public class IvyClient extends Thread {
}
}
- private void sendString(int type, int id, String arg) {
+ private void sendString(Protocol type, int id, String arg) {
try {
- sendBuffer(type+" "+id+StartArg+arg);
+ sendBuffer(type.value()+" "+id+Protocol.STARTARG+arg);
} catch (IvyException ie ) {
System.err.println("received an exception: " + ie.getMessage());
ie.printStackTrace();
}
}
- private void sendResult(int type,Integer id, Matcher m) {
+ private void sendResult(Protocol type,Integer id, Matcher m) {
try {
StringBuffer buffer = new StringBuffer();
- buffer.append(type);
+ buffer.append(type.value());
buffer.append(" ");
buffer.append(id);
- buffer.append(StartArg);
+ buffer.append(Protocol.STARTARG);
for(int i=1;i<=m.groupCount();i++){
buffer.append(m.group(i));
- buffer.append(EndArg);
+ buffer.append(Protocol.ENDARG);
}
sendBuffer(buffer.toString());
} catch (IvyException ie ) {
@@ -472,7 +459,8 @@ public class IvyClient extends Thread {
protected boolean newParseMsg(String s) throws IvyException {
if (s==null) throw new IvyException("null string to parse in protocol");
byte[] b = s.getBytes();
- int from=0,to=0,msgType;
+ int from=0,to=0;
+ Protocol msgType;
Integer msgId;
while ((to<b.length)&&(b[to]!=' ')) to++;
// return false au lieu de throw
@@ -480,12 +468,7 @@ public class IvyClient extends Thread {
System.out.println("Ivy protocol error from "+appName);
return false;
}
- try {
- msgType = Integer.parseInt(s.substring(from,to));
- } catch (NumberFormatException nfe) {
- System.out.println("Ivy protocol error on msgType from "+appName);
- return false;
- }
+ msgType = Protocol.fromString(s.substring(from,to));
from=to+1;
while ((to<b.length)&&(b[to]!=2)) to++;
if (to>=b.length) {
@@ -500,7 +483,7 @@ public class IvyClient extends Thread {
}
from=to+1;
switch (msgType) {
- case Die:
+ case DIE:
traceDebug("received die Message from " + appName);
// first, I'm not a first class IvyClient any more
bus.removeClient(this);
@@ -515,7 +498,7 @@ public class IvyClient extends Thread {
throw new IvyException(ioe.getMessage());
}
break;
- case Bye:
+ case BYE:
// the peer quits
traceDebug("received bye Message from "+appName);
// first, I'm not a first class IvyClient any more
@@ -529,13 +512,13 @@ public class IvyClient extends Thread {
throw new IvyException(ioe.getMessage());
}
break;
- case Pong:
+ case PONG:
PCHget(msgId);
break;
- case Ping:
- sendString(Pong,msgId.intValue(),"");
+ case PING:
+ sendString(Protocol.PONG,msgId.intValue(),"");
break;
- case AddRegexp:
+ case ADDREGEXP:
String regexp=s.substring(from,b.length);
if ( bus.checkRegexp(regexp) ) {
try {
@@ -545,7 +528,7 @@ public class IvyClient extends Thread {
} catch (PatternSyntaxException e) {
// the remote client sent an invalid regexp !
traceDebug("invalid regexp sent by " +appName+" ("+regexp+"), I will ignore this regexp");
- sendBuffer(Error+e.toString());
+ sendBuffer(Protocol.ERROR.value()+" "+e.toString());
}
} else {
// throw new IvyException("regexp Warning exp='"+regexp+"' can't match removing from "+appName);
@@ -553,17 +536,17 @@ public class IvyClient extends Thread {
bus.regexpReceived(this,msgId.intValue(),regexp);
}
break;
- case DelRegexp:
+ case DELREGEXP:
regexps.remove(msgId);
String text=(String)regexpsText.remove(msgId);
bus.regexpDeleted(this,msgId.intValue(),text);
break;
- case EndRegexp:
+ case ENDREGEXP:
bus.clientConnects(this);
String srm = bus.getReadyMessage();
if (srm!=null) sendMsg(srm);
break;
- case Msg:
+ case MSG:
Vector <String>v = new Vector<String>();
while (to<b.length) {
while ( (to<b.length) && (b[to]!=3) ) to++;
@@ -580,11 +563,11 @@ public class IvyClient extends Thread {
traceDebug(tab);
bus.getSelfIvyClient().callCallback(this,msgId,tab);
break;
- case Error:
+ case ERROR:
String error=s.substring(from,b.length);
traceDebug("Error msg "+msgId+" "+error);
break;
- case SchizoToken: // aka BeginRegexp in other implementations, or MsgSync
+ case SCHIZOTOKEN: // aka BeginRegexp in other implementations, or MsgSync
appName=s.substring(from,b.length);
remotePort=msgId.intValue();
traceDebug("the peer sent his service port: "+remotePort);
@@ -605,7 +588,7 @@ public class IvyClient extends Thread {
bus.handShake(this);
}
break;
- case DirectMsg:
+ case DIRECTMSG:
String direct=s.substring(from,b.length);
bus.directMessage( this, msgId.intValue(), direct );
break;
@@ -617,7 +600,7 @@ public class IvyClient extends Thread {
}
//private void sendBye() {sendString(Bye,0,"");}
- private void sendBye(String message) {sendString(Bye,0,message);}
+ private void sendBye(String message) {sendString(Protocol.BYE,0,message);}
private void traceDebug(String s){
String app="noname";
@@ -648,8 +631,8 @@ public class IvyClient extends Thread {
// more than MAXPONGCALLBACKS callbacks, we ought to limit to prevent a
// memory leak
// TODO remove the first
- Integer smallest=(Integer)new java.util.TreeSet<Integer>(PingCallbacksTable.keySet()).first();
- PingCallbackHolder pch = (PingCallbackHolder)PingCallbacksTable.remove(smallest);
+ Integer smallest=PingCallbacksTable.firstKey();
+ PingCallbackHolder pch = PingCallbacksTable.remove(smallest);
System.err.println("no response from "+getApplicationName()+" to ping "+smallest+" after "+pch.age()+" ms, discarding");
}
}
diff --git a/src/IvyDaemon.java b/src/IvyDaemon.java
index 2c0e42a..6fc884d 100644
--- a/src/IvyDaemon.java
+++ b/src/IvyDaemon.java
@@ -1,5 +1,6 @@
/**
- * IvyDaemon: simple TCP to Ivy relay.
+ * IvyDaemon: simple TCP to Ivy relay, can be useful if a shell command wants
+ * to send a message on the bus.
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -20,7 +21,7 @@
* - goes into tools subpackage
* 1.2.3
* - adds the traceDebug
- * - uses the clientThread paradigm to programm the thread sync
+ * - uses the daemonThread paradigm to programm the thread sync
* - invalid port number as a command line argument now stops the program
* - cleans up the code
* - adds a "quiet" option on the command line
@@ -41,7 +42,7 @@ public class IvyDaemon implements Runnable {
private ServerSocket serviceSocket;
private static boolean debug = (System.getProperty("IVY_DEBUG")!=null) ;
- private volatile Thread clientThread;// volatile to ensure the quick communication
+ private volatile Thread daemonThread;// volatile to ensure the quick communication
private Ivy bus;
public static final int DEFAULT_SERVICE_PORT = 3456 ;
@@ -94,12 +95,12 @@ public class IvyDaemon implements Runnable {
public IvyDaemon(Ivy bus,int servicePort) throws IOException {
this.bus=bus;
serviceSocket = new ServerSocket(servicePort) ;
- clientThread=new Thread(this);
- clientThread.setName("Ivy client thread set by Daemon ?! ");
+ daemonThread=new Thread(this);
+ daemonThread.setName("Ivy Daemon tool thread");
}
protected void doStart() {
- clientThread.start();
+ daemonThread.start();
}
/*
@@ -109,7 +110,7 @@ public class IvyDaemon implements Runnable {
public void run() {
Thread thisThread = Thread.currentThread();
traceDebug("Thread started");
- while ( clientThread==thisThread ) {
+ while ( daemonThread==thisThread ) {
try {
new SubReader(serviceSocket.accept());
} catch( IOException e ) {
diff --git a/src/IvyException.java b/src/IvyException.java
index 46c872f..780f156 100755
--- a/src/IvyException.java
+++ b/src/IvyException.java
@@ -1,5 +1,3 @@
-package fr.dgac.ivy;
-
/**
* signals that an unrecoverrable Ivy exception has occured.
*
@@ -12,6 +10,7 @@ package fr.dgac.ivy;
* added a serialVersionUID to be compatible with jdk1.5
* 1.0.12 changed default access constructor to public access
*/
+package fr.dgac.ivy;
public class IvyException extends Exception {
static final long serialVersionUID=1L;
diff --git a/src/IvyHttpGatewayClient.java b/src/IvyHttpGatewayClient.java
index 5c602d3..9018a4a 100644
--- a/src/IvyHttpGatewayClient.java
+++ b/src/IvyHttpGatewayClient.java
@@ -1,5 +1,9 @@
-/*
+/**
+ *
+ * a helper class for Ivy Web Services
+ *
* IvyHttpGatewayClient.java
+ * @author Francis Jambon, IMAG
*/
package fr.dgac.ivy.tools;
diff --git a/src/IvyHttpGatewayServlet.java b/src/IvyHttpGatewayServlet.java
index fd22bd2..9df187b 100644
--- a/src/IvyHttpGatewayServlet.java
+++ b/src/IvyHttpGatewayServlet.java
@@ -1,5 +1,7 @@
-/*
- * IvyHttpGatewayServlet.java
+/**
+ * a helper class for Ivy Web Services
+ *
+ * @author Francis Jambon
*/
package fr.dgac.ivy.tools;
@@ -536,7 +538,7 @@ public class IvyHttpGatewayServlet extends HttpServlet {
public String getDomain() { return this.domain; }
- public boolean equals(Object o) {
+ @Override public boolean equals(Object o) {
if (o!=null && o instanceof IvyHashKey) {
IvyHashKey ihk = (IvyHashKey)o;
return (this.from.equals(ihk.from) &&
diff --git a/src/IvyMessageListener.java b/src/IvyMessageListener.java
index de722d5..1ed9c94 100755
--- a/src/IvyMessageListener.java
+++ b/src/IvyMessageListener.java
@@ -1,5 +1,3 @@
-package fr.dgac.ivy;
-
/**
* this interface specifies the methods of an IvyMessageListener
*
@@ -8,6 +6,7 @@ package fr.dgac.ivy;
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
*/
+package fr.dgac.ivy;
public interface IvyMessageListener extends java.util.EventListener
{
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java
index cbd3910..f6507bb 100755
--- a/src/IvyWatcher.java
+++ b/src/IvyWatcher.java
@@ -116,6 +116,7 @@ class IvyWatcher extends Thread {
busWatcherId=bus.getWatcherId();
listenThread = new Thread(this);
listenThread.setName("Ivy Watcher thread for "+domainaddr+":"+port);
+ listenThread.setDaemon(true);
// create the MulticastSocket
try {
group = InetAddress.getByName(domainaddr);
@@ -156,10 +157,10 @@ class IvyWatcher extends Thread {
continue;
}
int version = Integer.parseInt(m.group(1));
- if ( version < Ivy.PROTOCOLMINIMUM ) {
+ if ( version < Protocol.PROTOCOLMINIMUM ) {
System.err.println("Ignoring bad format broadcast from "+
remotehostname+":"+packet.getPort()
- +" protocol version "+remotehost+" we need "+Ivy.PROTOCOLMINIMUM+" minimum");
+ +" protocol version "+remotehost+" we need "+Protocol.PROTOCOLMINIMUM+" minimum");
continue;
}
remotePort = Integer.parseInt(m.group(2));
@@ -291,7 +292,7 @@ class IvyWatcher extends Thread {
synchronized void doStart() throws IvyException {
// String hello = Ivy.PROTOCOLVERSION + " " + bus.getAppPort() + "\n";
- String hello = Ivy.PROTOCOLVERSION + " " + bus.getAppPort() + " "+busWatcherId+" "+bus.getSelfIvyClient().getApplicationName()+"\n";
+ String hello = Protocol.PROTOCOLVERSION + " " + bus.getAppPort() + " "+busWatcherId+" "+bus.getSelfIvyClient().getApplicationName()+"\n";
if (broadcast==null) throw new IvyException("IvyWatcher PacketSender null broadcast address");
new PacketSender(hello,bus); // notifies our arrival on each domain: protocol version + port
listenThread.start();
diff --git a/src/PingCallback.java b/src/PingCallback.java
index ff3233b..5ba6ac0 100644
--- a/src/PingCallback.java
+++ b/src/PingCallback.java
@@ -1,14 +1,16 @@
-package fr.dgac.ivy;
-
/**
* this interface specifies the methods of an PingCallback
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
+ * helps the probe utility to measure the time af a ping roundtrip to a remote
+ * agent.
+ *
* Changelog:
* 1.2.12
*/
+package fr.dgac.ivy;
public interface PingCallback {
/**
diff --git a/src/Protocol.java b/src/Protocol.java
new file mode 100644
index 0000000..a643e39
--- /dev/null
+++ b/src/Protocol.java
@@ -0,0 +1,54 @@
+/**
+ * the Protocol magic numbers and chars
+ * @author Yannick Jestin
+ * @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
+ *
+ * CHANGELOG:
+ * 1.2.16
+ * introduced to remove the int enum pattern
+ */
+
+package fr.dgac.ivy;
+
+enum Protocol {
+
+ BYE(0), /* end of the peer */
+ ADDREGEXP(1), /* the peer adds a regexp */
+ MSG(2), /* the peer sends a message */
+ ERROR(3), /* error message */
+ DELREGEXP(4), /* the peer removes one of his regex */
+ ENDREGEXP(5), /* no more regexp in the handshake */
+ SCHIZOTOKEN(6), /* avoid race condition in concurrent connexions, aka BeginRegexp in other implementations */
+ DIRECTMSG(7), /* the peer sends a direct message */
+ DIE(8), /* the peer wants us to quit */
+ PING(9),
+ PONG(10);
+
+ final static char STARTARG = '\u0002';/* begin of arguments */
+ final static char ENDARG = '\u0003'; /* end of arguments */
+ final static char ESCAPE = '\u001A';
+ final static char NEWLINE = '\n';
+ final static int PROTOCOLVERSION = 3 ;
+ final static int PROTOCOLMINIMUM = 3 ;
+ final static int MI = 3 ;
+
+ private int value = -1;
+ private Protocol(int v) {this.value = v;}
+
+ int value() {return value;}
+
+ static Protocol fromString(String s) throws IvyException {
+ try {
+ return fromInt(Integer.parseInt(s));
+ } catch (NumberFormatException nfe) {
+ throw new IvyException("protocol problem: "+s+" is not a valid integer");
+ }
+ }
+
+ static Protocol fromInt(int i) throws IvyException {
+ for (Protocol p : Protocol.values())
+ if (p.value() == i) return p;
+ throw new IvyException("protocol magic number "+i+" not known");
+ }
+
+}
diff --git a/src/ProxyClient.java b/src/ProxyClient.java
index 431cfc5..1fd7b75 100644
--- a/src/ProxyClient.java
+++ b/src/ProxyClient.java
@@ -1,5 +1,5 @@
/**
- * ProxyClient: Ivy relay, first attempt
+ * ProxyClient: Ivy relay, first attempt, still in beta stage DO NOT USE
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -25,7 +25,7 @@ import java.util.* ;
import gnu.getopt.Getopt;
import java.util.regex.*;
-public class ProxyClient extends Ivy {
+class ProxyClient extends Ivy {
private Socket clientSocket;
private PrintWriter out;
diff --git a/src/ProxyMaster.java b/src/ProxyMaster.java
index 65d8c7f..9d40ebb 100644
--- a/src/ProxyMaster.java
+++ b/src/ProxyMaster.java
@@ -1,5 +1,5 @@
/**
- * ProxyMaster: Ivy relay, first attempt
+ * ProxyMaster: Ivy relay, first attempt, DO NOT USE
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -23,7 +23,7 @@ import java.util.* ;
import gnu.getopt.Getopt;
import java.util.regex.*;
-public class ProxyMaster {
+class ProxyMaster {
private ServerSocket serviceSocket;
private static boolean debug=false;
diff --git a/src/Puppet.java b/src/Puppet.java
index 17844ea..c307e01 100644
--- a/src/Puppet.java
+++ b/src/Puppet.java
@@ -1,5 +1,5 @@
/**
- * Part of a Ivy-level proxy
+ * Part of a Ivy-level proxy, still in development, DO NOT USE
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
@@ -7,6 +7,8 @@
* (c) CENA 1998-2004
*
* CHANGELOG:
+ * 1.2.16
+ * uses Protocol enum
* 1.2.14
* - switch from gnu regexp (deprecated) to the built in java regexp
* - add generic types to declarations
@@ -49,13 +51,13 @@ class Puppet {
bound.put(ghostId,localId);
}
public void receive(IvyClient ic,String args[]) {
- StringBuffer tosend = new StringBuffer(IvyClient.Msg);
+ StringBuffer tosend = new StringBuffer(Protocol.MSG.value());
tosend.append(" ");
tosend.append(ghostId);
- tosend.append(IvyClient.StartArg);
+ tosend.append(Protocol.STARTARG);
for (int i=0;i<args.length;i++) {
tosend.append(args[i]);
- tosend.append(IvyClient.EndArg);
+ tosend.append(Protocol.ENDARG);
}
sendGhost(tosend.toString());
}
@@ -94,30 +96,30 @@ class Puppet {
void parse(String s) throws IvyException {
Matcher m;
if (!(m=ivyProto.matcher(s)).matches()) { System.out.println("Puppet error, can't parse "+s); return; }
- int pcode=Integer.parseInt(m.group(1));
+ Protocol pcode=Protocol.fromString(m.group(1));
String pid=m.group(2);
String args=m.group(3);
trace("must parse code:"+pcode+" id:"+pid+" args:"+args);
switch (pcode) {
- case IvyClient.AddRegexp: // the Ghost's peer subscribes to something
+ case ADDREGEXP: // the Ghost's peer subscribes to something
addRegexp(pid,args);
break;
- case IvyClient.DelRegexp: // the Ghost's peer unsubscribes to something
+ case DELREGEXP: // the Ghost's peer unsubscribes to something
removeRegexp(pid);
break;
- case IvyClient.Bye: // the Ghost's peer disconnects gracefully
+ case BYE: // the Ghost's peer disconnects gracefully
bus.stop();
// TODO end of the puppet ?
break;
- case IvyClient.Die:
+ case DIE:
// the Ghost's peer wants to ... kill ProxyClient ?
break;
- case IvyClient.Msg:
+ case MSG:
// the Ghost's peer sends a message to ProxyClient, with regard to one
// of our subscriptions
// TODO a qui le faire passer ?
break;
- case IvyClient.SchizoToken:
+ case SCHIZOTOKEN:
appName = args;
bus = new PuppetIvy(appName,appName+" fakeready",null);
for ( String ghostId: regexps.keySet() )new ForwardMessenger(ghostId,regexps.get(ghostId));
@@ -125,11 +127,11 @@ class Puppet {
trace("starting the bus on "+domain);
bus.start(domain);
break;
- case IvyClient.Error:
- case IvyClient.EndRegexp:
- case IvyClient.DirectMsg:
- case IvyClient.Ping:
- case IvyClient.Pong:
+ case ERROR:
+ case ENDREGEXP:
+ case DIRECTMSG:
+ case PING:
+ case PONG:
default:
trace("unused Ivy protocol code "+pcode);
}
diff --git a/src/SelfIvyClient.java b/src/SelfIvyClient.java
index 1957124..b5d9996 100644
--- a/src/SelfIvyClient.java
+++ b/src/SelfIvyClient.java
@@ -1,10 +1,13 @@
/**
- * A private Class for ourself on the bus
+ * our handle for our own agent on the bus
*
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
* @since 1.2.4
*
+ * the other agents are accessed throung IvyClient
+ * @see IvyClient
+ *
* CHANGELOG:
* 1.2.16
* - now uses the synchronized wrappers of the Java API for all collections
diff --git a/src/Waiter.java b/src/Waiter.java
index 51b68fb..d625217 100644
--- a/src/Waiter.java
+++ b/src/Waiter.java
@@ -1,4 +1,5 @@
/**
+ * a helper class to implement faitForClient, Wait for Message
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
diff --git a/src/WaiterClient.java b/src/WaiterClient.java
index 007a179..f6b00b5 100644
--- a/src/WaiterClient.java
+++ b/src/WaiterClient.java
@@ -1,4 +1,8 @@
/**
+ * a helper class to implement the Ivy.waitForClient method
+ *
+ * @see Ivy.waitForClient
+ *
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*