<--development, continued ^--Soigan--^ next stage-->

Soigan - a Multicast XML monitoring system - even more development

Even more development

With a working Worker, we should now get a Server to talk to it.

Server

We can also break the Server into four parts, very similar to the Worker:

Configuration file reader

<configuration>

<network>
  <server>
    <port>5107</port>
  </server>
</network>

<permissions>
  <worker>
    <allow>127.0.0.1</allow>
  </worker>
</permissions>

<plugins/>

<workers>
  <worker>
    <host>localhost</host>
    <services>
      <service>
        <name>who</name>
        <params/>
        <period units="seconds">30</period>
      </service>
    </services>
  </worker>
</workers>

</configuration>
The same class as before, ConfReader, handles the Server settings as well as the Worker ones. We can look at soigan_server.java and see how similar the usage of ConfReader is between Worker and Server.
import org.apache.xmlrpc.WebServer;

class soigan_server {
  public static void main(String args[]) {
    ConfReader cr;
    try {
      cr=new ConfReader(args[0]);
    } catch (Exception e) {
      cr=new ConfReader("soigan.conf");
    }

    if (cr.isValid()) {
      WebServer server=new WebServer(cr.getServerPort());
      cr.setServerPerms(server);
      
      ServerHandler handler=new ServerHandler();
      cr.setServerPlugins(handler);
      
      server.addHandler("plugin",handler.getPluginHandler());
      server.addHandler("schema",handler.getSchemaHandler());
      
      server.start();
    } else {
      System.err.println("Invalid configuration file.");
    }
  }
}
All the functions are just mirrors of the Worker versions: getServerPort(), setServerPerms() and setServerPlugins(). The last one is a bit of a misnomer, since it's really setting up the Workers that are being called.

XML-RPC Server

Similar to the Worker, we have a ServerHandler class which takes care of the XML-RPC server portion. Here's the plugin.results() handler function:
    public boolean results(final String host, final Date date, final String name, final Hashtable results) {
      boolean returncode=false;
      if (callers!=null) {
        Object o=callers.get(host+"."+name);
        if (o!=null) {
          final PluginCaller p=(PluginCaller)o;
            returncode=true;
            (new Thread() {
                public void run() {
                  System.out.println(date+" "+name+"@"+host+" soigan: "+results);
                }
              }).start();
        }
      }
      return returncode;
    }
For now, we've got the Result being spit out onto stdin in a log-like format. We haven't really discussed what a Server should do with the Result yet. One thing at a time. Here's an example of the output:
Wed Jun 23 11:39:28 MDT 2004 who@localhost soigan: {whoentries=[{when=Tue Jun 01 08
:02:00 MDT 2004, login=crwth, tty=pts/1, from=stilton}, {when=Tue Jun 01 08:41:00 M
DT 2004, login=crwth, tty=pts/3, from=stilton}, {when=Thu Jun 03 15:41:00 MDT 2004,
 login=crwth, tty=pts/4, from=stilton}], count=3}

Worker (service) handler

This sets up all of the Server/s work. For most cases, especially the ones that come from the configuration file, these will be individual threads that are launched to handle periodic calls to different Workers. Occasionally a Client might ask the Server to make a Request on its behalf, usually as a one-off (though Clients might also add a periodic Request to a Server as well).

To accommodate this, our Server, or in this case the ServerHandler, has an add() function that will set up the thread. All the thread does is call the XML-RPC client portion of the Server at regular periods.

XML-RPC client

The real guts run in a PluginCaller object, here:
  public void run() {
    try {
      while (true) {
        XmlRpcClient client=new XmlRpcClient("http://"+hostname+":"+port);
        Vector params=new Vector();

        params.addElement(new String(myname));
        params.addElement(java.util.Calendar.getInstance().getTime());
        params.addElement(new String(pluginname));
        params.addElement(options);

        if (schema)
          results=client.execute("schema.get",params);
        else
          results=client.execute("plugin.run",params);

        if (period>0) {
          Thread.sleep(period*1000);
        } else {
          break;
        }
      }  
    } catch (Exception e) {
      e.printStackTrace();
    }
  }  

Testing

Since we already have a Worker written, we don't need to make special testing objects. As shown above, the Server currently connects to the Workers specified in the configuration file, at the specified period.
<--development, continued ^--Soigan--^ next stage-->
©2002-2017 Wayne Pearson