Previous topic

3.1. How to set an experiment with MAGI

Next topic

3.3. How to control basic operations with Python

This Page

3.2. How to control basic operations with JavaΒΆ

This assumes that you already have an experiment with the MAGI backend running on it. If not, see How to set an experiment with MAGI.

The following code segments are written in Java but they can all be written using the Python library as well.

In the following example, we:
  1. have A1 and A2 join clientsgroup group and V join serversgroup group
  2. ask all clientsgroup nodes to load and start wget agent
  3. ask all serversgroup nodes to load and start apache agent
  4. ask all serversgroup nodes to load and start counters agent
  5. ask apache agent on all serversgroup nodes to start
  6. configure wget agent on all clientsgroup nodes and then ask them to start
  7. request stream of counter data from the counters agent node V (listening at dock pktcount1)
  8. receive 15 messages, should only be counter messages
  9. ask the counters agent on V to stop streaming
  10. ask each of the agent groups to stop their respective agents
  11. have A1, A2 and V leave the groups that they joined
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import net.deterlab.magi.messages.CounterData;
import net.deterlab.magi.messages.MethodCall;
import net.deterlab.magi.messaging.ClientConnection;
import net.deterlab.magi.messaging.MessageUtil;
import net.deterlab.magi.messaging.MessagingException;
import net.deterlab.magi.messaging.MAGIMessage;

/**
 * Java example using messaging system to communicate with experiment.
 */
public class javaexample
{        
    /**
     * main
     * @param args ignored
     * @throws MessagingException
     * @throws InterruptedException
     * @throws IOException 
     */
    public static void main(String[] args) throws MessagingException, InterruptedException, IOException 
    {
    	Logger log = Logger.getLogger("net.deterlab.magi");
    	log.setLevel(Level.FINE);
    	Logger.getLogger("").getHandlers()[0].setLevel(Level.ALL);  // they just don't make it easy
    	
    	log.fine("Opening connection");
        ClientConnection messaging = new ClientConnection();
        messaging.connect("myhostname2", "localhost", 18808);  // assumes port forwarding setup to control node
        
        /** Send a method call request to have have particular nodes join clientgroup */
        MessageUtil.buildGroup(messaging, "clientgroup", new String[] { "A1", "A2" });

        /** Send a method call request to have have particular nodes join servergroup */
        MessageUtil.buildGroup(messaging, "servergroup", new String[] { "V" });

        Thread.sleep(2000); // wait to make sure routing info has spread, this will be a trigger later
           
        /** Request to clientgroup nodes to load http client agent at the dock 'client1'. */
        MessageUtil.loadLocalAgent(messaging, "clientgroup", "http_wget", "client1");
        
        /** Request to servergroup nodes to load apache agent at the dock 'server1'. */
        MessageUtil.loadLocalAgent(messaging, "servergroup", "apache", "server1");
        // will need to have a trigger for waiting for completion, some agents will need to install software which can take from seconds to minutes
        
        /** Request to servergroup nodes to load the counter agent at the dock 'counters' */ 
        MessageUtil.loadLocalAgent(messaging, "servergroup", "counters", "pktcount1");
                                
        /** Now send message to the apache servers and ask them to start */
        MessageUtil.groupMethodCall(messaging, "servergroup", "server1", "startServer"); // goes to all agents on nodes in servergroup group listening to dock apache
        
        /** Configure sizes, interval and server list on all wget agents */
        Map<String, Object> vars = new HashMap<String,Object>();
        vars.put("sizes", "minmax(1000, 10000)");
        vars.put("interval", "minmax(0.5, 2)");
        vars.put("servers",  new String[] { "V" });
        MessageUtil.groupMethodCall(messaging, "clientgroup", "client1", "setConfig", vars);
        
        /** Now send message to the wget agents and ask them to start */
        MessageUtil.groupMethodCall(messaging, "clientgroup", "client1", "startClient");        
        
        /** Request stream of counter data from node V. */
        MethodCall streamcall = new MethodCall("stream")
            .addArg("name", "in-10.1.2.2")  
            // looking for incoming traffic on interface 10.1.2.2
            // ugly but hacked in for now as we will eventually have the user specify a filter and assign a name to it
            .addArg("dstnodes", new String[]{"myhostname2"}) // send the reports to me
            .addArg("dstdocks", new String[]{"countermonitor"}) // send them to the particular dock for processing
            .addArg("period", 3.0);  // collect and send every 3 seconds
        MessageUtil.sendToNode(messaging, "V", "pktcount1", streamcall); // goes to the counters agent on node V
        
        /** keep receiving messages until the one the first counters reply */
        int count = 15;
        while (count-- > 0)
        {
        	MAGIMessage msg = (MAGIMessage)messaging.nextMessage(true, 0); 
            log.info(""+msg);
            if (msg.containsDestDock("countermonitor"))  // this is the dock we asked the counters agent to send to
            {
                CounterData counters = new CounterData(msg.getDecodedData());
                log.info(""+counters);
            }
        } 
        
        /**
         *  Stop the streaming call, rather than rebuild the necessary args again (name, dst, dock), 
         *  we just save the old call and update the name, the extra period arg will be ignored
         */
        streamcall.setMethodName("stopstream");
        MessageUtil.sendToNode(messaging, "V", "pktcount1", streamcall); // goes to the counters agent on node V
        
        /** After running for some time, ask clients and servers to stop running. */
        MessageUtil.groupMethodCall(messaging, "clientgroup", "client1", "stopClient"); 
        MessageUtil.groupMethodCall(messaging, "servergroup", "server1", "stopServer"); 
        
        /** Send a method call request to have particular nodes leave clientgroup */
        MessageUtil.tearDownGroup(messaging, "clientgroup", new String[] { "A1", "A2" });
        
        /** Send a method call request to have particular nodes leave servergroup */
        MessageUtil.tearDownGroup(messaging, "servergroup", new String[] { "V" });
        
        /** give sockets time to send last message, should be a thread.join eventually */
        Thread.sleep(1000); 
        log.info("Done");
    }
}