From c2b0bc89067fda22755e884a771b809463ea8e30 Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Sun, 23 Dec 2012 17:24:03 +0100 Subject: [PATCH] First version with monitoring. --- monitor/pom.xml | 4 + .../java/org/wamblee/upnpmonitor/Config.java | 47 ++++++++ .../java/org/wamblee/upnpmonitor/Main.java | 62 ++--------- .../java/org/wamblee/upnpmonitor/Monitor.java | 101 ++++++++++++++++++ .../org/wamblee/upnpmonitor/UpnpStack.java | 53 +++++++++ pom.xml | 5 + 6 files changed, 217 insertions(+), 55 deletions(-) create mode 100644 monitor/src/main/java/org/wamblee/upnpmonitor/Config.java create mode 100644 monitor/src/main/java/org/wamblee/upnpmonitor/Monitor.java create mode 100644 monitor/src/main/java/org/wamblee/upnpmonitor/UpnpStack.java diff --git a/monitor/pom.xml b/monitor/pom.xml index 544224b..0bab4a3 100644 --- a/monitor/pom.xml +++ b/monitor/pom.xml @@ -12,6 +12,10 @@ jar /monitor + + org.wamblee + wamblee-support-general + org.teleal.cling cling-core 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 index 0000000..d4e8c2c --- /dev/null +++ b/monitor/src/main/java/org/wamblee/upnpmonitor/Config.java @@ -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; + } +} diff --git a/monitor/src/main/java/org/wamblee/upnpmonitor/Main.java b/monitor/src/main/java/org/wamblee/upnpmonitor/Main.java index 8fc5b77..4d49b33 100644 --- a/monitor/src/main/java/org/wamblee/upnpmonitor/Main.java +++ b/monitor/src/main/java/org/wamblee/upnpmonitor/Main.java @@ -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 index 0000000..fab9fe6 --- /dev/null +++ b/monitor/src/main/java/org/wamblee/upnpmonitor/Monitor.java @@ -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 index 0000000..2940e37 --- /dev/null +++ b/monitor/src/main/java/org/wamblee/upnpmonitor/UpnpStack.java @@ -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 047451e..0f88432 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,11 @@ + org.wamblee + wamblee-support-general + 0.7 + + org.teleal.cling cling-core 1.0.5 -- 2.31.1