First version with monitoring.
authorErik Brakkee <erik@brakkee.org>
Sun, 23 Dec 2012 16:24:03 +0000 (17:24 +0100)
committerErik Brakkee <erik@brakkee.org>
Sun, 23 Dec 2012 16:24:03 +0000 (17:24 +0100)
monitor/pom.xml
monitor/src/main/java/org/wamblee/upnpmonitor/Config.java [new file with mode: 0644]
monitor/src/main/java/org/wamblee/upnpmonitor/Main.java
monitor/src/main/java/org/wamblee/upnpmonitor/Monitor.java [new file with mode: 0644]
monitor/src/main/java/org/wamblee/upnpmonitor/UpnpStack.java [new file with mode: 0644]
pom.xml

index 544224b821d6e18b47252d4edb879a3d28030e3f..0bab4a35242278fa3eff2b959c36769e1f2657f5 100644 (file)
   <packaging>jar</packaging>
   <name>/monitor</name>
   <dependencies>
+      <dependency>
+          <groupId>org.wamblee</groupId>
+          <artifactId>wamblee-support-general</artifactId>
+      </dependency>
       <dependency>
           <groupId>org.teleal.cling</groupId>
           <artifactId>cling-core</artifactId>
diff --git a/monitor/src/main/java/org/wamblee/upnpmonitor/Config.java b/monitor/src/main/java/org/wamblee/upnpmonitor/Config.java
new file mode 100644 (file)
index 0000000..d4e8c2c
--- /dev/null
@@ -0,0 +1,47 @@
+package org.wamblee.upnpmonitor;
+
+import java.util.Properties;
+
+public class Config {
+
+    public static final String INTERVAL_SECONDS = "org.wamblee.upnpmonitor.intervalSeconds";
+    public static final String STARTUP_COMMAND = "org.wamblee.upnpmonitor.startupCommand";
+    public static final String SHUTDOWN_COMMAND = "org.wamblee.upnpmonitor.shutdownCommand";
+    public static final String PATTERN = "org.wamblee.upnpmonitor.pattern";
+
+    private int intervalSeconds;
+    private String startupCommand;
+    private String shutdownCommand;
+    private String pattern;
+
+    public static Config parse(Properties aProperties) {
+        return new Config(Integer.parseInt(aProperties.getProperty(
+            INTERVAL_SECONDS, "30")), aProperties.getProperty(STARTUP_COMMAND),
+            aProperties.getProperty(SHUTDOWN_COMMAND),
+            aProperties.getProperty(PATTERN));
+    }
+
+    public Config(int aIntervalSeconds, String aStartupCommand,
+        String aShutdownCommand, String aPattern) {
+        intervalSeconds = aIntervalSeconds;
+        startupCommand = aStartupCommand;
+        shutdownCommand = aShutdownCommand;
+        pattern = aPattern;
+    }
+
+    public int getIntervalSeconds() {
+        return intervalSeconds;
+    }
+
+    public String getStartupCommand() {
+        return startupCommand;
+    }
+
+    public String getShutdownCommand() {
+        return shutdownCommand;
+    }
+
+    public String getPattern() {
+        return pattern;
+    }
+}
index 8fc5b778dd49d5ae58d9712ad36ca9ecece547e4..4d49b33a7e115b2ca90de619b1ec82f49c253db9 100644 (file)
@@ -2,73 +2,25 @@ package org.wamblee.upnpmonitor;
 
 import java.util.logging.Logger;
 
