001 package org.hackystat.sensorshell; 002 003 import java.io.File; 004 import java.util.Date; 005 006 import org.hackystat.sensorbase.client.SensorBaseClient; 007 import org.hackystat.sensorbase.resource.sensordata.jaxb.Properties; 008 import org.hackystat.sensorbase.resource.sensordata.jaxb.Property; 009 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 010 import org.hackystat.utilities.tstamp.Tstamp; 011 012 /** 013 * A command line tool that facilitates performance evaluation and tuning of sensor data 014 * transmission. To use this tool, invoke: 015 * 016 * <pre> 017 * java -jar shellperfeval.jar [numInstancesToSend] 018 * </pre> 019 * 020 * With a sensorshell.properties file located in the same directory as this jar file. 021 * <p> 022 * This results in the following: 023 * <ul> 024 * <li> The sensorshell.properties file is read in and used to initialize a SensorShell, except that 025 * the user and password fields are not used. Instead, a test user called 026 * "ShellPerfEval@hackystat.org" is created and used instead. 027 * <li> Offline caching and recovery are also disabled. 028 * These properties are printed out. 029 * <li> The number provided on the command line is read and used to generate and send that many 030 * Sensor Data instances to the server. The number of milliseconds required to send each request is 031 * printed out, 50 per line. 032 * <li> Once all of the instances have been sent to the server, summary statistics are printed out, 033 * and all of the data associated with this test user is deleted. 034 * </ul> 035 * 036 * @author Philip Johnson 037 * 038 */ 039 public class ShellPerfEval { 040 041 /** 042 * Provide a sensorshell.properties file in the same directory as the location of the jar file 043 * invoking this program. Invoke it with one argument, the number of instances to send. 044 * 045 * @param args One argument, the number of instances to send. 046 * @throws Exception If things go wrong. 047 */ 048 public static void main(String[] args) throws Exception { 049 // Get the number of instances, or exit if failure. 050 int numInstances = 0; 051 try { 052 numInstances = Integer.parseInt(args[0]); 053 } 054 catch (Exception e) { 055 System.out.println("java -jar shellperfeval [numInstancesToSend]"); 056 return; 057 } 058 // Get the sensorshell.properties file, or exit if failure. 059 File propsFile = new File(System.getProperty("user.dir"), "sensorshell.properties"); 060 if (!propsFile.exists()) { 061 System.out.println("sensorshell.properties file must be in this directory."); 062 return; 063 } 064 065 String user = "ShellPerfEval@hackystat.org"; 066 067 // Create our SensorShellProperties with the overridden user and password. 068 SensorShellProperties origProps = new SensorShellProperties(propsFile); 069 java.util.Properties props = new java.util.Properties(); 070 props.setProperty(SensorShellProperties.SENSORSHELL_SENSORBASE_USER_KEY, user); 071 props.setProperty(SensorShellProperties.SENSORSHELL_SENSORBASE_PASSWORD_KEY, user); 072 props.setProperty(SensorShellProperties.SENSORSHELL_OFFLINE_CACHE_ENABLED_KEY, "false"); 073 props.setProperty(SensorShellProperties.SENSORSHELL_OFFLINE_RECOVERY_ENABLED_KEY, "false"); 074 SensorShellProperties shellProps = new SensorShellProperties(origProps, props); 075 System.out.println(shellProps.toString()); 076 077 // Instantiate the sensorshell. 078 SensorShell shell = new SensorShell(shellProps, false, "ShellPerfEval"); 079 080 // Make sure the user remembers to get the SensorBase running. :-) 081 if (!shell.ping()) { 082 System.out.println("Error: Could not contact: " + shell.getProperties().getSensorBaseHost()); 083 } 084 085 // Register our user. 086 SensorBaseClient.registerUser(shellProps.getSensorBaseHost(), user); 087 088 // Now do the run. 089 Date startTime = new Date(); 090 System.out.println("Number of milliseconds for each 'add' command, 50 per line:"); 091 for (long i = 0; i < numInstances; i++) { 092 long time1 = new Date().getTime(); 093 SensorData data = makeSensorData(user, time1 + (i * 10)); 094 shell.add(data); 095 long time2 = new Date().getTime(); 096 if ((i > 0) && ((i % 50) == 0)) { 097 System.out.println(); 098 } 099 if ((i > 0) && ((i % 1000) == 0)) { 100 System.out.println("Finished: " + i + " out of " + numInstances); 101 } 102 System.out.print((time2 - time1) + " "); 103 } 104 105 // Make sure the user remembers to get the SensorBase running. :-) 106 if (!shell.ping()) { 107 System.out.println("Error: Could not contact: " + shell.getProperties().getSensorBaseHost()); 108 // return; 109 } 110 System.out.println(); 111 // Make sure all data has been sent. 112 shell.quit(); 113 long totalTime = (new Date().getTime() - startTime.getTime()); 114 System.out.println("Total time: " + totalTime + " milliseconds."); 115 double timePerData = (double) totalTime / (double) numInstances; 116 System.out.println("Milliseconds/sensordata instance: " + timePerData); 117 SensorBaseClient client = new SensorBaseClient(shellProps.getSensorBaseHost(), user, user); 118 System.out.print("Deleting data from sensorbase..."); 119 client.deleteSensorData(user); 120 System.out.println(" done."); 121 } 122 123 /** 124 * Creates a sample SensorData instance given a user. 125 * 126 * @param user The user. 127 * @param utc The timestamp to be used for this instance. 128 * @return The new SensorData instance. 129 */ 130 private static SensorData makeSensorData(String user, long utc) { 131 String sdt = "TestSdt"; 132 SensorData data = new SensorData(); 133 String tool = "Subversion"; 134 data.setTool(tool); 135 data.setOwner(user); 136 data.setSensorDataType(sdt); 137 data.setTimestamp(Tstamp.makeTimestamp(utc)); 138 data.setResource("file://foo/bar/baz.txt"); 139 data.setRuntime(Tstamp.makeTimestamp()); 140 Property property = new Property(); 141 property.setKey("SampleField"); 142 property.setValue("The test value for Sample Field"); 143 Properties properties = new Properties(); 144 properties.getProperty().add(property); 145 data.setProperties(properties); 146 return data; 147 } 148 149 }