public class WaageWatchService { private static final String myPID = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; private static final Logger log = Logger.getLogger(WaageWatchService.class); private static final String ARGUMENT_CFGFILE = "-cfg"; private static String configfile = null; private static File pidfile = null; private static final String ARGUMENT_STOP = "-stop"; private static boolean stopService = false; private static final String ARGUMENT_TEST = "-test"; private static boolean testService = false; private static WaageConfigurationReader waageConfigurationReader = WaageConfigurationReader.getInstance(); private static WaageConfiguration configuration = WaageConfiguration.getInstance(); private static void exit(int exitCode, final String exitMessage) { if (exitCode == 0) { log.info(exitMessage); System.out.println("[INFO] " + exitMessage); } else { log.error(exitMessage); System.err.println("[ERROR] " + exitMessage); System.out.println("[ERROR] " + exitMessage); } if (pidfile != null) { pidfile.delete(); } Runtime.getRuntime().exit(exitCode); } private static void exit(int exitCode, final Throwable e) { log.error(e.getMessage(), e); System.err.println("[ERROR] " + e.getMessage()); if (pidfile != null) { pidfile.delete(); } try { Thread.sleep(10000); } catch (InterruptedException e1) { log.error("Beim Beenden konnte der Thread nicht schlafen gelegt werden!", e1); } Runtime.getRuntime().exit(exitCode); } private static void exit(int exitCode, String exitMessage, Throwable e) { log.error(exitMessage + " # " + e.getMessage(), e); System.err.println("[ERROR] " + exitMessage + " # " + e.getMessage()); if (pidfile != null) { pidfile.delete(); } try { Thread.sleep(10000); } catch (InterruptedException e1) { log.error("Beim Beenden konnte der Thread nicht schlafen gelegt werden!", e1); } Runtime.getRuntime().exit(exitCode); } /** * @param args args[0] : configuration file * @throws ConnectException */ public static void main(String[] args) { /* * Arguments */ for (int i = 0; i < args.length; i++) { if (args[i].equals(ARGUMENT_CFGFILE)) { configfile = args[++i]; } else if (args[i].equals(ARGUMENT_STOP)) { stopService = true; } else if (args[i].equals(ARGUMENT_TEST)) { testService = true; } else { System.out.println("Unknown parameter '" + args[i] + "' will be ignored."); } } if (!stopService) { log.info("[" + myPID + "] ####### NEW WATCHSERVICE #######"); } // configuration file if (null == configfile) { exit(1, "No configuration file given."); } File cfgFile = new File(configfile); if (!cfgFile.exists()) { exit(1, "Configuration file not found: " + cfgFile.getAbsolutePath()); } if (!cfgFile.isFile()) { exit(1, "Given file is no file: " + cfgFile.getAbsolutePath()); } // PID file setPidfile(cfgFile); if (pidfile.exists()) { int runningPID = getPidFromFile(pidfile); if (processIsAlreadyRunning(runningPID, cfgFile.getName())) { if (stopService) { log.info("stopping process..."); try { Runtime.getRuntime().exec("kill -9 " + runningPID); pidfile.delete(); } catch (IOException e1) { exit(1, "[" + runningPID + "] Could not stop service.", e1); } exit(0, "[" + runningPID + "] WaagenWatchService stopped."); } exit(1, "[error] Process already running (pid " + runningPID + ") ..."); } else { if (stopService) { pidfile.delete(); exit(0, "Specified WaagenWatchService is not running."); } // else: Write PID to PID file } } // write PID to PID file FileWriter w = null; try { w = new FileWriter(pidfile); w.write(myPID); } catch (IOException e) { exit(1, "IOException in pid file.", e); } finally { try { w.close(); } catch (IOException e) { } } // AbasRueckmeldung erzeugen if (!stopService) { /* * Configuration */ try { waageConfigurationReader.read(cfgFile); configuration = waageConfigurationReader.getConfiguration(); configuration.setPIDFile(pidfile); } catch (IOException e) { exit(1, e); } /* * Existing files */ log.info("Handle existing files..."); log.info("Starting WaagenWatchservice..."); AbasRueckmeldung abasrueck; Thread threadAbas = new Thread(abasrueck = new AbasRueckmeldung(waageConfigurationReader.getConfiguration())); threadAbas.start(); Long wartezaehler = new Long(0); if (abasrueck == null) { throw new NullPointerException("Es wurde kein Object abasRückmeldung angelegt!"); } while (!abasrueck.isConnected()) { wartezaehler = wartezaehler + 1; if (wartezaehler % 100 == 0) { log.info(wartezaehler.toString() + " Warten bis EDP-Verbindung steht"); } if (wartezaehler > 10000000) { exit( 1, "Es konnte keine EDP-Verbindung hergestellt werden! Der Waagen service hat sich beendet!"); } } if (threadAbas.isAlive()) { log.info("abasrueckmeldung Thread wurde erzeugt"); // Die einzelnen Waagenüberwachungen starten boolean alive = threadAbas.isAlive(); try { for (int i = 0; i < waageConfigurationReader.getConfiguration().getAnzahlWaagen(); i++) { log.trace("WaageThread " + i + " wird gestartet"); SocketClient socket = new SocketClient(waageConfigurationReader.getConfiguration(), i, abasrueck); } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error(e); } } else { System.err.println("abasrueckmeldung Thread konnte nicht erzeugt werden"); log.error("abasrueckmeldung Thread konnte nicht erzeugt werden"); } } // } private static void setPidfile(File cfgFile) { String[] cF = configfile.split("/"); String cFName = cF[cF.length - 1]; cFName = cFName.substring(0, cFName.lastIndexOf(".")); if (null == cfgFile.getParent()) { pidfile = new File(cFName + ".pid"); } else { pidfile = new File(cfgFile.getParent().toString() + '/' + cFName + ".pid"); } cFName = null; cF = null; } private static boolean processIsAlreadyRunning(int pid, String cfgFile) { log.debug("processIsAlreadyRunning(" + pid + ", " + cfgFile + ") ..."); if (pid == 0) { exit(1, "PID file corrupted. Please check WatchService manually."); } String jarName = System.getProperty("java.class.path"); jarName = jarName.split("/")[jarName.split("/").length - 1]; String[] cmd = { "/bin/sh", "-c", "ps -o \"pid user command\" -p " + pid + " | sed 1d | grep -E '.*" + jarName + ".* -cfg .*" + cfgFile + ".*' | wc -l" }; if (cmd.length >= 3) { log.debug(cmd[2]); } Process p = null; try { p = Runtime.getRuntime().exec(cmd); } catch (IOException e) { exit(1, "IOException in ps command.", e); } BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); int numOfLines = 0; try { numOfLines = Integer.valueOf(br.readLine()); if (numOfLines >= 1) { return true; } return false; } catch (NumberFormatException e) { log.error("NumberFormatException in numOfLines of BufferedReader.", e); } catch (IOException e) { log.error("IOException in BufferedReader", e); } finally { try { br.close(); } catch (IOException e) { } } return false; } private static int getPidFromFile(File pidfile) { int runningPID = 0; BufferedReader br = null; try { br = new BufferedReader(new FileReader(pidfile)); runningPID = Integer.valueOf(br.readLine()); } catch (IOException e) { exit(1, e); } finally { try { br.close(); } catch (IOException e) { } } return runningPID; } }
/** * @param args args[0] : configuration file * @throws ConnectException */ public static void main(String[] args) { /* * Arguments */ for (int i = 0; i < args.length; i++) { if (args[i].equals(ARGUMENT_CFGFILE)) { configfile = args[++i]; } else if (args[i].equals(ARGUMENT_STOP)) { stopService = true; } else if (args[i].equals(ARGUMENT_TEST)) { testService = true; } else { System.out.println("Unknown parameter '" + args[i] + "' will be ignored."); } } if (!stopService) { log.info("[" + myPID + "] ####### NEW WATCHSERVICE #######"); } // configuration file if (null == configfile) { exit(1, "No configuration file given."); } File cfgFile = new File(configfile); if (!cfgFile.exists()) { exit(1, "Configuration file not found: " + cfgFile.getAbsolutePath()); } if (!cfgFile.isFile()) { exit(1, "Given file is no file: " + cfgFile.getAbsolutePath()); } // PID file setPidfile(cfgFile); if (pidfile.exists()) { int runningPID = getPidFromFile(pidfile); if (processIsAlreadyRunning(runningPID, cfgFile.getName())) { if (stopService) { log.info("stopping process..."); try { Runtime.getRuntime().exec("kill -9 " + runningPID); pidfile.delete(); } catch (IOException e1) { exit(1, "[" + runningPID + "] Could not stop service.", e1); } exit(0, "[" + runningPID + "] WaagenWatchService stopped."); } exit(1, "[error] Process already running (pid " + runningPID + ") ..."); } else { if (stopService) { pidfile.delete(); exit(0, "Specified WaagenWatchService is not running."); } // else: Write PID to PID file } } // write PID to PID file FileWriter w = null; try { w = new FileWriter(pidfile); w.write(myPID); } catch (IOException e) { exit(1, "IOException in pid file.", e); } finally { try { w.close(); } catch (IOException e) { } } // AbasRueckmeldung erzeugen if (!stopService) { /* * Configuration */ try { waageConfigurationReader.read(cfgFile); configuration = waageConfigurationReader.getConfiguration(); configuration.setPIDFile(pidfile); } catch (IOException e) { exit(1, e); } /* * Existing files */ log.info("Handle existing files..."); log.info("Starting WaagenWatchservice..."); AbasRueckmeldung abasrueck; Thread threadAbas = new Thread(abasrueck = new AbasRueckmeldung(waageConfigurationReader.getConfiguration())); threadAbas.start(); Long wartezaehler = new Long(0); if (abasrueck == null) { throw new NullPointerException("Es wurde kein Object abasRückmeldung angelegt!"); } while (!abasrueck.isConnected()) { wartezaehler = wartezaehler + 1; if (wartezaehler % 100 == 0) { log.info(wartezaehler.toString() + " Warten bis EDP-Verbindung steht"); } if (wartezaehler > 10000000) { exit( 1, "Es konnte keine EDP-Verbindung hergestellt werden! Der Waagen service hat sich beendet!"); } } if (threadAbas.isAlive()) { log.info("abasrueckmeldung Thread wurde erzeugt"); // Die einzelnen Waagenüberwachungen starten boolean alive = threadAbas.isAlive(); try { for (int i = 0; i < waageConfigurationReader.getConfiguration().getAnzahlWaagen(); i++) { log.trace("WaageThread " + i + " wird gestartet"); SocketClient socket = new SocketClient(waageConfigurationReader.getConfiguration(), i, abasrueck); } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error(e); } } else { System.err.println("abasrueckmeldung Thread konnte nicht erzeugt werden"); log.error("abasrueckmeldung Thread konnte nicht erzeugt werden"); } } // }
public void run() { BufferedInputStream in; InputStream is = null; try { is = socket.getInputStream(); in = new BufferedInputStream(is); log.trace(this.waageName + " an Stream horchen"); } catch (IOException e) { log.error(this.waageName + " Verbindungsaufbau geht schief", e); try { socket.close(); } catch (IOException e2) { log.error(this.waageName + "Socket not closed :" + e2); } return; } File pidFileSicherung = waageConfiguration.getPidFile(); String rueckString = ""; Boolean rueckMeldungActive = false; Boolean errorFlag = false; Boolean reconnect = false; while (!errorFlag) { log.trace(this.waageName + " Schleife Socketclient"); // Änderung da der direkte Aufruf von pidFileexists in die Hose ging. if (!waageConfiguration.pidFileexists()) { log.info(this.waageName + " pid-File existiert nicht mehr"); File pidfile = waageConfiguration.getPidFile(); log.error( this.waageName + " Das PID-File hat den Namen " + pidfile.getAbsolutePath() + " und das PID-Sicherung " + pidFileSicherung.getAbsolutePath()); if (!pidfile.exists()) { log.error(this.waageName + " Das pidfile existiert nicht!"); if (!pidFileSicherung.exists()) { log.error(this.waageName + " Das pidfileSicherung existiert auch nicht!"); errorFlag = true; } else { log.error(this.waageName + " Das pidfileSicherung existiert!"); } } } if (!socket.isConnected()) { log.error( this.waageName + " Socket Verbindung zu Waage " + this.waageName + " mit IP " + this.waageIP + " wurde unterbrochen!"); reconnect = true; } ; Rueckmeldung rueckMeldung = null; ArrayList<String> rueckschlange = new ArrayList<String>(); String inputString = null; try { inputString = readInputStream(in, this.waageName); // in.readLine(); log.info(this.waageName + " : " + inputString); if (inputString == null || reconnect) { // parent.error("Connection closed by client"); log.error( this.waageName + " Connection closed for waage " + this.waageName + " mit IP " + waageIP); // boolean isCon = socket.isConnected(); // boolean isbound = socket.isBound(); // boolean isinputshutdown = socket.isInputShutdown(); // boolean isoutputshutdown = socket.isOutputShutdown(); socket.close(); in.close(); is.close(); Boolean newSocket = false; while (!newSocket) { try { log.trace(this.waageName + " Vor neuer Socketverbindung"); this.socket = new Socket(waageIP, waagePort); this.socket.setKeepAlive(true); log.trace(this.waageName + " Nach neuer Socketverbindung"); is = socket.getInputStream(); log.trace(this.waageName + " Nach getinputstream"); // Stream schliessen, bevor wieder geöffnet wird in.close(); in = new BufferedInputStream(is); log.trace(this.waageName + " Nach BufferedInputstream"); newSocket = true; } catch (IOException e) { log.error( this.waageName + " Connection not opend for waage " + " mit IP " + waageIP, e); } catch (Exception e) { log.error(this.waageName + " neue Exception ", e); } log.trace(this.waageName + " Ende NewSocket Schleife"); } // zum Testen Daten wegschicken, da dann eine Antwort erfolgt log.trace(this.waageName + " Vor lampeAnschalten PIEPSLEISE"); TestSocket testSocket = new TestSocket(socket, this.waageName); log.trace(this.waageName + " Vor readInputStream"); inputString = readInputStream(in, this.waageName); log.info( "Die Waage" + this.waageName + " mit der IP-Adresse " + waageIP + " wird wieder überwacht"); reconnect = false; } if (rueckString != null) { if (rueckMeldungActive) { if (inputString.contains(ENDE_ZEICHEN)) { String teilString[] = inputString.split(ENDE_ZEICHEN); if (teilString.length > 0) { rueckString = rueckString + teilString[0]; rueckschlange.add(rueckString); log.trace(this.waageName + " RückmeldungString : " + rueckString); rueckMeldungActive = false; } for (int i = 1; i < teilString.length; i++) { if ((teilString[i].contains(ENDE_ZEICHEN)) & (teilString[i].contains(ANFANGS_ZEICHEN))) { rueckschlange.add(teilString[i]); log.trace(this.waageName + " RückmeldungString : " + teilString[1]); rueckMeldungActive = false; } else if (teilString[i].contains(ANFANGS_ZEICHEN)) { rueckString = teilString[i]; rueckMeldungActive = true; } } } else if (inputString.contains(ANFANGS_ZEICHEN)) { String teilString[] = inputString.split(ANFANGS_ZEICHEN); if (teilString.length > 0) { rueckString = teilString[0]; rueckMeldungActive = true; } } } else { // Falls kein Anfangszeichen enthalten ist, wird auch keine Rückmeldung erzeugt. if (inputString != null) { if (inputString.contains(ANFANGS_ZEICHEN)) { String teilString[] = inputString.split(ANFANGS_ZEICHEN); if (teilString.length > 1) { // Der Start beginnt ja erst nach dem Startzeichen for (int i = 1; i < teilString.length; i++) { if (teilString[i].contains(ENDE_ZEICHEN)) { rueckschlange.add(teilString[1]); log.trace(this.waageName + " RückmeldungString : " + teilString[1]); rueckMeldungActive = false; } else { rueckString = teilString[i]; rueckMeldungActive = true; } } } } } else { log.error("Die Variable inputstring ist null.Es erfolgt einreconnect"); reconnect = true; } } } for (String rueckMeldungString : rueckschlange) { rueckMeldung = new Rueckmeldung(rueckMeldungString); if (rueckMeldung.isRueckmeldung()) { rueckMeldung = this.abasrueckmeldung.meldung(rueckMeldung); Integer led = rueckMeldung.getLed(); switch (led) { case 1: // grüne Lampe anschalten rueckmeldungAnWaageSenden(LEDS.GREEN, rueckMeldung.getOfMenge()); break; case 2: // gelbe Lampe anschalten rueckmeldungAnWaageSenden(LEDS.YELLOW, rueckMeldung.getOfMenge()); break; case 3: // rote Lampe anschalten rueckmeldungAnWaageSenden(LEDS.RED, rueckMeldung.getOfMenge()); break; case 4: // leiser Piepser anschalten rueckmeldungAnWaageSenden(LEDS.PIEPSLEISE, rueckMeldung.getOfMenge()); break; case 5: // lauter Piepser anschalten rueckmeldungAnWaageSenden(LEDS.PIEPSLAUT, rueckMeldung.getOfMenge()); break; default: log.info("Break in Case Wert LED : " + led); break; } } } rueckschlange.clear(); } catch (SocketException e) { log.error(this.waageName + "Socketverbindung wurde unterbrochen!", e); reconnect = true; } catch (IOException e) { log.error(e); reconnect = true; } catch (CantChangeFieldValException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (CantBeginSessionException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (CantBeginEditException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (InvalidRowOperationException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (CantSaveException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (EDPException e) { log.error(this.waageName + "Rueckmeldung anlegen schiefgelaufen!", e); fehlerAnWaage("Rueckmeldung nicht erfolgreich"); } catch (Exception e) { log.error(this.waageName + " unbekannte Exception 2", e); } } // end of while log.trace(this.waageName + " PID FILE nicht gefunden - Socketclient wird beendet"); try { is.close(); in.close(); // socket.close(); } catch (Exception err) { } socket = null; } // end of run