diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/Ivy.java | 66 | ||||
-rwxr-xr-x | src/IvyClient.java | 5 | ||||
-rwxr-xr-x | src/IvyWatcher.java | 13 | ||||
-rw-r--r-- | src/Probe.java | 57 |
4 files changed, 114 insertions, 27 deletions
diff --git a/src/Ivy.java b/src/Ivy.java index 15926bc..5e149ec 100755 --- a/src/Ivy.java +++ b/src/Ivy.java @@ -22,7 +22,12 @@ import java.util.*; *</pre> * * CHANGELOG: - * 1.0.12: + * 1.2.1: + * - bus.start(null) now starts on DEFAULT_DOMAIN + * - added the getDomains in order to correctly display the domain list + * - checks if the serverThread exists before interrupting it + * - no has unBindMsg(String) + * 1.2.0: * - setSoTimeout is back on the server socket * - added a regression test main() * - clients is now a Hashtable. the deletion now works better @@ -55,7 +60,7 @@ public class Ivy implements Runnable { * the library version, useful for development purposes only, when java is * invoked with -DIVY_DEBUG */ - public static final String libVersion ="1.2.0"; + public static final String libVersion ="1.2.1"; private boolean debug; private static int serial=0; /* an unique ID for each regexp */ @@ -107,6 +112,7 @@ public class Ivy implements Runnable { * */ public void start(String domainbus) throws IvyException { + if (domainbus==null) domainbus=DEFAULT_DOMAIN; try { app = new ServerSocket(0); app.setSoTimeout(TIMEOUTLENGTH); @@ -117,13 +123,10 @@ public class Ivy implements Runnable { traceDebug("lib: "+libVersion+" protocol: "+PROCOCOLVERSION+" TCP service open on port "+applicationPort); watchers = new Vector(); + Domain[] d = parseDomains(domainbus); // readies the rendezvous : an IvyWatcher (thread) per domain bus - StringTokenizer st = new StringTokenizer(domainbus,","); - while ( st.hasMoreTokens()) { - String s = st.nextToken() ; - String domainaddr=IvyWatcher.getDomain(s); - int port=IvyWatcher.getPort(s); - IvyWatcher watcher =new IvyWatcher(this,domainaddr,port); + for (int index=0;index<d.length;index++){ + IvyWatcher watcher =new IvyWatcher(this,d[index].domainaddr,d[index].port); watchers.addElement(watcher); } serverThread = new Thread(this); @@ -132,6 +135,17 @@ public class Ivy implements Runnable { for (int i=0;i<watchers.size();i++){ ((IvyWatcher)watchers.elementAt(i)).start(); } } + public Domain[] parseDomains(String domainbus) { + StringTokenizer st = new StringTokenizer(domainbus,","); + Domain[] d = new Domain[st.countTokens()]; + int index=0; + while ( st.hasMoreTokens()) { + String s = st.nextToken() ; + d[index++]=new Domain(IvyWatcher.getDomain(s),IvyWatcher.getPort(s)); + } + return d; + } + /** * disconnects from the Ivy bus */ @@ -142,7 +156,7 @@ public class Ivy implements Runnable { // stopping the serverThread Thread t=serverThread; serverThread=null; - t.interrupt(); + if (t!=null) t.interrupt(); // The serverThread might be stopped even before having been created app.close(); // stopping the IvyWatchers for (int i=0;i<watchers.size();i++){ ((IvyWatcher)watchers.elementAt(i)).stop(); } @@ -234,6 +248,28 @@ public class Ivy implements Runnable { } /** + * unsubscribes a regular expression + * + * @return a boolean, true if the regexp existed, false otherwise or + * whenever an exception occured during unbinding + * @param String the string for the regular expression + */ + public boolean unBindMsg(String re) { + for (Enumeration e=regexp_out.keys();e.hasMoreElements();) { + Integer k = (Integer)e.nextElement(); + if ( ((String)regexp_out.get(k)).compareTo(re) == 0) { + try { + unBindMsg(k.intValue()); + } catch (IvyException ie) { + return false; + } + return true; + } + } + return false; + } + + /** * adds an application listener to a bus * @param callback is an object implementing the IvyApplicationListener * interface @@ -425,13 +461,23 @@ public class Ivy implements Runnable { return s; } + class Domain { + private String domainaddr; + private int port; + public Domain(String domainaddr,int port) {this.domainaddr=domainaddr;this.port=port;} + public String toString() {return domainaddr+":"+port;} + public String getDomainaddr() { return domainaddr; } + public int getPort() { return port; } + } + + /* * unitary test. Normally, running java fr.dgac.ivy.Ivy should stop in 2.3 seconds :) */ public static void main(String[] args) { Ivy bus = new Ivy("Test Unitaire","TU ready",null); try { - bus.start(DEFAULT_DOMAIN); + bus.start(null); try { Thread.sleep(2000); } catch (InterruptedException ie) { } bus.stop(); } catch (IvyException ie) { diff --git a/src/IvyClient.java b/src/IvyClient.java index 3857631..d98bb0f 100755 --- a/src/IvyClient.java +++ b/src/IvyClient.java @@ -19,6 +19,9 @@ import gnu.regexp.*; * created for each remote client. * * CHANGELOG: + * 1.2.1: + * - removes a NullPointerException when stops pinging on a pinger that + * wasn't even started * 1.0.12: * - introducing a Ping and Pong in the protocol, in order to detect the loss of * connection faster. Enabled through the use of -DIVY_PING variable only @@ -152,7 +155,7 @@ public class IvyClient implements Runnable { */ void close(boolean notify) throws IOException { traceDebug("closing connexion to "+appName); - if (doping) { pinger.stopPinging(); } + if (doping&&(pinger!=null)) { pinger.stopPinging(); } if (notify) sendBye("hasta la vista"); stopListening(); // bus.clientDisconnect(this); diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java index 004c704..d64b0d6 100755 --- a/src/IvyWatcher.java +++ b/src/IvyWatcher.java @@ -22,6 +22,11 @@ import java.util.Enumeration; * thing. * * CHANGELOG: + * 1.2.1: + * - changed the fill character from 0 to 10, in order to prevent a nasty bug + * on Windows XP machines + * - fixed a NullPointerException while trying to stop a Thread before having + * created it. * 1.0.12: * - setSoTimeout on socket * - the broadcast reader Thread goes volatile @@ -82,7 +87,9 @@ class IvyWatcher implements Runnable { try { broadcast.receive(packet); String msg = new String(packet.getData()) ; - for (int i=0;i<buf.length;i++) { buf[i]=0; } // clean up the buffer after each message + for (int i=0;i<buf.length;i++) { buf[i]=10; } + // clean up the buffer after each message + // BUGFIX ? I change 0 to 10 in order to avoid a bug InetAddress remotehost = packet.getAddress(); traceDebug("BUSWATCHER Receive Broadcast from "+ remotehost.getHostName()+":"+packet.getPort()); // TODO if ( !isInDomain( remotehost ) ) continue; @@ -135,7 +142,7 @@ class IvyWatcher implements Runnable { Thread t = listenThread; listenThread=null; broadcast.close(); - t.interrupt(); + if (t!=null) { t.interrupt(); } // it might not even have been created traceDebug("ending stopping an IvyWatcher"); } @@ -185,7 +192,7 @@ class IvyWatcher implements Runnable { System.out.println("Bad broascat addr " + net); return null; } - //System.out.println("net: "+net); + // System.out.println("net: "+net); return net; } diff --git a/src/Probe.java b/src/Probe.java index a0a2ed0..c72c2ad 100644 --- a/src/Probe.java +++ b/src/Probe.java @@ -5,14 +5,16 @@ import gnu.getopt.Getopt; /** * terminal implementation in java of the ivyprobe. - * For a graphical version, see TestIvySwing - * @see fr.dgac.ivy.TestIvySwing * @author Yannick Jestin * @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a> * * * Changelog: - * 1.0.12 + * 1.2.1 + * - new -t switch to print the date for each ivy message + * - now displays the correct domain list + * - now has .bind and .unbind commands + * 1.2.0 * - Probe can now send empty strings on keyboard input * - rewritten with a looping thread on stdin to allow a cleaner exit on die * message : not very good @@ -29,12 +31,13 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { /** * help message for the standalone program */ - public static final String helpCommands = "Available commands:\n.die CLIENTNAME sends a die message\n.bye quits the application\n.quit idem\n.list lists the available clients\n.ping sends a ping request if IVY_PING is enabled"; - public static final String helpmsg = "usage: java fr.dgac.ivy.Probe [options] [regexp]\n\t-b BUS\tspecifies the Ivy bus domain\n\t-n ivyname (default JPROBE)\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-h\thelp\n\n\t regexp is a Perl5 compatible regular expression"; + public static final String helpCommands = "Available commands:\n.die CLIENTNAME sends a die message\n.bye quits the application\n.quit idem\n.list lists the available clients\n.ping sends a ping request if IVY_PING is enabled\n.bind REGEXP binds to a regexp at runtime\n.unbind REGEXP unbinds to a regexp at runtime"; + public static final String helpmsg = "usage: java fr.dgac.ivy.Probe [options] [regexp]\n\t-b BUS\tspecifies the Ivy bus domain\n\t-n ivyname (default JPROBE)\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-t\ttime stamp each message\n\t-h\thelp\n\n\t regexp is a Perl5 compatible regular expression"; public static void main(String[] args) throws IvyException { - Getopt opt = new Getopt("Probe",args,"n:b:dh"); + Getopt opt = new Getopt("Probe",args,"n:b:dht"); int c; + boolean timestamp=false; String domain=Ivy.getDomain(null); String name="JPROBE"; while ((c = opt.getopt()) != -1) switch (c) { @@ -44,6 +47,9 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { case 'n': name=opt.getOptarg(); break; + case 't': + timestamp=true; + break; case 'd': System.setProperty("IVY_DEBUG","yes"); break; @@ -52,13 +58,18 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { System.out.println(helpmsg); System.exit(0); } // getopt - Probe p = new Probe(); + Probe p = new Probe(timestamp); Ivy bus=new Ivy(name,name+" ready",p); for (int i=opt.getOptind();i<args.length;i++) { System.out.println("you want to subscribe to " + args[i]); bus.bindMsg(args[i],p); } - System.out.println("broadcasting on "+domain); + String s = "broadcasting on "; + Ivy.Domain[] d = bus.parseDomains(domain); + for (int index=0;index<d.length;index++) { + s+=d[index].getDomainaddr()+":"+d[index].getPort()+" "; + } + System.out.println(s); bus.start(domain); p.start(bus); } @@ -66,10 +77,12 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { private BufferedReader in; private volatile Thread looperThread; private Ivy bus; + private boolean timestamp; - Probe() { + Probe(boolean timestamp) { in = new BufferedReader(new InputStreamReader(System.in)); looperThread=new Thread(this); + this.timestamp=timestamp; } public void start(Ivy bus) { @@ -105,7 +118,7 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { // crude parsing of the ".xyz" commands // TODO use regexps instends of String.lastIndexOf(String) if (s.length()==0) { - System.out.println("-> Sent to " +bus.sendMsg(s)+" peers"); + System.out.println(date()+"-> Sent to " +bus.sendMsg(s)+" peers"); } else if (s.lastIndexOf(".die ")>=0){ String target=s.substring(5); Vector v=bus.getIvyClientsByName(target); @@ -115,6 +128,17 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { for (int i=0;i<v.size();i++) { ((IvyClient)v.elementAt(i)).sendDie(); } + } else if (s.lastIndexOf(".unbind ")>=0){ + String regexp=s.substring(8); + if (bus.unBindMsg(regexp)) { + System.out.println("you want to unsubscribe to " + regexp); + } else { + System.out.println("you can't unsubscribe to " + regexp + ", your're not subscribed to it"); + } + } else if (s.lastIndexOf(".bind ")>=0){ + String regexp=s.substring(6); + System.out.println("you want to subscribe to " + regexp); + bus.bindMsg(regexp,this); } else if (s.lastIndexOf(".ping ")>=0){ String target=s.substring(6); Vector v=bus.getIvyClientsByName(target); @@ -131,7 +155,7 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { Vector v = bus.getIvyClients(); System.out.println(v.size()+" clients on the bus"); for (int i=0;i<v.size();i++) { - System.out.println(" -> "+((IvyClient)v.elementAt(i)).getApplicationName()); + System.out.println("-> "+((IvyClient)v.elementAt(i)).getApplicationName()); } } else if ( s.lastIndexOf(".help")>=0) { System.out.println(helpCommands); @@ -139,7 +163,7 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { System.out.println("this command is not recognized"); System.out.println(helpCommands); } else { - System.out.println("-> Sent to " +bus.sendMsg(s)+" peers"); + System.out.println(date()+"-> Sent to " +bus.sendMsg(s)+" peers"); } } // parseCommand @@ -167,9 +191,16 @@ class Probe implements IvyApplicationListener, IvyMessageListener, Runnable { } public void receive(IvyClient client, String[] args) { - String s=client.getApplicationName() + " sent"; + String s=date()+client.getApplicationName() + " sent"; for (int i=0;i<args.length;i++) s+=" '"+args[i]+"'"; System.out.println(s); } + private String date() { + if (!timestamp) return ""; + Date d = new Date(); + java.text.DateFormat df = java.text.DateFormat.getTimeInstance(); + return "["+df.format(d)+"] "; + } + } |