/* * (C) Copyright IBM Corp. 2008 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.tools.replay; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import com.ibm.mqtt.MqttException; public class SensorSimulator { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2008"; private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); // Relevant time ranges where we have interesting data for "personnelTracking", "mortarFire" and "smallArms" events. // +1 hour added to values used in perl scripts (because Timestamp on left in logs is an hour ahead of sensor date and time logged in msg) // i.e. Timestamp on left is unix time which takes account of Daylight Saving Time (+1 hr in summer) - the sensor times are UTC (=GMT) private static final String[] startTimes = { "2007-09-24 21:15:00.000", // personnel start period "2007-09-25 15:15:00.000", // mortar start period "2007-09-25 15:20:00.000" // small arms start period }; private static final String[] endTimes = { "2007-09-24 22:00:00.000", "2007-09-25 16:00:00.000", //"2007-09-24 21:15:30.000" "2007-09-25 15:40:00.000" }; // Topics for personelTracking, mortarFire and smallArms events. private static final String[] SENSOR_TOPICS = { "xyzzy/PITADA/STAT/010", "xyzzy/PITADA/STAT/011", "xyzzy/PITADA/STAT/012", "xyzzy/MITADS/LOBR/2185", "xyzzy/MITADS/LOBR/5324" }; private static final String[] BROKER_TOPICS = { "xyzzy/PITADA/STAT/010", "xyzzy/PITADA/STAT/011", "xyzzy/PITADA/STAT/012", "xyzzy/MITADS/LOBR/2185", "xyzzy/MITADS/LOBR/5324" }; // Set of forwarding links for each broker connector that will be created. // Each set of links identifies the brokers that the given broker connector will forward its messages to. // IMPORTANT NOTE!! CARE MUST BE TAKEN HERE NOT TO DEFINE LOOPING CONNECTIONS! private static final int[][] FORWARDING_LINKS = { null, null, null, { 0 }, { 0 } }; // private static final String[] CLIENT_NAMES = { "PersonnelMovement1", "PersonnelMovement2", "PersonnelMovement3", // "EventBearingSensor1", "EventBearingSensor2" };//, "fireEventSensorBroker" }; public static void main(String[] args) throws MqttException, IOException, ParseException, InterruptedException { System.out.println("Starting SensorSimulator..."); /*args.length == 1 || args.length > 2 ? args[args.length-1] :*/ String filename = "log.txt"; String startTime = args.length > 0 ? args[0] : startTimes[1]; String endTime = args.length > 1 ? args[1] : endTimes[1]; // the latest end time int argIdx = 2; while ( args.length > argIdx ) { if ( argIdx-2 >= BROKER_TOPICS.length ) { System.out.println("Ignoring overlay topic " + args[argIdx] + ", maximum number is " + BROKER_TOPICS.length); } else { String overlayTopicSuffix = args[argIdx]; String topic = BROKER_TOPICS[argIdx-2]; BROKER_TOPICS[argIdx-2] = topic.substring(0, topic.length() - overlayTopicSuffix.length()) + overlayTopicSuffix; } argIdx++; } int numSensors = BROKER_TOPICS.length; System.out.println("Creating BrokerConnector objects..."); BrokerConnector[] bcs = new BrokerConnector[ numSensors ]; for (int i=0; i<numSensors; i++) { try { String topic = BROKER_TOPICS[i]; bcs[i] = new BrokerConnector( "Sensor" + topic.substring(topic.lastIndexOf('/')+1), "localhost", 1883 + i, topic + "/#" ); } catch ( Exception e ) { System.out.println("No broker to connect to on port " + (1883+i)); bcs[i] = null; continue; } int[] links = FORWARDING_LINKS[i]; if ( null != links ) for (int j=0; j<links.length; j++) { try { bcs[i].setForwardingLinkToBroker("localhost", 1883+links[j]); } catch ( Exception e ) { System.out.println("Connector to broker on " + (1883+i) + " could not setup forwarding link to broker on " + (1883+links[j])); } } } FileReader fr = null; try { fr = new FileReader( filename ); } catch ( FileNotFoundException e ) { fr = new FileReader( "C:\\temp\\log.txt" ); } BufferedReader br = new BufferedReader( fr ); String line; long start = sdf.parse( startTime ).getTime()/1000; long end = sdf.parse( endTime ).getTime()/1000; System.out.println("Replaying sensor events from file " + filename + " between timestamps " + startTime + " = " + start + " and " + endTime + " = " + end); // int lineNumber = 0; // int linesIncrement = 100; // String logMsg = null; int countPitada010 = 0, countPitada011 = 0, countPitada012 = 0, countPitada013 = 0; int countMitads2185 = 0, countMitads5324 = 0; int count = 0, msgCount=0; long previousTimeStamp = 0; while( null != ( line = br.readLine() ) ) { // lineNumber++; // if ( 0 == lineNumber%linesIncrement ) // System.out.println("Processing next " + linesIncrement + " lines from line " + lineNumber ); if ( ! line.startsWith("#!#") ) continue; String lineMinusPrefix = line.substring(3); long stamp = Long.parseLong( lineMinusPrefix.substring(0, lineMinusPrefix.indexOf('#')) ); if ( 0 == stamp%600 ) {// Print msg every 1 minutes of logs // System.out.println("Checking that timestamp is within targetted time period: " + start + " < " + stamp + " < " + end); System.out.print('.'); count++; } if ( stamp < start ) continue; if ( stamp > end ) break; for ( int i=0; i<numSensors; i++ ) { if ( null == bcs[i] ) continue; String topic = SENSOR_TOPICS[i]; int idx = line.indexOf( topic ); if ( -1 != idx ) { // Apply potential overlay, i.e. replace topic with expected broker topic for a given sensor topic topic = BROKER_TOPICS[i] + line.substring( idx + topic.length(), line.indexOf("#", idx) ); //topic = line.substring( idx, line.indexOf("#", idx) ); String msg = line.substring( idx + topic.length() + 1 ); // remove the 1st char: "#" if ( ! msg .startsWith("$MITADS") && ! msg.startsWith("$PITADA") ) break; // Check for invalid msgs if ( 0 != previousTimeStamp ) { // wait the amount of time that passed in real life // if ( 0 == stamp%600 ) // System.out.println( "Times: " + previousTimeStamp + ", " + stamp + ", diff " + ( stamp - previousTimeStamp ) ); Thread.sleep( 100 * ( stamp - previousTimeStamp ) ); } previousTimeStamp = stamp; // String log = stamp + " Topic " + topic + ", publishing message: " + msg; // if ( null == logMsg || msg.startsWith("$MITADS") ) // System.out.println( log ); char evt = topic.charAt(topic.length()-1); // if ( null != overlayTopic ) // evt = overlayTopic.charAt( overlayTopic.length()-1 ); switch ( evt ) { case '0': countPitada010++; break; case '1': countPitada011++; break; case '2': countPitada012++; break; case '3': countPitada013++; break; case '4': countMitads5324++; break; case '5': countMitads2185++; break; } System.out.print( evt ); if ( 0 == ++count%150 ) System.out.println(); msgCount++; // logMsg = log; bcs[i].publish( topic, msg ); } } } // if ( null != logMsg ) //// System.out.println( logMsg ); // System.out.println( "M" ); System.out.println("\nPublished " + msgCount + " messages"); System.out.println("Pitada counts: 010: " + countPitada010 + ", 011: " + countPitada011 + ", 012: " + countPitada012 + ", 013: " + countPitada013); System.out.println("Mitads counts: 2185: " + countMitads2185 + ", 5324: " + countMitads5324); br.close(); fr.close(); for ( int i=0; i<numSensors; i++ ) if ( null != bcs[i] ) bcs[i].terminate(); } }