aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/Ivy.java66
-rwxr-xr-xsrc/IvyClient.java5
-rwxr-xr-xsrc/IvyWatcher.java13
-rw-r--r--src/Probe.java57
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)+"] ";
+ }
+
}