-import org.teleal.cling.UpnpService;
-import org.teleal.cling.UpnpServiceImpl;
-import org.teleal.cling.controlpoint.ControlPoint;
-import org.teleal.cling.model.message.header.DeviceTypeHeader;
-import org.teleal.cling.model.meta.Device;
-import org.teleal.cling.model.types.DeviceType;
-import org.teleal.cling.registry.DefaultRegistryListener;
-import org.teleal.cling.registry.Registry;
-import org.teleal.cling.registry.RegistryListener;
-
 public class Main {
 
     private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
 
-    public static class UpnpStack {
-        private UpnpService upnpService;
-        private ControlPoint controlPoint;
-        private DeviceType deviceType;
-
-        public UpnpStack() {
-            RegistryListener listener = new DefaultRegistryListener() {
-                @Override
-                public void deviceAdded(Registry aRegistry, Device aDevice) {
-                    super.deviceAdded(aRegistry, aDevice);
-                    System.out.println("Device added: " +
-                        aDevice.getDisplayString());
-                    System.out.println(aDevice.getType());
-                }
-
-                @Override
-                public void deviceRemoved(Registry aRegistry, Device aDevice) {
-                    super.deviceRemoved(aRegistry, aDevice);
-                    System.out.println("Device removed: " +
-                        aDevice.getDisplayString());
-                }
-            };
-            upnpService = new UpnpServiceImpl(listener);
-            controlPoint = upnpService.getControlPoint();
-            deviceType = new DeviceType("schemas-upnp-org", "MediaServer");
-
-        }
-
-        public void search() {
-            controlPoint.search(new DeviceTypeHeader(deviceType));
-        }
+    public static void main(String[] aArgs) throws Exception {
 
-        public void shutdown() {
-            upnpService.shutdown();
-        }
-    }
+        Config config = new Config(30, "echo starting", "echo stopping",
+            "mediatomb");
 
-    public static void main(String[] aArgs) throws Exception {
+        final Monitor monitor = new Monitor(config);
 
         Runtime.getRuntime().addShutdownHook(new Thread() {
             @Override
             public void run() {
-                System.out.println("Shutdown hook");
+                System.out.println("Signal caught, terminating monitor");
+                monitor.stop();
             }
         });
 
-        for (;;) {
-            UpnpStack stack = new UpnpStack();
-            stack.search();
-            Thread.sleep(10000);
-            stack.shutdown();
-
-        }
-
+        monitor.start();
     }
 }
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());
+    }
+}
diff --git a/monitor/src/main/java/org/wamblee/upnpmonitor/UpnpStack.java b/monitor/src/main/java/org/wamblee/upnpmonitor/UpnpStack.java
new file mode 100644 (file)
index 0000000..2940e37
--- /dev/null
@@ -0,0 +1,53 @@
+package org.wamblee.upnpmonitor;
+
+import org.teleal.cling.UpnpService;
+import org.teleal.cling.UpnpServiceImpl;
+import org.teleal.cling.controlpoint.ControlPoint;
+import org.teleal.cling.model.message.header.DeviceTypeHeader;
+import org.teleal.cling.model.meta.Device;
+import org.teleal.cling.model.types.DeviceType;
+import org.teleal.cling.registry.DefaultRegistryListener;
+import org.teleal.cling.registry.Registry;
+import org.teleal.cling.registry.RegistryListener;
+
+public class UpnpStack {
+
+    public static interface Listener {
+
+        void deviceAdded(String aDeviceString);
+
+        void deviceRemoved(String aDeviceString);
+    }
+
+    private UpnpService upnpService;
+    private ControlPoint controlPoint;
+    private DeviceType deviceType;
+
+    public UpnpStack(final Listener aListener) {
+        RegistryListener listener = new DefaultRegistryListener() {
+            @Override
+            public void deviceAdded(Registry aRegistry, Device aDevice) {
+                super.deviceAdded(aRegistry, aDevice);
+                aListener.deviceAdded(aDevice.getDisplayString());
+            }
+
+            @Override
+            public void deviceRemoved(Registry aRegistry, Device aDevice) {
+                super.deviceRemoved(aRegistry, aDevice);
+                aListener.deviceRemoved(aDevice.getDisplayString());
+            }
+        };
+        upnpService = new UpnpServiceImpl(listener);
+        controlPoint = upnpService.getControlPoint();
+        deviceType = new DeviceType("schemas-upnp-org", "MediaServer");
+
+    }
+
+    public void search() {
+        controlPoint.search(new DeviceTypeHeader(deviceType));
+    }
+
+    public void shutdown() {
+        upnpService.shutdown();
+    }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 047451e84efdb958b6665f69e0f7437f89f5fd47..0f884327f117556c1b38d07d1cd2eec39a3916ac 100644 (file)
--- a/pom.xml
+++ b/pom.xml
        <dependencyManagement>
                <dependencies>
                    <dependency>
+                <groupId>org.wamblee</groupId>
+                <artifactId>wamblee-support-general</artifactId>
+                <version>0.7</version>
+            </dependency>
+                   <dependency>
                 <groupId>org.teleal.cling</groupId>
                 <artifactId>cling-core</artifactId>
                 <version>1.0.5</version>