changeset 376:b84868793ef2

Fix for database not stopping n at service shutdown reviewed-by: rkennke review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-June/001837.html
author Mario Torre <neugens.limasoftware@gmail.com>
date Thu, 14 Jun 2012 22:06:19 +0200
parents 8b0c224f1d88
children 253b33b762b3
files client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java common/core/src/main/java/com/redhat/thermostat/common/Activator.java common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistryImpl.java common/core/src/main/java/com/redhat/thermostat/common/cli/LauncherImpl.java common/core/src/main/java/com/redhat/thermostat/common/cli/OSGiContext.java common/core/src/test/java/com/redhat/thermostat/common/cli/LauncherTest.java tools/src/main/java/com/redhat/thermostat/tools/ThermostatService.java tools/src/main/java/com/redhat/thermostat/tools/cli/ShellCommand.java tools/src/test/java/com/redhat/thermostat/tools/cli/ShellCommandTest.java
diffstat 12 files changed, 138 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java	Thu Jun 14 22:06:19 2012 +0200
@@ -49,9 +49,11 @@
 import com.redhat.thermostat.common.cli.Command;
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.cli.OSGiContext;
 
-public class GUIClientCommand implements Command {
+public class GUIClientCommand implements Command, OSGiContext {
 
+    private BundleContext context;
     private Main clientMain;
 
     public GUIClientCommand(Main clientMain) {
@@ -59,8 +61,12 @@
     }
 
     @Override
+    public void setBundleContext(BundleContext context) {
+        this.context = context;
+    }
+    
+    @Override
     public void run(CommandContext ctx) throws CommandException {
-        BundleContext context = ctx.getCommandContextFactory().getBundleContext();
         context.registerService(ApplicationService.class.getName(), new ApplicationServiceProvider(), null);
         context.registerService(ContextAction.class.getName(), new ContextActionServiceProvider(), null);
         
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java	Thu Jun 14 22:06:19 2012 +0200
@@ -68,7 +68,10 @@
 
         cmdReg = new CommandRegistryImpl(context);
         Main main = new Main(uiFacadeFactory, new String[0]);
-        cmdReg.registerCommands(Arrays.asList(new GUIClientCommand(main)));
+        
+        GUIClientCommand cmd = new GUIClientCommand(main);
+        cmd.setBundleContext(context);
+        cmdReg.registerCommands(Arrays.asList(cmd));
     }
 
     @Override
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java	Thu Jun 14 22:06:19 2012 +0200
@@ -81,10 +81,11 @@
     public void testRun() throws CommandException {
         BundleContext bCtx = mock(BundleContext.class);
         CommandContextFactory cmdCtxFactory = mock(CommandContextFactory.class);
-        when(cmdCtxFactory.getBundleContext()).thenReturn(bCtx);
+
         CommandContext cmdCtx = mock(CommandContext.class);
         when(cmdCtx.getCommandContextFactory()).thenReturn(cmdCtxFactory);
 
+        cmd.setBundleContext(bCtx);
         cmd.run(cmdCtx);
 
         verify(clientMain).run();
--- a/common/core/src/main/java/com/redhat/thermostat/common/Activator.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/Activator.java	Thu Jun 14 22:06:19 2012 +0200
@@ -61,7 +61,9 @@
         reg.registerCommands(cmds);
 
         CommandContextFactory cmdCtxFactory = new CommandContextFactory(context);
-        Launcher launcher = new LauncherImpl(cmdCtxFactory);
+        LauncherImpl launcher = new LauncherImpl(cmdCtxFactory);
+        launcher.setBundleContext(context);
+        
         launcherReg = context.registerService(Launcher.class.getName(), launcher, null);
     }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java	Thu Jun 14 22:06:19 2012 +0200
@@ -43,11 +43,8 @@
     private CommandRegistry commandRegistry;
     private Console console = new SystemConsole();
 
-    private BundleContext bundleContext;
-
     public CommandContextFactory(BundleContext ctx) {
         commandRegistry = new CommandRegistryImpl(ctx);
-        bundleContext = ctx;
     }
 
     public CommandContext createContext(Arguments args) {
@@ -65,9 +62,4 @@
     public Console getConsole() {
         return console ;
     }
-
-    public BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
 }
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistryImpl.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistryImpl.java	Thu Jun 14 22:06:19 2012 +0200
@@ -61,6 +61,10 @@
     }
 
     protected ServiceRegistration registerCommand(Command cmd) {
+        if (cmd instanceof OSGiContext) {
+            ((OSGiContext) cmd).setBundleContext(context);
+        }
+        
         Hashtable<String, String> props = new Hashtable<>();
         props.put(Command.NAME, cmd.getName());
         ServiceRegistration registration = context.registerService(Command.class.getName(), cmd, props);
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/LauncherImpl.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/LauncherImpl.java	Thu Jun 14 22:06:19 2012 +0200
@@ -40,6 +40,7 @@
 import java.util.Collection;
 import java.util.logging.Level;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 
 import com.redhat.thermostat.common.appctx.ApplicationContext;
@@ -48,7 +49,7 @@
 import com.redhat.thermostat.common.storage.ConnectionException;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
-public class LauncherImpl implements Launcher {
+public class LauncherImpl implements Launcher, OSGiContext {
 
     private static final String UNKNOWN_COMMAND_MESSAGE = "unknown command '%s'\n";
 
@@ -60,10 +61,17 @@
 
     private int usageCount = 0;
 
+    private BundleContext context;
+    
     public LauncherImpl(CommandContextFactory cmdCtxFactory) {
         this.cmdCtxFactory = cmdCtxFactory;
     }
 
+    @Override
+    public void setBundleContext(BundleContext context) {
+        this.context = context;
+    }
+    
     public void run(String[] args) {
         usageCount++;
         try {
@@ -87,7 +95,7 @@
         if (usageCount == 0) {
             try {
                 ApplicationContext.getInstance().getTimerFactory().shutdown();
-                cmdCtxFactory.getBundleContext().getBundle(0).stop();
+                context.getBundle(0).stop();
             } catch (BundleException e) {
                 throw (InternalError) new InternalError().initCause(e);
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/OSGiContext.java	Thu Jun 14 22:06:19 2012 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.common.cli;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * Interface that allows classes to carry a {@link BundleContext}.
+ */
+public interface OSGiContext {
+
+    void setBundleContext(BundleContext context);
+}
--- a/common/core/src/test/java/com/redhat/thermostat/common/cli/LauncherTest.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/common/core/src/test/java/com/redhat/thermostat/common/cli/LauncherTest.java	Thu Jun 14 22:06:19 2012 +0200
@@ -231,20 +231,26 @@
         });
         ctxFactory.getCommandRegistry().registerCommands(Arrays.asList(errorCmd));
 
-        new LauncherImpl(ctxFactory).run(new String[] { "error" });
+        LauncherImpl launcher = new LauncherImpl(ctxFactory);
+        launcher.setBundleContext(bundleContext);
+        launcher.run(new String[] { "error" });
         assertEquals("test error\n", ctxFactory.getError());
 
     }
 
     private void runAndVerifyCommand(String[] args, String expected) {
-        new LauncherImpl(ctxFactory).run(args);
+        LauncherImpl launcher = new LauncherImpl(ctxFactory);
+        launcher.setBundleContext(bundleContext);
+        launcher.run(args);
         assertEquals(expected, ctxFactory.getOutput());
         assertTrue(timerFactory.isShutdown());
     }
 
     @Test
     public void verifyStorageCommandSetsUpDAOFactory() {
-        new LauncherImpl(ctxFactory).run(new String[] { "test3" , "--dbUrl", "mongo://fluff:12345" });
+        LauncherImpl launcher = new LauncherImpl(ctxFactory);
+        launcher.setBundleContext(bundleContext);
+        launcher.run(new String[] { "test3" , "--dbUrl", "mongo://fluff:12345" });
         verify(appContextSetup).setupAppContext("mongo://fluff:12345");
     }
 
@@ -252,6 +258,7 @@
         ClientPreferences prefs = mock(ClientPreferences.class);
         when(prefs.getConnectionUrl()).thenReturn("mongo://fluff:12345");
         LauncherImpl l = new LauncherImpl(ctxFactory);
+        l.setBundleContext(bundleContext);
         l.setPreferences(prefs);
         l.run(new String[] { "test3" });
         verify(appContextSetup).setupAppContext("mongo://fluff:12345");
--- a/tools/src/main/java/com/redhat/thermostat/tools/ThermostatService.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/tools/src/main/java/com/redhat/thermostat/tools/ThermostatService.java	Thu Jun 14 22:06:19 2012 +0200
@@ -40,8 +40,11 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
 
 import com.redhat.thermostat.agent.AgentApplication;
@@ -54,6 +57,7 @@
 import com.redhat.thermostat.common.cli.CommandContextImpl;
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.cli.Launcher;
+import com.redhat.thermostat.common.cli.OSGiContext;
 import com.redhat.thermostat.common.cli.SimpleArgumentSpec;
 import com.redhat.thermostat.common.cli.SimpleArguments;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
@@ -68,7 +72,7 @@
  * Simple service that allows starting Agent and DB Backend
  * in a single step.
  */
-public class ThermostatService extends BasicCommand implements ActionListener<ApplicationState> {
+public class ThermostatService extends BasicCommand implements ActionListener<ApplicationState>, OSGiContext {
     
     private static final String NAME = "service";
 
@@ -83,7 +87,8 @@
     private ActionNotifier<ApplicationState> notifier;
 
     private CommandContext context;
-
+    private BundleContext bundleContext;
+    
     private List<Runnable> tasksOnStop = new CopyOnWriteArrayList<>();
 
     public ThermostatService() {
@@ -92,6 +97,11 @@
         notifier = new ActionNotifier<>(this);
     }
     
+    @Override
+    public void setBundleContext(BundleContext context) {
+        this.bundleContext = context;
+    }
+    
     private void addListeners() throws InvalidConfigurationException {
         // Currently, all the arguments are for the db. We only configure the
         // agent accordingly to the database settings.
@@ -136,10 +146,23 @@
                     @Override
                     public void run() {
                         String[] args = new String[] { "storage", "--stop" };
-                        BundleContext bCtx = context.getCommandContextFactory().getBundleContext();
-                        ServiceReference launcherRef = bCtx.getServiceReference(Launcher.class.getName());
-                        Launcher launcher = (Launcher) bCtx.getService(launcherRef);
-                        launcher.run(args);
+                        
+                        ServiceReference launcherRef = bundleContext.getServiceReference(Launcher.class.getName());
+                        if (launcherRef != null) {
+                            Launcher launcher = (Launcher) bundleContext.getService(launcherRef);
+                            launcher.run(args);
+                        } else {
+                            try {
+                                SimpleArguments arguments = new SimpleArguments();
+                                arguments.addArgument("stop", args[1]);
+                                database.run(new CommandContextImpl(arguments,
+                                        ThermostatService.this.context.getCommandContextFactory()));
+                                
+                            } catch (CommandException e) {
+                                Logger.getLogger(getClass().getSimpleName()).log(Level.WARNING, "Can't stop database", e);
+                            }
+                        }
+                        
                     }
                 });
                 
--- a/tools/src/main/java/com/redhat/thermostat/tools/cli/ShellCommand.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/tools/src/main/java/com/redhat/thermostat/tools/cli/ShellCommand.java	Thu Jun 14 22:06:19 2012 +0200
@@ -59,11 +59,12 @@
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.cli.Launcher;
+import com.redhat.thermostat.common.cli.OSGiContext;
 import com.redhat.thermostat.common.config.ConfigUtils;
 import com.redhat.thermostat.common.config.InvalidConfigurationException;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 
-public class ShellCommand implements Command {
+public class ShellCommand implements Command, OSGiContext {
 
     private static final Logger logger = LoggingUtils.getLogger(ShellCommand.class);
 
@@ -80,6 +81,8 @@
     private CommandContext context;
     private HistoryProvider historyProvider;
 
+    private BundleContext bundleContext;
+    
     static class HistoryProvider {
         public PersistentHistory get() {
             PersistentHistory history = null;
@@ -101,6 +104,11 @@
     }
 
     @Override
+    public void setBundleContext(BundleContext context) {
+        bundleContext = context;
+    }
+    
+    @Override
     public void run(CommandContext ctx) throws CommandException {
         context = ctx;
         Terminal term = TerminalFactory.create();
@@ -156,10 +164,9 @@
 
     private void launchCommand(String line) throws CommandException {
         String[] parsed = line.split(" ");
-        BundleContext bCtx = context.getCommandContextFactory().getBundleContext();
-        ServiceReference launcherRef = bCtx.getServiceReference(Launcher.class.getName());
+        ServiceReference launcherRef = bundleContext.getServiceReference(Launcher.class.getName());
         if (launcherRef != null) {
-            Launcher launcher = (Launcher) bCtx.getService(launcherRef);
+            Launcher launcher = (Launcher) bundleContext.getService(launcherRef);
             launcher.run(parsed);
         } else {
             throw new CommandException("Severe: Could not locate launcher");
--- a/tools/src/test/java/com/redhat/thermostat/tools/cli/ShellCommandTest.java	Wed Jun 13 21:34:41 2012 +0200
+++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/ShellCommandTest.java	Thu Jun 14 22:06:19 2012 +0200
@@ -86,6 +86,8 @@
     public void testBasic() throws CommandException {
         ServiceReference ref = mock(ServiceReference.class);
         BundleContext bundleContext = mock(BundleContext.class);
+        cmd.setBundleContext(bundleContext);
+        
         when(bundleContext.getServiceReference(Launcher.class.getName())).thenReturn(ref);
         Launcher launcher = mock(Launcher.class);
         when(bundleContext.getService(ref)).thenReturn(launcher);
@@ -151,12 +153,16 @@
 
         ServiceReference ref = mock(ServiceReference.class);
         BundleContext bundleContext = mock(BundleContext.class);
+        cmd.setBundleContext(bundleContext);
+        
         when(bundleContext.getServiceReference(Launcher.class.getName())).thenReturn(ref);
         Launcher launcher = mock(Launcher.class);
         when(bundleContext.getService(ref)).thenReturn(launcher);
         TestCommandContextFactory ctxFactory = new TestCommandContextFactory(bundleContext);
 
         cmd = new ShellCommand(provider);
+        cmd.setBundleContext(bundleContext);
+        
         // "\u001b[A" is the escape code for up-arrow. use xxd -p to generate
         ctxFactory.setInput("\u001b[A\nexit\n");
         Arguments args = new SimpleArguments();
@@ -181,8 +187,11 @@
         Launcher launcher = mock(Launcher.class);
         when(bundleContext.getService(ref)).thenReturn(launcher);
         TestCommandContextFactory ctxFactory = new TestCommandContextFactory(bundleContext);
-
+        cmd.setBundleContext(bundleContext);
+        
         cmd = new ShellCommand(provider);
+        cmd.setBundleContext(bundleContext);
+        
         ctxFactory.setInput("add-to-history\nexit\n");
         Arguments args = new SimpleArguments();
         CommandContext ctx = ctxFactory.createContext(args);