First version with monitoring.
[upnpmonitor] / monitor / src / main / java / org / wamblee / upnpmonitor / Monitor.java
diff --git a/monitor/src/main/java/org/wamblee/upnpmonitor/Monitor.java b/monitor/src/main/java/org/wamblee/upnpmonitor/Monitor.java
new file mode 100644 (file)
index 0000000..fab9fe6
--- /dev/null
@@ -0,0 +1,101 @@
+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());
+    }
+}