Instrumentation and Automation API

Using Instrumentation and Automation

Installing the Plug-Ins

To use PAL Thunderbird/Firefox instrumentation and automation, the first step is to install the respective plug-ins into Firefox and Thunderbird. You can get the plug-ins from the downloads section. For Firefox, simply drag the firefox.xpi plug-in to the browser frame. For Thunderbird, click Tools->Add-ons, navigate to thunderbird.xpi and click install. Be sure to restart the applications after installing the plug-ins.

Running the RemoteXML Server

You can get the RemoteXML server in the downloads section. After downloading, unpack and run remotexml_server.bat. This will start the server on port 33804. Note, if you have a source release, you will need to compile everything first by running ant from the command prompt. You should see a confirmation message that looks like this:


	Starting RemoteXml server on port 33804

Running the RemoteXML Client

If you want to verify that everything is working correctly, you can run the demo client app that simply prints the XML messages to the console. Run remotexml_client.bat from a command prompt and you should see something like this:


	Starting RemoteXml client on port 33805

And you should see something like this on the server:

	Added remote message listener for endpoint http://localhost:33805

API

Event Types


      public abstract class Event {

  	//TYPES
    	//Email
    	//email_task, email_sent, email_selected, email_window_opened, 
    	//email_compose_response, email_compose, email_folder_select, 
    	//email_open_attachment, email_add_attachment, email_save_attachment, 
    	//email_mark_email_read,
    	//Browser
    	//browser_location_changed, browser_open_url, browser_save_url, 
    	//browser_submit_form, browser_download_file,
  	//Thunderbird evens
 	 public static final String ADD_EMAIL_ATTACHMENT = "tasks:AddEmailAttachment";
  	public static final String DELETE_EMAIL = "tasks:DeleteEmail";
  	public static final String MARK_READ_EMAIL = "tasks:MarkReadEmail";
  	public static final String MARK_UNREAD_EMAIL = "tasks:MarkUnReadEmail";
  	public static final String OPEN_COMPOSE_EMAIL_WINDOW = "tasks:OpenComposeEmailWindow";
  	public static final String OPEN_EMAIL_WINDOW = "tasks:OpenEmailWindow";
  	public static final String OPEN_COMPOSE_RESPONSE_WINDOW = "tasks:OpenComposeResponseWindow";
  	public static final String OPEN_EMAIL_ATTACHMENT = "tasks:OpenEmailAttachment";
  	public static final String PREDICT_CC = "tasks:PredictCC";
  	public static final String PREDICT_ATTACHMENTS = "tasks:PredictAttachments";
  	public static final String SAVE_EMAIL_ATTACHMENT = "tasks:SaveEmailAttachment";
  	public static final String SELECT_EMAIL = "tasks:SelectEmail";
  	public static final String SELECT_EMAIL_FOLDER = "tasks:SelectEmailFolder";
  	public static final String SEND_EMAIL = "tasks:SendEmail";
 
  	//Firefox events
  	public static final String OPEN_URL = "tasks:OpenUrl";
  	public static final String SUBMIT_FORM_BROWSER = "tasks:SubmitFormBrowser";
  
  	//
  	protected Map fields;
  	protected String type;

  	//Automation
  	protected String targetAgentUri;
  	protected String taskSpec;
  
  	public Event(String type) {
  	  super();
    	  fields = new HashMap();
    	  this.type = type;
  	}

  	public Map getFields() {
    	  return fields;
  	}
  
  	public String getType(){
    	  return type;
  	}
  
  	public String toString() {
    	  return type;
  	}

	public abstract Map doAutomation(Map map) throws Exception;

  	/**
   	* Go through the JAXB object and get the fields necessary.
   		* 
   	* @param requestData
   	* @return fields
   	*/
  	public abstract Map doInstrumentation(Object... requestData);

     }

