diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/After.java | 8 | ||||
-rw-r--r-- | src/BindType.java | 5 | ||||
-rw-r--r-- | src/Ghost.java | 2 | ||||
-rwxr-xr-x | src/Ivy.java | 25 | ||||
-rwxr-xr-x | src/IvyApplicationListener.java | 4 | ||||
-rw-r--r-- | src/IvyBindListener.java | 6 | ||||
-rwxr-xr-x | src/IvyClient.java | 115 | ||||
-rw-r--r-- | src/IvyDaemon.java | 15 | ||||
-rwxr-xr-x | src/IvyException.java | 3 | ||||
-rw-r--r-- | src/IvyHttpGatewayClient.java | 6 | ||||
-rw-r--r-- | src/IvyHttpGatewayServlet.java | 8 | ||||
-rwxr-xr-x | src/IvyMessageListener.java | 3 | ||||
-rwxr-xr-x | src/IvyWatcher.java | 7 | ||||
-rw-r--r-- | src/PingCallback.java | 6 | ||||
-rw-r--r-- | src/Protocol.java | 54 | ||||
-rw-r--r-- | src/ProxyClient.java | 4 | ||||
-rw-r--r-- | src/ProxyMaster.java | 4 | ||||
-rw-r--r-- | src/Puppet.java | 34 | ||||
-rw-r--r-- | src/SelfIvyClient.java | 5 | ||||
-rw-r--r-- | src/Waiter.java | 1 | ||||
-rw-r--r-- | src/WaiterClient.java | 4 |
21 files changed, 193 insertions, 126 deletions
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> * |