+package org.wamblee.upnpmonitor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.wamblee.io.SimpleProcess;
+
+public class Monitor implements Runnable {
+
+ private static final Logger LOGGER = Logger.getLogger(Monitor.class
+ .getName());
+
+ private ScheduledThreadPoolExecutor executor;
+ private Config config;
+ private boolean serviceFound;
+ private UpnpStack stack;
+
+ public Monitor(Config aConfig) {
+ config = aConfig;
+ executor = new ScheduledThreadPoolExecutor(1);
+ }
+
+ public void start() {
+ serviceFound = true;
+ executor.scheduleWithFixedDelay(this, 0, config.getIntervalSeconds(),
+ TimeUnit.SECONDS);
+ executeCommand(config.getStartupCommand());
+ }
+
+ public synchronized void setServiceFound(boolean aServiceFound) {
+ serviceFound = aServiceFound;
+ }
+
+ public synchronized void run() {
+
+ if (!serviceFound) {
+ LOGGER.info("UPNP service is down, executing recovery");
+ // we need to execute recovery.
+ executeCommand(config.getShutdownCommand());
+ executeCommand(config.getStartupCommand());
+ setServiceFound(true);
+ // give process a chance to startup.
+ return;
+ }
+
+ shutdownStack();
+
+ setServiceFound(false);
+
+ stack = new UpnpStack(new UpnpStack.Listener() {
+ @Override
+ public void deviceAdded(String aDeviceString) {
+ LOGGER.fine("Device added: " + aDeviceString);
+ if (aDeviceString.toLowerCase().contains(
+ config.getPattern().toLowerCase())) {
+ synchronized (Monitor.this) {
+ setServiceFound(true);
+ }
+ }
+ }
+
+ @Override
+ public void deviceRemoved(String aDeviceString) {
+ LOGGER.fine("Device removed:" + aDeviceString);
+ }
+ });
+ stack.search();
+ }
+
+ private void shutdownStack() {
+ if (stack != null) {
+ stack.shutdown();
+ stack = null;
+ }
+ }
+
+ private void executeCommand(String command) {
+ LOGGER.info("Executing command: " + command);
+ SimpleProcess process = new SimpleProcess(new File("."), new String[] {
+ "sh", "-c", command });
+
+ try {
+ int ret = process.run();
+ LOGGER.info(process.getStdout());
+ LOGGER.info(process.getStderr());
+ LOGGER.info("Exit status: " + ret);
+ } catch (IOException e) {
+ LOGGER.log(Level.INFO, "Problem executing command", e);
+ }
+ }
+
+ public void stop() {
+ executor.shutdown();
+ shutdownStack();
+ executeCommand(config.getShutdownCommand());
+ }
+}