Listening for events - use the IRemoteMessageListener interface


	public interface IRemoteMessageListener {
    		boolean notifyMessageReceived(String client, String message);
	}

	public class RemoteMessageListenerImpl implements IRemoteMessageListener {
    		static EventFactory ef = EventFactory.getInstance();
    		private static Logger log = Logger.getLogger(RemoteMessageListenerImpl.class);

    		public boolean notifyMessageReceived(String client, String message) {
      			log.info("notifyMessageReceived: client = " + client + ", message = " + message);
      			//@SuppressWarnings("unused")
      			//Event e = ef.create(message);
      
      			return true;
    		}
	}


Setting up XML-RPC server - use the Apache Webserver class


      public class RemoteXmlServerImpl implements IRemoteXmlServer {
  
    	private static String LOG4J_CONFIG_FILENAME="config/remotexml-log4j.config";
    	private static Logger log = Logger.getLogger(RemoteXmlServerImpl.class);

    	private int port;
    	private WebServer webServer;
    	private PropertyHandlerMapping phm;

    	public RemoteXmlServerImpl(int port) throws XmlRpcException {
        	this.port = port;
        	webServer = new WebServer(port);
        	XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
        	phm = new PropertyHandlerMapping();
        	xmlRpcServer.setHandlerMapping(phm);
        	XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
        	serverConfig.setEnabledForExtensions(true);
        	serverConfig.setContentLengthOptional(false);
    	}

    	public void addHandler(String name, Class handler) {
        	try {
            	phm.addHandler(name, handler);
        	} catch (XmlRpcException e) {
            	log.error("Failed to add add handler for name = " + name + ", handler = " + handler.getName(), e);
        	}
    	}

    	public void start() {
        	try {
            	log.info("Starting RemoteXml server on port " + port);
            	webServer.start();
        	} catch (IOException e) {
            	log.error("Failed to start web server", e);
        	}
    	}

    	public void stop() {
        	webServer.shutdown();
    	}

    	public static void main(String[] args) throws Exception {
      	PropertyConfigurator.configure(LOG4J_CONFIG_FILENAME);
        	// Load services
        	Map services = new HashMap();
       		services.put("com.sri.remotexml.plugin.IClientManager",
			"com.sri.remotexml.plugin.ClientManagerImpl");
       		services.put("com.sri.remotexml.plugin.IEndpointManager",
			"com.sri.remotexml.plugin.EndpointManagerImpl");
        	services.put("com.sri.remotexml.plugin.IIDGenerator",
			"com.sri.remotexml.plugin.IDGeneratorImpl");
       		services.put("com.sri.remotexml.plugin.IXMLMessageDispatcher",
			"com.sri.remotexml.plugin.XMLMessageDispatcherImpl");

        	for (String key : services.keySet()) {
            		String value = services.get(key);
            		IServiceManager serviceManager = ServiceManagerImpl.getInstance();
            		Class type = Class.forName(key);
            		IService service = (IService) Class.forName(value).newInstance();
            		serviceManager.addService(type, service);
        	}

        	// Create remote xml server
        	int port = 33804;
        	IRemoteXmlServer server = new RemoteXmlServerImpl(port);

        	// Load handlers
        	Map handlers = new HashMap();
        	handlers.put("IXMLClientHelper", "com.sri.remotexml.plugin.XMLClientHelperImpl");
        	handlers.put("IRemoteMessageDispatcher", "com.sri.remotexml.server.RemoteMessageDispatcherImpl");
        	for (String key : handlers.keySet()) {
            		String value = handlers.get(key);
            		Class type = Class.forName(value);
            		server.addHandler(key, type);
        	}

        	// Start server
        	server.start();
    	}

      }

Setting up XML-RPC client - use the Apache XmlRpcClient class


	import org.apache.xmlrpc.client.XmlRpcClient;
	
	XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL("http://localhost:33804/"));
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        Object[] params = new Object[] {"http://localhost:33805"};
        client.execute("IRemoteMessageDispatcher.addRemoteMessageListener", params);