//import java.net.*; import java.io.*; import java.util.Date; import java.sql.ResultSet; //import java.sql.Connection; //import java.sql.DriverManager; //import java.sql.SQLException; //import java.sql.Statement; //import java.sql.Time; class ScheduleReader { //configuration/log classes here //logstream class performs message formating, message priority, redirects //to appropriate streams, and formating exception stack prints public LogStream logStream; static String configName = "/home/pcruce/opstools/src/scratch-/filetracker/trackerconfig/filetracker.cfg"; public static String logFile; //configuration state vars public static String hostName; public static String userName; public static String password; public static String dbName; public static String emailList; // public static String opsMailList; public static String returnUser; //connection classes SatConnection satCon; MysqlConnection myCon; static int counter = 1; public static void main(String[] args) { //can take the name of a configuration file on the command line if(args.length > 0) { configName = args[0]; } //configuration file class follows bryce robert's config class from c++ Config c; c = new Config(configName); logFile = c.getString("schedulerlogfilepath"); hostName = c.getString("mysqlhostname"); userName = c.getString("mysqlusername"); password = c.getString("mysqlpassword"); dbName = c.getString("mysqldbname"); emailList = c.getString("emaillist"); // opsMailList = c.getString("opsmaillist"); returnUser = c.getString("user"); //date was used during testing Date d = new Date(); ScheduleReader t = null; //this is used on the top level of the system LogStream mainLogStream; //PrintStream o; // int mainCounter = 0; try { mainLogStream = new LogStream(logFile,4); } catch (Exception e) { mainLogStream = new LogStream(System.out,3); mainLogStream.print("LogStream allocation error:\n" + e + "\nDefaulting to System.out\n",2); System.exit(1); } mainLogStream.print("Emaillist: " + emailList,1); //class allocation and error catching try { t = new ScheduleReader(logFile,4); } catch(Exception e) { try { SendMail.sendEmailNotification("The ScheduleReader was unable to start due to an unexpected internal error\nReceived error: " + e.toString(),"ScheduleReader Programmatic Startup Error",emailList,returnUser,e); } catch(Exception ex) { mainLogStream.print("Caught exception while sending email notification: " + ex.toString(),1); mainLogStream.printStackTrace(ex,1); } mainLogStream.print("Error in main loop while allocatingreader class:\n" + e,3); System.exit(1); } //main loop and error catching try { t.satTrackLoop(); } catch(Exception e) { try { SendMail.sendEmailNotification("A ScheduleReader internal runtime error caused the program to fail unexpectedly\nReceived error: " + e.toString(),"ScheduleReader Programmatic Runtime Error",emailList,returnUser,e); } catch(Exception ex) { mainLogStream.print("Caught exception while sending email notification: " + ex.toString(),1); mainLogStream.printStackTrace(ex,1); } t.logStream.print("Runtime Error: " + e + " Printing stack trace",3); t.logStream.printStackTrace(e,3); } finally //shut down { try { t.close(); } catch(Exception ex) { mainLogStream.print("Shutdown Error: " + ex,2); } mainLogStream.print("Terminating schedulereader",3); System.exit(1); } //just in case, specically system.exits must be called becaus //not all thread terminate, to fix, all additional threads should //be flagged as daemon threads(see javadoc & tutorial on multithreading System.exit(1); } /**starts the schedule reader,most of the configuration is done by setting *the class static variables *@param log a string naming the logfile to which output should be written *@param verbosity how much output the class should print; should be between 1-5, 5 is most verbose */ public ScheduleReader(String log, int verbosity) throws Exception { logStream = new LogStream(log,verbosity); logStream.print("Starting Iteration: " + counter,4); counter++; //start sattrack connection try { satCon = new SatConnection(logStream); } catch(Exception e) { if(satCon != null) { satCon.close(); satCon = null; } throw e; } // System.out.println("host: " + hostName +"\nuserName: " + userName + "\npassword: " + password + "\ndbName: " + dbName); //start mysql connection try { myCon = new MysqlConnection(logStream,hostName,userName,password,dbName); } catch(Exception e) { satCon.close(); satCon = null; if(myCon != null) { myCon.close(); myCon = null; } throw e; } logStream.print("Started",4); } public void close() throws Exception { logStream.print("Stopping",5); if(satCon != null) { try { satCon.close(); } catch(Exception e) { logStream.print("SatCon Shutdown Error: " + e,2); } } if(myCon != null) { try { myCon.close(); } catch(Exception e) { logStream.print("myCon Shutdown Error: " + e,2); } } logStream.close(); } /**The central component of this program *This function first does an active query of the schedule to make sure the schedule is up to date if the program has not been run for * some time, then is sits and waits for any schedule updates to come from sattrack, these should occur at least once per day. */ public void satTrackLoop() throws Exception { Date d = new Date(); // long start,now; boolean sleep = false; String s; String q = null; try { logStream.print("Entering schedule processing loop",5); //sends the command to actively query the sattrack schedule database satCon.activeScheduleQuery(); //myCon.getLock(); while(true) { if(satCon.ready()) { if((s = satCon.readLine()) != null) { logStream.print("Found line:\n " + s + "\n in ScheduleReader.satTrackLoop\n",4); if(Find.find("\"Facility\",\"Object\",\"Object Number\",\"Object ID\",\"Orbit\",\"Element Set\",\"Priority\",\"PRP Begin\",\"AOS\",\"LOS\",\"POP End\",\"TLM Mode\",\"CMD Mode\"",s) || Find.find("\"Facility\",\"Object\",\"Object Number\",\"Object ID\",\"Orbit\",\"Element Set\",\"Priority\",\"Pre-Pass Begin\",\"Pass AOS\",\"Pass LOS\",\"Post-Pass End\",\"Telemetry Mode\",\"Command Mode\"",s)) { logStream.print("Update Found : Counter/Date:" + counter + "/" + d.toString(),3); deleteFutureContacts(); counter = 0; } else if(Find.find("End of Schedule",s)) { logStream.print("Found end of schedule",3); break; } else { q = processScheduleLine(s); myCon.mysqlDbExecuteQuery(q); q = getCheckLine(s); myCon.mysqlDbExecuteQuery(q); } } counter++; } } //myCon.releaseLock(); logStream.print("Starting passive query",3); //second passive query //sends the command to passively query the sattrack schedule database satCon.passiveScheduleQuery(); while(true) { if(satCon.ready()) { s = satCon.readLine(); logStream.print("Found line:\n " + s + "\n in ScheduleReader.satTrackLoop\n",4); if(Find.find("\"Facility\",\"Object\",\"Object Number\",\"Object ID\",\"Orbit\",\"Element Set\",\"Priority\",\"PRP Begin\",\"AOS\",\"LOS\",\"POP End\",\"TLM Mode\",\"CMD Mode\"",s) || Find.find("\"Facility\",\"Object\",\"Object Number\",\"Object ID\",\"Orbit\",\"Element Set\",\"Priority\",\"Pre-Pass Begin\",\"Pass AOS\",\"Pass LOS\",\"Post-Pass End\",\"Telemetry Mode\",\"Command Mode\"",s)) { // myCon.getLock(); sleep = false; logStream.print("Update Found : Counter/Date:" + counter + "/" + d.toString(),3); deleteFutureContacts(); } else if(Find.find("End of Schedule",s)) { logStream.print("Found end of schedule",3); //myCon.releaseLock(); sleep = true; } else { q = processScheduleLine(s); myCon.mysqlDbExecuteQuery(q); q = getCheckLine(s); myCon.mysqlDbExecuteQuery(q); } } //keeps processor load down when nothing is coming down the pipe if(sleep == true) { Thread.sleep(500); } } } catch(Exception e) { //System.out.println(e); //no longer catching any exceptions here throw e; } } /** deletes all the contacts in the future so that the new set of contacts added in will not be duplicated */ private void deleteFutureContacts() throws Exception { String q; ResultSet rs; int sz; q = "SELECT contact_key FROM contact_schedule WHERE POP_end_datetime > get_mission_time()"; rs = myCon.mysqlDbExecuteQuery(q,false); sz = myCon.resultSetSize(rs); logStream.print("Got contact_keys for delete_future_contacts() size: " + sz,3); rs.beforeFirst(); for(int i = 0;i < sz;i++) { rs.next(); q = "CALL delete_check(" + rs.getInt("contact_key") + ")"; myCon.mysqlDbExecuteQuery(q); } logStream.print("checks deleted",3); q = "CALL delete_future_contacts()"; myCon.mysqlDbExecuteQuery(q); } /*takes a line of the schedule and turns it into a line for insert into mysql *@param s a String containing a line from the sattrack schedule *@return a string formatted for insert into mysql */ private String processScheduleLine(String s) { String[] f; f = s.split(","); return "CALL insert_contact(\"" + f[0] +"\",\"" + f[1] + "\"," + f[2] + "," + f[3] + "," + f[4] + "," + f[5] + "," + f[6] + ",STR_TO_DATE(\"" + f[7] + "\",\"%Y/%j %H:%i:%s\")" + ",STR_TO_DATE(\"" + f[8] + "\",\"%Y/%j %H:%i:%s\")" + ",STR_TO_DATE(\"" + f[9] + "\",\"%Y/%j %H:%i:%s\")" + ",STR_TO_DATE(\"" + f[10] + "\",\"%Y/%j %H:%i:%s\")" + ",\"" + f[11] + "\",\"" + f[12] + "\")"; } /*takes a line from the sattrack schedule and formats it to add the proper check entries to the database *@param s a String containing a line from the sattrack schedule *@return a string formatted for insert into mysql */ private String getCheckLine(String s) { String[] f; f = s.split(","); return "CALL insert_check(get_contact_key(\"" + f[0] + "\",STR_TO_DATE(\"" + f[8] + "\",\"%Y/%j %H:%i:%s\")))"; } /*now on send mail class static String stackTraceString(Throwable t) { String o = ""; StackTraceElement[] e; e = t.getStackTrace(); for(int i = 0;i < e.length;i++) { o += e[i].toString() + "\n"; } return o; } */ };