# HG changeset patch # User Severin Gehwolf # Date 1348244261 -7200 # Node ID 9e4437930235af462e4967ab8d6d7223bc91207b # Parent bb3d671fe253176fdfa7cfb16716bab01803a8c7 Add DB connection service This should improve usability of the Thermostat shell. In particular in a remote setup. The current situation is that if a shell is fired up it does not make a connection to storage. So if a user has storage set up to bind to a "public" IP, 192.1.1.129 say, then mongo requires username/password for connections. This results in bad usability of the shell: ./bin/thermostat shell Thermostat > ping Could not connect to db mongodb://192.168.1.14:27518 (creds are missing or incorrect host IP in user prefs) Thermostat > ping --username blah --password blah -d mongodb://example.org (works) Thermostat > list-vms --username blah --password blah -d ... (i.e. a user needs to pass credential info for every command on the shell). This patch introduces a "connect" and "disconnect" command which establishes a DB connection on demand and registers a DbService. The above shell session becomes: ./bin/thermostat shell Thermostat > ping Could not connect to db mongodb://192.168.1.14:27518 Thermostat > connect -d mongodb://192.168.1.14:27518 -u blah -p blah Thermostat > ping agent-id (works) Thermostat > list-vms (works) Thermostat > disconnect (disconnects from mongo storage at 192.168.1.14:27518) Thermostat > ping Could not connect to db mongodb://192.168.1.14:27518 Details of the patch: ----------------------------------------------------------------- 1. It removes AppContextSetup/AppContextSetupImpl 2. Modifies LauncherImpl in order to use the new DbService (i.e. other use cases remain the same) 3. OSGIUtils now returns the ServiceRegistration for registered services. 4. Added a method which allows services to be null to OSGIUtils. Existing getService() throws a NPE if the service reference is null (bundleContext.getServiceReference(clazz)). 5. Adds ConnectCommand ("connect" on shell) 6. Adds DisconnectCommand ("disconnect" on shell) 7. Tests Reviewed-by: omajid Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-September/003341.html PR1164 diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/cli/AppContextSetupImpl.java --- a/common/core/src/main/java/com/redhat/thermostat/common/cli/AppContextSetupImpl.java Thu Sep 20 18:07:27 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * 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 - * . - * - * 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 com.redhat.thermostat.common.appctx.ApplicationContext; -import com.redhat.thermostat.common.config.StartupConfiguration; -import com.redhat.thermostat.common.dao.DAOFactory; -import com.redhat.thermostat.common.dao.MongoDAOFactory; -import com.redhat.thermostat.common.storage.Connection; -import com.redhat.thermostat.common.storage.MongoStorageProvider; -import com.redhat.thermostat.common.storage.StorageProvider; - -class AppContextSetupImpl implements AppContextSetup { - - @Override - public void setupAppContext(String dbUrl, String username, String password) { - StartupConfiguration config = new ConnectionConfiguration(dbUrl, username, password); - - StorageProvider connProv = new MongoStorageProvider(config); - DAOFactory daoFactory = new MongoDAOFactory(connProv); - Connection connection = daoFactory.getConnection(); - connection.connect(); - ApplicationContext.getInstance().setDAOFactory(daoFactory); - - } - -} diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContext.java --- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContext.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContext.java Fri Sep 21 18:17:41 2012 +0200 @@ -45,8 +45,6 @@ CommandRegistry getCommandRegistry(); - AppContextSetup getAppContextSetup(); - CommandContextFactory getCommandContextFactory(); } diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java --- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextFactory.java Fri Sep 21 18:17:41 2012 +0200 @@ -51,10 +51,6 @@ return new CommandContextImpl(args, this); } - protected AppContextSetup getAppContextSetup() { - return new AppContextSetupImpl(); - } - public CommandRegistry getCommandRegistry() { return commandRegistry; } diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextImpl.java --- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextImpl.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandContextImpl.java Fri Sep 21 18:17:41 2012 +0200 @@ -62,11 +62,6 @@ } @Override - public AppContextSetup getAppContextSetup() { - return commandContextFactory.getAppContextSetup(); - } - - @Override public CommandContextFactory getCommandContextFactory() { return commandContextFactory; } diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/cli/ConnectionConfiguration.java --- a/common/core/src/main/java/com/redhat/thermostat/common/cli/ConnectionConfiguration.java Thu Sep 20 18:07:27 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * 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 - * . - * - * 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 com.redhat.thermostat.common.config.StartupConfiguration; - -class ConnectionConfiguration implements StartupConfiguration, AuthenticationConfiguration { - - private String dbUrl; - private String username; - private String password; - - ConnectionConfiguration(String dbUrl, String username, String password) { - this.dbUrl = dbUrl; - this.username = username; - this.password = password; - } - - @Override - public String getDBConnectionString() { - return dbUrl; - } - - @Override - public String getUsername() { - return username; - } - - @Override - public String getPassword() { - return password; - } -} diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/common/utils/OSGIUtils.java --- a/common/core/src/main/java/com/redhat/thermostat/common/utils/OSGIUtils.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/utils/OSGIUtils.java Fri Sep 21 18:17:41 2012 +0200 @@ -41,6 +41,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; public class OSGIUtils { @@ -55,6 +56,13 @@ instance = utils; } + /** + * Gets a service and never return null. It will throw a NullPointerException + * before it returns. + * + * @param clazz + * @return The best matching service implementation for the requested clazz. + */ @SuppressWarnings({ "rawtypes", "unchecked" }) public E getService(Class clazz) { BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext(); @@ -62,12 +70,24 @@ return (E) ctx.getService(ref); } - public void registerService(Class serviceClass, E service) { - registerService(serviceClass, service, null); + @SuppressWarnings({ "rawtypes", "unchecked" }) + public E getServiceAllowNull(Class clazz) { + BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext(); + ServiceReference ref = ctx.getServiceReference(clazz.getName()); + if (ref == null) { + return null; + } + return (E) ctx.getService(ref); + } + + @SuppressWarnings("rawtypes") + public ServiceRegistration registerService(Class serviceClass, E service) { + return registerService(serviceClass, service, null); } - public void registerService(Class serviceClass, E service, Dictionary properties) { + @SuppressWarnings("rawtypes") + public ServiceRegistration registerService(Class serviceClass, E service, Dictionary properties) { BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext(); - ctx.registerService(serviceClass.getName(), service, properties); + return ctx.registerService(serviceClass.getName(), service, properties); } } diff -r bb3d671fe253 -r 9e4437930235 common/core/src/main/java/com/redhat/thermostat/test/TestCommandContextFactory.java --- a/common/core/src/main/java/com/redhat/thermostat/test/TestCommandContextFactory.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/test/TestCommandContextFactory.java Fri Sep 21 18:17:41 2012 +0200 @@ -68,14 +68,6 @@ private CommandRegistry commandRegistry = new TestCommandRegistry(); - private AppContextSetup appContextSetup = new AppContextSetup() { - - @Override - public void setupAppContext(String dbUrl, String username, String password) { - // We do nothing for now. - } - }; - private TestConsole console; private PipedOutputStream inOut; @@ -118,11 +110,6 @@ } @Override - public AppContextSetup getAppContextSetup() { - return TestCommandContextFactory.this.getAppContextSetup(); - } - - @Override public CommandContextFactory getCommandContextFactory() { return TestCommandContextFactory.this; } @@ -135,11 +122,6 @@ return commandRegistry; } - @Override - protected AppContextSetup getAppContextSetup() { - return appContextSetup; - } - public String getOutput() { return new String(out.toByteArray()); } diff -r bb3d671fe253 -r 9e4437930235 common/core/src/test/java/com/redhat/thermostat/common/cli/CommandContextFactoryTest.java --- a/common/core/src/test/java/com/redhat/thermostat/common/cli/CommandContextFactoryTest.java Thu Sep 20 18:07:27 2012 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/cli/CommandContextFactoryTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -36,7 +36,6 @@ package com.redhat.thermostat.common.cli; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; @@ -67,7 +66,6 @@ Arguments args = mock(Arguments.class); CommandContext ctx = cmdCtxFactory.createContext(args); assertSame(args, ctx.getArguments()); - assertNotNull(ctx.getAppContextSetup()); assertSame(cmdCtxFactory, ctx.getCommandContextFactory()); assertSame(cmdCtxFactory.getCommandRegistry(), ctx.getCommandRegistry()); assertSame(cmdCtxFactory.getConsole(), ctx.getConsole()); diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/CommonCommandOptions.java --- a/launcher/src/main/java/com/redhat/thermostat/launcher/CommonCommandOptions.java Thu Sep 20 18:07:27 2012 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/CommonCommandOptions.java Fri Sep 21 18:17:41 2012 +0200 @@ -14,9 +14,9 @@ public static final String USERNAME_ARG = "username"; public static final String PASSWORD_ARG = "password"; - private static final String DB_URL_DESC = "the URL of the storage to connect to"; - private static final String USERNAME_DESC = "the username to use for authentication"; - private static final String PASSWORD_DESC = "the password to use for authentication"; + public static final String DB_URL_DESC = "the URL of the storage to connect to"; + public static final String USERNAME_DESC = "the username to use for authentication"; + public static final String PASSWORD_DESC = "the password to use for authentication"; public static final String LOG_LEVEL_ARG = "logLevel"; private static final String LOG_LEVEL_DESC = "log level"; diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/DbService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/DbService.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,72 @@ +/* + * 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 + * . + * + * 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.launcher; + +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.common.storage.ConnectionException; + +public interface DbService { + + /** + * Connects to the given database. + * + * @throws ConnectionException If DB connection cannot be established. + */ + void connect() throws ConnectionException; + + + /** + * Disconnects from the database. + * + * @throws ConnectionException + */ + void disconnect() throws ConnectionException; + + /** + * Get the registration for this service. + * @return + */ + @SuppressWarnings("rawtypes") + ServiceRegistration getServiceRegistration(); + + /** + * Set the registration suitable for this service. + */ + @SuppressWarnings("rawtypes") + void setServiceRegistration(ServiceRegistration registration); +} \ No newline at end of file diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/DbServiceFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/DbServiceFactory.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,50 @@ +/* + * 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 + * . + * + * 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.launcher; + +import com.redhat.thermostat.launcher.internal.DbServiceImpl; + +/** + * Factory in order to be able to hide the BbService implementation. + * + */ +public class DbServiceFactory { + + public static DbService createDbService(String username, String password, String dbUrl) { + return DbServiceImpl.create(username, password, dbUrl); + } +} diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/internal/ConnectionConfiguration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/ConnectionConfiguration.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,68 @@ +/* + * 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 + * . + * + * 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.launcher.internal; + +import com.redhat.thermostat.common.cli.AuthenticationConfiguration; +import com.redhat.thermostat.common.config.StartupConfiguration; + +class ConnectionConfiguration implements StartupConfiguration, AuthenticationConfiguration { + + private String dbUrl; + private String username; + private String password; + + ConnectionConfiguration(String dbUrl, String username, String password) { + this.dbUrl = dbUrl; + this.username = username; + this.password = password; + } + + @Override + public String getDBConnectionString() { + return dbUrl; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } +} diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/internal/DbServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/DbServiceImpl.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,117 @@ +/* + * 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 + * . + * + * 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.launcher.internal; + +import java.util.Objects; + +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.config.StartupConfiguration; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.MongoDAOFactory; +import com.redhat.thermostat.common.storage.Connection; +import com.redhat.thermostat.common.storage.ConnectionException; +import com.redhat.thermostat.common.storage.MongoStorageProvider; +import com.redhat.thermostat.common.storage.StorageProvider; +import com.redhat.thermostat.launcher.DbService; + +public class DbServiceImpl implements DbService { + + private String username; + private String password; + private String dbUrl; + @SuppressWarnings("rawtypes") + private ServiceRegistration registration; + + + DbServiceImpl(String username, String password, String dbUrl) { + this.username = username; + this.password = password; + this.dbUrl = dbUrl; + } + + /* + * (non-Javadoc) + * @see com.redhat.thermostat.launcher.DbService#connect() + */ + public void connect() throws ConnectionException { + StartupConfiguration config = new ConnectionConfiguration(dbUrl, username, password); + + StorageProvider connProv = new MongoStorageProvider(config); + DAOFactory daoFactory = new MongoDAOFactory(connProv); + Connection connection = daoFactory.getConnection(); + connection.connect(); + ApplicationContext.getInstance().setDAOFactory(daoFactory); + } + + /* + * (non-Javadoc) + * @see com.redhat.thermostat.launcher.DbService#disconnect() + */ + public void disconnect() throws ConnectionException { + DAOFactory factory = ApplicationContext.getInstance().getDAOFactory(); + Connection connection = factory.getConnection(); + connection.disconnect(); + ApplicationContext.getInstance().setDAOFactory(null); + } + + + + /** + * Factory method for creating a DbService instance. + * + * @param username + * @param password + * @param dbUrl + * @return + */ + public static DbService create(String username, String password, String dbUrl) { + return new DbServiceImpl(username, password, dbUrl); + } + + @SuppressWarnings("rawtypes") + @Override + public ServiceRegistration getServiceRegistration() { + return registration; + } + + @Override + public void setServiceRegistration(@SuppressWarnings("rawtypes") ServiceRegistration registration) { + this.registration = Objects.requireNonNull(registration); + } +} diff -r bb3d671fe253 -r 9e4437930235 launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java --- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Thu Sep 20 18:07:27 2012 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Fri Sep 21 18:17:41 2012 +0200 @@ -45,6 +45,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.ServiceRegistration; import com.redhat.thermostat.bundles.OSGiRegistry; import com.redhat.thermostat.common.ActionListener; @@ -67,6 +68,8 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.common.utils.OSGIUtils; import com.redhat.thermostat.launcher.CommonCommandOptions; +import com.redhat.thermostat.launcher.DbService; +import com.redhat.thermostat.launcher.DbServiceFactory; import com.redhat.thermostat.launcher.Launcher; import com.redhat.thermostat.utils.keyring.Keyring; @@ -253,29 +256,37 @@ return args; } + @SuppressWarnings("rawtypes") private CommandContext setupCommandContext(Command cmd, Arguments args) throws CommandException { + CommandContext ctx = cmdCtxFactory.createContext(args); + if (prefs == null) { prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class)); } - CommandContext ctx = cmdCtxFactory.createContext(args); if (cmd.isStorageRequired()) { - String dbUrl = ctx.getArguments().getArgument(CommonCommandOptions.DB_URL_ARG); - if (dbUrl == null) { - dbUrl = prefs.getConnectionUrl(); - } - String username = ctx.getArguments().getArgument(CommonCommandOptions.USERNAME_ARG); - String password = ctx.getArguments().getArgument(CommonCommandOptions.PASSWORD_ARG); - try { - ctx.getAppContextSetup().setupAppContext(dbUrl, username, password); - } catch (ConnectionException ex) { - throw new CommandException("Could not connect to: " + dbUrl, ex); + DbService service = OSGIUtils.getInstance().getServiceAllowNull(DbService.class); + if (service == null) { + String dbUrl = ctx.getArguments().getArgument(CommonCommandOptions.DB_URL_ARG); + if (dbUrl == null) { + dbUrl = prefs.getConnectionUrl(); + } + String username = ctx.getArguments().getArgument(CommonCommandOptions.USERNAME_ARG); + String password = ctx.getArguments().getArgument(CommonCommandOptions.PASSWORD_ARG); + service = DbServiceFactory.createDbService(username, password, dbUrl); + try { + service.connect(); + } catch (ConnectionException ex) { + throw new CommandException("Could not connect to: " + dbUrl, ex); + } + ServiceRegistration registration = OSGIUtils.getInstance().registerService(DbService.class, service); + service.setServiceRegistration(registration); } } return ctx; } - + private boolean isVersionQuery() { return args[0].equals(Version.VERSION_OPTION); } diff -r bb3d671fe253 -r 9e4437930235 launcher/src/test/java/com/redhat/thermostat/launcher/LauncherTest.java --- a/launcher/src/test/java/com/redhat/thermostat/launcher/LauncherTest.java Thu Sep 20 18:07:27 2012 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/LauncherTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -41,6 +41,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Matchers.any; import java.text.MessageFormat; import java.util.ArrayList; @@ -58,6 +59,7 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -69,7 +71,6 @@ import com.redhat.thermostat.common.Version; import com.redhat.thermostat.common.appctx.ApplicationContext; import com.redhat.thermostat.common.appctx.ApplicationContextUtil; -import com.redhat.thermostat.common.cli.AppContextSetup; import com.redhat.thermostat.common.cli.Arguments; import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; @@ -79,6 +80,7 @@ import com.redhat.thermostat.common.locale.Translate; import com.redhat.thermostat.common.tools.ApplicationState; import com.redhat.thermostat.common.tools.BasicCommand; +import com.redhat.thermostat.common.utils.OSGIUtils; import com.redhat.thermostat.launcher.internal.HelpCommand; import com.redhat.thermostat.launcher.internal.LauncherImpl; import com.redhat.thermostat.test.TestCommandContextFactory; @@ -88,7 +90,7 @@ import com.redhat.thermostat.utils.keyring.KeyringProvider; @RunWith(PowerMockRunner.class) -@PrepareForTest(FrameworkUtil.class) +@PrepareForTest({FrameworkUtil.class, DbServiceFactory.class}) public class LauncherTest { private static String defaultKeyringProvider; @@ -123,7 +125,6 @@ } private TestCommandContextFactory ctxFactory; - private AppContextSetup appContextSetup; private BundleContext bundleContext; private TestTimerFactory timerFactory; private OSGiRegistry registry; @@ -169,22 +170,15 @@ } private void setupCommandContextFactory() { - appContextSetup = mock(AppContextSetup.class); Bundle sysBundle = mock(Bundle.class); bundleContext = mock(BundleContext.class); when(bundleContext.getBundle(0)).thenReturn(sysBundle); - ctxFactory = new TestCommandContextFactory(bundleContext) { - @Override - protected AppContextSetup getAppContextSetup() { - return appContextSetup; - } - }; + ctxFactory = new TestCommandContextFactory(bundleContext); } @After public void tearDown() { - appContextSetup = null; ctxFactory = null; ApplicationContextUtil.resetApplicationContext(); } @@ -300,32 +294,63 @@ public void verifyStorageCommandSetsUpDAOFactory() { LauncherImpl launcher = new LauncherImpl(bundleContext, ctxFactory, registry); Keyring keyring = mock(Keyring.class); + Bundle sysBundle = mock(Bundle.class); + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(OSGIUtils.class)).thenReturn(sysBundle); + when(sysBundle.getBundleContext()).thenReturn(bundleContext); + PowerMockito.mockStatic(DbServiceFactory.class); + String dbUrl = "mongo://fluff:12345"; + DbService dbService = mock(DbService.class); + when(DbServiceFactory.createDbService(null, null, dbUrl)).thenReturn(dbService); launcher.setPreferences(new ClientPreferences(keyring)); - launcher.setArgs(new String[] { "test3" , "--dbUrl", "mongo://fluff:12345" }); + launcher.setArgs(new String[] { "test3" , "--dbUrl", dbUrl }); launcher.run(); - verify(appContextSetup).setupAppContext("mongo://fluff:12345", null, null); + verify(dbService).connect(); + verify(dbService).setServiceRegistration(any(ServiceRegistration.class)); } @Test public void verifyStorageCommandSetsUpDAOFactoryWithAuth() { LauncherImpl launcher = new LauncherImpl(bundleContext, ctxFactory, registry); Keyring keyring = mock(Keyring.class); + Bundle sysBundle = mock(Bundle.class); + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(OSGIUtils.class)).thenReturn(sysBundle); + when(sysBundle.getBundleContext()).thenReturn(bundleContext); + PowerMockito.mockStatic(DbServiceFactory.class); + String dbUrl = "mongo://fluff:12345"; + String testUser = "testUser"; + String testPasswd = "testPassword"; + DbService dbService = mock(DbService.class); + when(DbServiceFactory.createDbService(testUser, testPasswd, dbUrl)).thenReturn(dbService); + launcher.setPreferences(new ClientPreferences(keyring)); - launcher.setArgs(new String[] { "test3" , "--dbUrl", "mongo://fluff:12345", "--username", "testuser", "--password", "testpwd" }); + launcher.setArgs(new String[] { "test3" , "--dbUrl", dbUrl, "--username", testUser, "--password", testPasswd }); launcher.run(); - verify(appContextSetup).setupAppContext("mongo://fluff:12345", "testuser", "testpwd"); + verify(dbService).connect(); + verify(dbService).setServiceRegistration(any(ServiceRegistration.class)); } public void verifyPrefsAreUsed() { ClientPreferences prefs = mock(ClientPreferences.class); - when(prefs.getConnectionUrl()).thenReturn("mongo://fluff:12345"); + String dbUrl = "mongo://fluff:12345"; + when(prefs.getConnectionUrl()).thenReturn(dbUrl); LauncherImpl l = new LauncherImpl(bundleContext, ctxFactory, registry); + Bundle sysBundle = mock(Bundle.class); + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(OSGIUtils.class)).thenReturn(sysBundle); + when(sysBundle.getBundleContext()).thenReturn(bundleContext); + PowerMockito.mockStatic(DbServiceFactory.class); + DbService dbService = mock(DbService.class); + // this makes sure that dbUrl is indeed retrieved from preferences + when(DbServiceFactory.createDbService(null, null, dbUrl)).thenReturn(dbService); l.setPreferences(prefs); l.setArgs(new String[] { "test3" }); l.run(); - verify(appContextSetup).setupAppContext("mongo://fluff:12345", null, null); + verify(dbService).connect(); + verify(dbService).setServiceRegistration(any(ServiceRegistration.class)); } @Test diff -r bb3d671fe253 -r 9e4437930235 launcher/src/test/java/com/redhat/thermostat/launcher/internal/DbServiceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/DbServiceTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,72 @@ +/* + * 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 + * . + * + * 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.launcher.internal; + +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.launcher.DbService; + +public class DbServiceTest { + + private DbService dbService; + + @Before + public void setup() { + String dbUrl = "mongodb://testhost.example.com:19223"; + dbService = new DbServiceImpl("tester", "testerpassword", dbUrl); + } + + @After + public void teardown() { + dbService = null; + } + + @Test + public void testSetRegistrationRegistryThrowsException() { + try { + dbService.setServiceRegistration(null); + fail("Null registrations not allowed"); + } catch (Exception e) { + // pass + } + } + +} diff -r bb3d671fe253 -r 9e4437930235 tools/src/main/java/com/redhat/thermostat/tools/LocaleResources.java --- a/tools/src/main/java/com/redhat/thermostat/tools/LocaleResources.java Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/main/java/com/redhat/thermostat/tools/LocaleResources.java Fri Sep 21 18:17:41 2012 +0200 @@ -50,6 +50,14 @@ COMMAND_VM_STAT_DESCRIPTION, COMMAND_VM_STAT_ARGUMENT_CONTINUOUS_DESCRIPTION, + + COMMAND_CONNECT_DESCRIPTION, + COMMAND_CONNECT_ALREADY_CONNECTED, + COMMAND_CONNECT_FAILED_TO_CONNECT, + + COMMAND_DISCONNECT_DESCRIPTION, + COMMAND_DISCONNECT_NOT_CONNECTED, + COMMAND_DISCONNECT_ERROR, VM_INFO_PROCESS_ID, VM_INFO_START_TIME, diff -r bb3d671fe253 -r 9e4437930235 tools/src/main/java/com/redhat/thermostat/tools/cli/ConnectCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/cli/ConnectCommand.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,137 @@ +/* + * 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 + * . + * + * 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.tools.cli; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.common.cli.ArgumentSpec; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleArgumentSpec; +import com.redhat.thermostat.common.cli.SimpleCommand; +import com.redhat.thermostat.common.config.ClientPreferences; +import com.redhat.thermostat.common.storage.ConnectionException; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.launcher.CommonCommandOptions; +import com.redhat.thermostat.launcher.DbService; +import com.redhat.thermostat.launcher.DbServiceFactory; +import com.redhat.thermostat.tools.LocaleResources; +import com.redhat.thermostat.tools.Translate; +import com.redhat.thermostat.utils.keyring.Keyring; + +/** + * Command in order to persistently connect to a database. Available only in + * shell. + * + * This commands registers a connection service. If this service is available, + * it can be used to retrieve a DB connection. + * + */ +public class ConnectCommand extends SimpleCommand { + + private static final String NAME = "connect"; + private static final String USAGE = "connect -d [-u ] [-p ]"; + private static final String DESC = Translate.localize(LocaleResources.COMMAND_CONNECT_DESCRIPTION); + + private ClientPreferences prefs; + + @SuppressWarnings("rawtypes") + @Override + public void run(CommandContext ctx) throws CommandException { + DbService service = OSGIUtils.getInstance().getServiceAllowNull(DbService.class); + if (service != null) { + // Already connected, bail out + throw new CommandException(Translate.localize(LocaleResources.COMMAND_CONNECT_ALREADY_CONNECTED)); + } + if (prefs == null) { + prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class)); + } + String dbUrl = ctx.getArguments().getArgument(CommonCommandOptions.DB_URL_ARG); + if (dbUrl == null) { + dbUrl = prefs.getConnectionUrl(); + } + String username = ctx.getArguments().getArgument(CommonCommandOptions.USERNAME_ARG); + String password = ctx.getArguments().getArgument(CommonCommandOptions.PASSWORD_ARG); + service = DbServiceFactory.createDbService(username, password, dbUrl); + try { + service.connect(); + } catch (ConnectionException ex) { + throw new CommandException(Translate.localize(LocaleResources.COMMAND_CONNECT_FAILED_TO_CONNECT, dbUrl), ex); + } + ServiceRegistration registration = OSGIUtils.getInstance().registerService(DbService.class, service); + service.setServiceRegistration(registration); + } + + @Override + public String getName() { + return NAME; + } + + @Override + public String getDescription() { + return DESC; + } + + @Override + public String getUsage() { + return USAGE; + } + + @Override + public Collection getAcceptedArguments() { + List acceptedArgs = new ArrayList<>(); + acceptedArgs.add(new SimpleArgumentSpec(CommonCommandOptions.DB_URL_ARG, "d", CommonCommandOptions.DB_URL_DESC, true, true)); + acceptedArgs.add(new SimpleArgumentSpec(CommonCommandOptions.USERNAME_ARG, "u", CommonCommandOptions.USERNAME_DESC, false, true)); + acceptedArgs.add(new SimpleArgumentSpec(CommonCommandOptions.PASSWORD_ARG, "p", CommonCommandOptions.PASSWORD_DESC, false, true)); + return acceptedArgs; + } + + @Override + public boolean isAvailableOutsideShell() { + return false; + } + + @Override + public boolean isStorageRequired() { + return false; + } + +} diff -r bb3d671fe253 -r 9e4437930235 tools/src/main/java/com/redhat/thermostat/tools/cli/DisconnectCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/cli/DisconnectCommand.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,109 @@ +/* + * 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 + * . + * + * 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.tools.cli; + +import java.util.Collection; +import java.util.Collections; + +import org.osgi.framework.ServiceRegistration; + +import com.redhat.thermostat.common.cli.ArgumentSpec; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleCommand; +import com.redhat.thermostat.common.storage.ConnectionException; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.launcher.DbService; +import com.redhat.thermostat.tools.LocaleResources; +import com.redhat.thermostat.tools.Translate; + +public class DisconnectCommand extends SimpleCommand { + + private static final String NAME = "disconnect"; + private static final String USAGE = NAME; + private static final String DESC = Translate.localize(LocaleResources.COMMAND_DISCONNECT_DESCRIPTION); + + + @SuppressWarnings("rawtypes") + @Override + public void run(CommandContext ctx) throws CommandException { + DbService service = OSGIUtils.getInstance().getServiceAllowNull(DbService.class); + if (service == null) { + // not connected + throw new CommandException(Translate.localize(LocaleResources.COMMAND_DISCONNECT_NOT_CONNECTED)); + } + try { + service.disconnect(); + } catch (ConnectionException e) { + throw new CommandException(Translate.localize(LocaleResources.COMMAND_DISCONNECT_ERROR)); + } + // remove DB service + ServiceRegistration registration = service.getServiceRegistration(); + registration.unregister(); + } + + @Override + public String getName() { + return NAME; + } + + @Override + public String getDescription() { + return DESC; + } + + @Override + public String getUsage() { + return USAGE; + } + + @Override + public Collection getAcceptedArguments() { + return Collections.emptyList(); + } + + @Override + public boolean isAvailableOutsideShell() { + return false; + } + + @Override + public boolean isStorageRequired() { + return false; + } + +} diff -r bb3d671fe253 -r 9e4437930235 tools/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command --- a/tools/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command Fri Sep 21 18:17:41 2012 +0200 @@ -2,3 +2,5 @@ com.redhat.thermostat.tools.cli.ShellCommand com.redhat.thermostat.tools.cli.VMInfoCommand com.redhat.thermostat.tools.cli.VMStatCommand +com.redhat.thermostat.tools.cli.ConnectCommand +com.redhat.thermostat.tools.cli.DisconnectCommand diff -r bb3d671fe253 -r 9e4437930235 tools/src/main/resources/com/redhat/thermostat/tools/strings.properties --- a/tools/src/main/resources/com/redhat/thermostat/tools/strings.properties Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/main/resources/com/redhat/thermostat/tools/strings.properties Fri Sep 21 18:17:41 2012 +0200 @@ -11,6 +11,14 @@ COMMAND_VM_STAT_DESCRIPTION = show various statistics about a VM COMMAND_VM_STAT_ARGUMENT_CONTINUOUS_DESCRIPTION = print data continuously +COMMAND_CONNECT_DESCRIPTION = persistenly connect to a database +COMMAND_CONNECT_ALREADY_CONNECTED = Already connected to storage. Please use disconnect command to disconnect. +COMMAND_CONNECT_FAILED_TO_CONNECT = Could not connect to db {0} + +COMMAND_DISCONNECT_DESCRIPTION = disconnect from the currently used database +COMMAND_DISCONNECT_NOT_CONNECTED = Not connected to storage. You may use the connect command for establishing connections. +COMMAND_DISCONNECT_ERROR = Failed to disconnect from database. + VM_INFO_PROCESS_ID = Process ID: VM_INFO_START_TIME = Start time: VM_INFO_STOP_TIME = Stop time: diff -r bb3d671fe253 -r 9e4437930235 tools/src/test/java/com/redhat/thermostat/tools/cli/ConnectCommandTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/ConnectCommandTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,188 @@ +/* + * 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 + * . + * + * 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.tools.cli; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Matchers.any; + +import java.util.Collection; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.redhat.thermostat.common.appctx.ApplicationContextUtil; +import com.redhat.thermostat.common.cli.ArgumentSpec; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleArgumentSpec; +import com.redhat.thermostat.common.cli.SimpleArguments; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.launcher.CommonCommandOptions; +import com.redhat.thermostat.launcher.DbService; +import com.redhat.thermostat.launcher.DbServiceFactory; +import com.redhat.thermostat.test.TestCommandContextFactory; +import com.redhat.thermostat.tools.LocaleResources; +import com.redhat.thermostat.tools.Translate; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ OSGIUtils.class, DbServiceFactory.class }) +public class ConnectCommandTest { + + private ConnectCommand cmd; + private TestCommandContextFactory cmdCtxFactory; + private BundleContext bundleContext; + + @Before + public void setUp() { + ApplicationContextUtil.resetApplicationContext(); + setupCommandContextFactory(); + + cmd = new ConnectCommand(); + + } + + private void setupCommandContextFactory() { + Bundle sysBundle = mock(Bundle.class); + bundleContext = mock(BundleContext.class); + when(bundleContext.getBundle(0)).thenReturn(sysBundle); + cmdCtxFactory = new TestCommandContextFactory(bundleContext); + } + + @After + public void tearDown() { + cmdCtxFactory = null; + cmd = null; + ApplicationContextUtil.resetApplicationContext(); + } + + @Test + public void verifyConnectedThrowsException() { + DbService dbService = mock(DbService.class); + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + when(utils.getServiceAllowNull(DbService.class)).thenReturn(dbService); + + SimpleArguments args = new SimpleArguments(); + args.addArgument("--dbUrl", "fluff"); + try { + cmd.run(cmdCtxFactory.createContext(args)); + } catch (CommandException e) { + assertEquals(Translate.localize(LocaleResources.COMMAND_CONNECT_ALREADY_CONNECTED), e.getMessage()); + } + } + + @Test + public void verifyNotConnectedConnects() throws CommandException { + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + when(utils.getServiceAllowNull(DbService.class)).thenReturn(null); + + DbService dbService = mock(DbService.class); + PowerMockito.mockStatic(DbServiceFactory.class); + String username = "testuser"; + String password = "testpassword"; + String dbUrl = "mongodb://10.23.122.1:12578"; + when(DbServiceFactory.createDbService(eq(username), eq(password), eq(dbUrl))).thenReturn(dbService); + SimpleArguments args = new SimpleArguments(); + args.addArgument("dbUrl", dbUrl); + args.addArgument("username", username); + args.addArgument("password", password); + CommandContext ctx = cmdCtxFactory.createContext(args); + cmd.run(ctx); + verify(dbService).connect(); + verify(dbService).setServiceRegistration(any(ServiceRegistration.class)); + } + + @Test + public void testIsStorageRequired() { + assertFalse(cmd.isStorageRequired()); + } + + @Test + public void testIsNotAvailableOutsideShell() { + assertFalse(cmd.isAvailableOutsideShell()); + } + + @Test + public void testIsAvailableInShell() { + assertTrue(cmd.isAvailableInShell()); + } + + @Test + public void testName() { + assertEquals("connect", cmd.getName()); + } + + @Test + public void testDescription() { + assertEquals("persistenly connect to a database", cmd.getDescription()); + } + + @Test + public void testUsage() { + String expected = "connect -d [-u ] [-p ]"; + + assertEquals(expected, cmd.getUsage()); + } + + @Test + public void testAcceptedArguments() { + Collection args = cmd.getAcceptedArguments(); + assertNotNull(args); + assertTrue(args.size() == 3); + assertTrue(args.contains(new SimpleArgumentSpec(CommonCommandOptions.DB_URL_ARG, "d", CommonCommandOptions.DB_URL_DESC, true, true))); + assertTrue(args.contains(new SimpleArgumentSpec(CommonCommandOptions.USERNAME_ARG, "u", CommonCommandOptions.USERNAME_DESC, false, true))); + assertTrue(args.contains(new SimpleArgumentSpec(CommonCommandOptions.PASSWORD_ARG, "p", CommonCommandOptions.PASSWORD_DESC, false, true))); + } +} diff -r bb3d671fe253 -r 9e4437930235 tools/src/test/java/com/redhat/thermostat/tools/cli/DisconnectCommandTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/DisconnectCommandTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -0,0 +1,173 @@ +/* + * 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 + * . + * + * 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.tools.cli; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collection; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.redhat.thermostat.common.appctx.ApplicationContextUtil; +import com.redhat.thermostat.common.cli.ArgumentSpec; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleArguments; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.launcher.DbService; +import com.redhat.thermostat.test.TestCommandContextFactory; +import com.redhat.thermostat.tools.LocaleResources; +import com.redhat.thermostat.tools.Translate; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ OSGIUtils.class, FrameworkUtil.class }) +public class DisconnectCommandTest { + + private DisconnectCommand cmd; + private TestCommandContextFactory cmdCtxFactory; + private BundleContext bundleContext; + + @Before + public void setUp() { + ApplicationContextUtil.resetApplicationContext(); + setupCommandContextFactory(); + + cmd = new DisconnectCommand(); + + } + + private void setupCommandContextFactory() { + Bundle sysBundle = mock(Bundle.class); + bundleContext = mock(BundleContext.class); + when(bundleContext.getBundle(0)).thenReturn(sysBundle); + cmdCtxFactory = new TestCommandContextFactory(bundleContext); + } + + @After + public void tearDown() { + cmdCtxFactory = null; + cmd = null; + ApplicationContextUtil.resetApplicationContext(); + } + + @Test + public void verifyNotConnectedThrowsException() { + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + when(utils.getServiceAllowNull(DbService.class)).thenReturn(null); + + try { + cmd.run(cmdCtxFactory.createContext(new SimpleArguments())); + fail("cmd.run() should have thrown exception."); + } catch (CommandException e) { + assertEquals(Translate.localize(LocaleResources.COMMAND_DISCONNECT_NOT_CONNECTED), e.getMessage()); + } + } + + @SuppressWarnings({ "rawtypes" }) + @Test + public void verifyConnectedDisconnectsAndUnregistersService() throws CommandException { + DbService dbService = mock(DbService.class); + OSGIUtils utils = mock(OSGIUtils.class); + PowerMockito.mockStatic(OSGIUtils.class); + when(OSGIUtils.getInstance()).thenReturn(utils); + when(utils.getServiceAllowNull(DbService.class)).thenReturn(dbService); + ServiceRegistration registration = mock(ServiceRegistration.class); + when(dbService.getServiceRegistration()).thenReturn(registration); + + CommandContext ctx = cmdCtxFactory.createContext(new SimpleArguments()); + cmd.run(ctx); + verify(dbService).disconnect(); + verify(registration).unregister(); + } + + @Test + public void testIsNotAvailableOutsideShell() { + assertFalse(cmd.isAvailableOutsideShell()); + } + + @Test + public void testIsAvailableInShell() { + assertTrue(cmd.isAvailableInShell()); + } + + @Test + public void testIsStorageRequired() { + assertFalse(cmd.isStorageRequired()); + } + + @Test + public void testName() { + assertEquals("disconnect", cmd.getName()); + } + + @Test + public void testDescription() { + assertEquals("disconnect from the currently used database", cmd.getDescription()); + } + + @Test + public void testUsage() { + String expected = "disconnect"; + assertEquals(expected, cmd.getUsage()); + } + + @Test + public void testAcceptedArguments() { + Collection args = cmd.getAcceptedArguments(); + assertNotNull(args); + assertTrue(args.size() == 0); + } +} diff -r bb3d671fe253 -r 9e4437930235 tools/src/test/java/com/redhat/thermostat/tools/cli/ListVMsCommandTest.java --- a/tools/src/test/java/com/redhat/thermostat/tools/cli/ListVMsCommandTest.java Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/ListVMsCommandTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -39,8 +39,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.isA; -import static org.mockito.Mockito.eq; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -53,7 +53,6 @@ import com.redhat.thermostat.common.appctx.ApplicationContext; import com.redhat.thermostat.common.appctx.ApplicationContextUtil; -import com.redhat.thermostat.common.cli.AppContextSetup; import com.redhat.thermostat.common.cli.ArgumentSpec; import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; @@ -69,7 +68,6 @@ public class ListVMsCommandTest { private ListVMsCommand cmd; - private AppContextSetup appContextSetup; private TestCommandContextFactory cmdCtxFactory; private HostInfoDAO hostsDAO; private VmInfoDAO vmsDAO; @@ -86,13 +84,7 @@ } private void setupCommandContextFactory() { - appContextSetup = mock(AppContextSetup.class); - cmdCtxFactory = new TestCommandContextFactory() { - @Override - protected AppContextSetup getAppContextSetup() { - return appContextSetup; - } - }; + cmdCtxFactory = new TestCommandContextFactory(); } private void setupDAOs() { @@ -110,7 +102,6 @@ hostsDAO = null; cmdCtxFactory = null; cmd = null; - appContextSetup = null; ApplicationContextUtil.resetApplicationContext(); } diff -r bb3d671fe253 -r 9e4437930235 tools/src/test/java/com/redhat/thermostat/tools/cli/VMInfoCommandTest.java --- a/tools/src/test/java/com/redhat/thermostat/tools/cli/VMInfoCommandTest.java Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/VMInfoCommandTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -56,7 +56,6 @@ import com.redhat.thermostat.common.appctx.ApplicationContext; import com.redhat.thermostat.common.appctx.ApplicationContextUtil; -import com.redhat.thermostat.common.cli.AppContextSetup; import com.redhat.thermostat.common.cli.ArgumentSpec; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.SimpleArgumentSpec; @@ -87,7 +86,6 @@ private VMInfoCommand cmd; private VmInfoDAO vmsDAO; - private AppContextSetup appContextSetup; private TestCommandContextFactory cmdCtxFactory; private VmRef vm; @@ -103,13 +101,7 @@ } private void setupCommandContextFactory() { - appContextSetup = mock(AppContextSetup.class); - cmdCtxFactory = new TestCommandContextFactory() { - @Override - protected AppContextSetup getAppContextSetup() { - return appContextSetup; - } - }; + cmdCtxFactory = new TestCommandContextFactory(); } private void setupDAOs() { diff -r bb3d671fe253 -r 9e4437930235 tools/src/test/java/com/redhat/thermostat/tools/cli/VmStatCommandTest.java --- a/tools/src/test/java/com/redhat/thermostat/tools/cli/VmStatCommandTest.java Thu Sep 20 18:07:27 2012 +0200 +++ b/tools/src/test/java/com/redhat/thermostat/tools/cli/VmStatCommandTest.java Fri Sep 21 18:17:41 2012 +0200 @@ -60,7 +60,6 @@ import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.appctx.ApplicationContext; import com.redhat.thermostat.common.appctx.ApplicationContextUtil; -import com.redhat.thermostat.common.cli.AppContextSetup; import com.redhat.thermostat.common.cli.ArgumentSpec; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.SimpleArgumentSpec; @@ -98,7 +97,6 @@ private VMStatCommand cmd; private VmCpuStatDAO vmCpuStatDAO; - private AppContextSetup appContextSetup; private TestCommandContextFactory cmdCtxFactory; private VmMemoryStatDAO vmMemoryStatDAO; private TestTimerFactory timerFactory; @@ -120,7 +118,6 @@ public void tearDown() { vmCpuStatDAO = null; - appContextSetup = null; cmdCtxFactory = null; cmd = null; timerFactory = null; @@ -128,13 +125,7 @@ } private void setupCommandContextFactory() { - appContextSetup = mock(AppContextSetup.class); - cmdCtxFactory = new TestCommandContextFactory() { - @Override - protected AppContextSetup getAppContextSetup() { - return appContextSetup; - } - }; + cmdCtxFactory = new TestCommandContextFactory(); } private void setupDAOs() {