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");
      }
    }

    //

  }
示例#3
0
  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