changeset 1734:8d3ce721d520

Add compatiblity with mongodb 2.6 Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-May/013725.html
author Omair Majid <omajid@redhat.com>
date Thu, 21 May 2015 15:36:44 -0400
parents c2f18f81f57a
children 4a5706c9f0cb
files distribution/config/commands/add-mongodb-user.properties distribution/scripts/thermostat-setup integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageConnectionTest.java integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/Activator.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommand.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcher.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommand.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/StartStopAddUserCommandDecorator.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcherTest.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandTest.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommandTest.java storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageTest.java
diffstat 19 files changed, 179 insertions(+), 1046 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/config/commands/add-mongodb-user.properties	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-bundles = com.redhat.thermostat.storage.mongodb=${project.version}, \
-          org.mongodb.mongo-java-driver=${mongo-driver.osgi-version}, \
-          org.apache.commons.beanutils=${commons-beanutils.version}, \
-          org.apache.commons.codec=${commons-codec.osgi-version}, \
-          org.apache.commons.collections=${commons-collections.version}, \
-          org.apache.commons.logging=${commons-logging.version}
-
-summary = add a new mongodb user to the thermostat DB
-
-description = Add a new mongodb user to the thermostat DB, reading credentials \
- from standard input.
-
-usage = add-mongodb-user -d <dbUrl> |\
-        add-mongodb-user -s
-
-options = AUTO_LOG_OPTION, AUTO_DB_OPTIONS, startStorage
-
-startStorage.short = s
-startStorage.long = startStorage
-startStorage.description = start storage with appropriate options before \
- running the command and stop the storage when the command finishes
-startStorage.required = false
-startStorage.hasarg = false
-
-environments = cli
--- a/distribution/scripts/thermostat-setup	Wed May 20 14:40:55 2015 -0400
+++ b/distribution/scripts/thermostat-setup	Thu May 21 15:36:44 2015 -0400
@@ -283,15 +283,40 @@
   echo -e "connections.\n"
   readUsername "$defaultName"
   readPassword
-  setupCmdName="add-mongodb-user -s"
-  output="$(echo -e $USERNAME\\n$PASSWORD\\n | $THERMOSTAT $setupCmdName 2>&1)"
-  # The above should have created the mongodb stamp file
-  monogdbSetupStampFile="$USER_THERMOSTAT_HOME/data/mongodb-user-done.stamp"
-  if [ ! -e "$monogdbSetupStampFile" ] ||
-    ! echo $output | grep -s "setup complete" > /dev/null; then
+  mkdir -p "$USER_THERMOSTAT_HOME"/data/db/
+  mkdir -p "$USER_THERMOSTAT_HOME"/logs/
+  mkdir -p "$USER_THERMOSTAT_HOME"/run/
+  mkdir -p "$USER_THERMOSTAT_HOME"/etc/
+  mkdir -p "$USER_THERMOSTAT_HOME"/cache/
+  mongod --nojournal \
+         --quiet \
+         --fork \
+         --noauth \
+         --nohttpinterface \
+         --bind_ip 127.0.0.1 \
+         --port 27518 \
+         --dbpath "$USER_THERMOSTAT_HOME"/data/db \
+         --logpath "$USER_THERMOSTAT_HOME"/logs/db.log \
+         --pidfilepath "$USER_THERMOSTAT_HOME"/run/db.pid
+  MONGOD_RETVAL="$?"
+  if [ "$MONGOD_RETVAL" -ne 0 ] ; then
     echo -e "\nMongodb user setup failed." 1>&2
     exitFail
   fi
+  sleep 5
+  mongo 127.0.0.1:27518 << EOF
+use thermostat
+db.addUser({ user: "$USERNAME", pwd: "$PASSWORD", roles: [ "readWrite" ] })
+use admin
+db.shutdownServer()
+quit()
+EOF
+  MONGO_SETUP_RETVAL="$?"
+  if [ "$MONGO_SETUP_RETVAL" -ne 0 ] ; then
+    echo -e "\nMongodb user setup failed." 1>&2
+    exitFail
+  fi
+  touch "$USER_THERMOSTAT_HOME"/data/mongodb-user-done.stamp
 }
 
 doProceedLoop() {
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java	Thu May 21 15:36:44 2015 -0400
@@ -146,6 +146,21 @@
         }
     }
     
+    protected static void createFakeUserSetupDoneFile() {
+        String userHome = getUserThermostatHome();
+        File fUserHome = new File(userHome);
+        fUserHome.mkdir();
+        File dataDir = new File(fUserHome, "data");
+        dataDir.mkdir();
+
+        File mongodbUserDoneFile = new File(dataDir, "mongodb-user-done.stamp");
+        try {
+            // creates the file only if not yet existing
+            mongodbUserDoneFile.createNewFile();
+        } catch (IOException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
 
     /**
      * Utility method for removing stamp files which may get created by certain
@@ -245,8 +260,6 @@
     }
     
     public static Spawn startStorage() throws Exception {
-        clearStorageDataDirectory();
-
         Spawn storage = spawnThermostat("storage", "--start", "--permitLocalhostException");
         try {
             storage.expect("pid:");
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java	Thu May 21 15:36:44 2015 -0400
@@ -68,9 +68,9 @@
 import com.redhat.thermostat.storage.core.Cursor;
 import com.redhat.thermostat.storage.core.Key;
 import com.redhat.thermostat.storage.core.Query;
-import com.redhat.thermostat.storage.core.StorageCredentials;
 import com.redhat.thermostat.storage.core.Query.SortDirection;
 import com.redhat.thermostat.storage.core.Storage;
+import com.redhat.thermostat.storage.core.StorageCredentials;
 import com.redhat.thermostat.storage.mongodb.internal.MongoStorage;
 import com.redhat.thermostat.storage.query.Expression;
 import com.redhat.thermostat.storage.query.ExpressionFactory;
@@ -123,6 +123,7 @@
     @BeforeClass
     public static void setUpOnce() throws Exception {
         createFakeSetupCompleteFile();
+        clearStorageDataDirectory();
         startStorage();
 
         addCpuData(4);
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageConnectionTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageConnectionTest.java	Thu May 21 15:36:44 2015 -0400
@@ -51,6 +51,7 @@
 
     // @BeforeClass // reinstate once we actually need storage running (see ignored tests)
     public static void setUpOnce() throws Exception {
+        clearStorageDataDirectory();
         startStorage();
     }
 
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/StorageTest.java	Thu May 21 15:36:44 2015 -0400
@@ -59,8 +59,9 @@
 
     @Test
     public void startAndStopStorage() throws Exception {
+        clearStorageDataDirectory();
+
         Spawn storage;
-
         storage = startStorage();
 
         storage = spawnThermostat("storage", "--status");
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java	Thu May 21 15:36:44 2015 -0400
@@ -54,6 +54,7 @@
     @BeforeClass
     public static void setUpOnce() throws Exception {
         createFakeSetupCompleteFile();
+        clearStorageDataDirectory();
         startStorage();
 
         // TODO insert actual data into the database and test that
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java	Thu May 21 15:36:44 2015 -0400
@@ -47,6 +47,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
@@ -57,10 +58,12 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.eclipse.jetty.server.Server;
@@ -110,9 +113,9 @@
 import com.redhat.thermostat.web.client.internal.WebStorage;
 import com.redhat.thermostat.web.server.auth.Roles;
 
+import expectj.ExpectJ;
 import expectj.Spawn;
 import expectj.TimeoutException;
-import java.util.NoSuchElementException;
 
 /**
  * This test class starts up a mongod instance and a web storage instance
@@ -240,6 +243,7 @@
     private static final double EQUALS_DELTA = 0.00000000000001;
     private static final String THERMOSTAT_USERS_FILE = getConfigurationDir() + "/thermostat-users.properties";
     private static final String THERMOSTAT_ROLES_FILE = getConfigurationDir() + "/thermostat-roles.properties";
+    private static final String THERMOSTAT_WEB_AUTH_FILE = getThermostatHome() + "/webapp/WEB-INF/web.auth";
     private static final String VM_ID1 = "vmId1";
     private static final String VM_ID2 = "vmId2";
     private static final String VM_ID3 = "vmId3";
@@ -248,25 +252,41 @@
     private static int port;
     private static Path backupUsers;
     private static Path backupRoles;
+    private static Path backupWebAuth;
 
     @BeforeClass
     public static void setUpOnce() throws Exception {
-        
-        // This starts storage with the permit localhost exception option.
-        // It's important to start storage with that exception. Otherwise the
-        // mongodb user creds setup will fail.
-        createFakeSetupCompleteFile();
-        startStorage();
-        
-        setupMongodbUser();
+        clearStorageDataDirectory();
 
         backupUsers = Files.createTempFile("itest-backup-thermostat-users", "");
         backupRoles = Files.createTempFile("itest-backup-thermostat-roles", "");
+        backupWebAuth = Files.createTempFile("itest-backup-webapp-auth", "");
         backupRoles.toFile().deleteOnExit();
         backupUsers.toFile().deleteOnExit();
+        backupWebAuth.toFile().deleteOnExit();
         Files.copy(new File(THERMOSTAT_USERS_FILE).toPath(), backupUsers, StandardCopyOption.REPLACE_EXISTING);
         Files.copy(new File(THERMOSTAT_ROLES_FILE).toPath(), backupRoles, StandardCopyOption.REPLACE_EXISTING);
+        Files.copy(new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), backupWebAuth, StandardCopyOption.REPLACE_EXISTING);
 
+        createFakeSetupCompleteFile();
+        createFakeUserSetupDoneFile();
+
+        setupMongodbUser();
+
+        startStorage();
+
+        ExpectJ mongo = new ExpectJ(TIMEOUT_IN_SECONDS);
+        Spawn mongoSpawn = mongo.spawn("mongo 127.0.0.1:27518");
+        mongoSpawn.send("use thermostat\n");
+        mongoSpawn.expect("switched to db thermostat");
+        mongoSpawn.send(String.format("db.auth(\"%s\", \"%s\")\n", getMongodbUsername(), getMongodbPassword()));
+        mongoSpawn.expect("1");
+        mongoSpawn.send("db[\"fake\"].insert({foo:\"bar\", baz: 1})\n");
+        mongoSpawn.send("db[\"fake\"].findOne()\n");
+        mongoSpawn.send("show collections\n");
+        mongoSpawn.send("show users\n");
+
+        createWebAuthFile();
 
         // start the server, deploy the war
         port = FreePortFinder.findFreePort(new TryPort() {
@@ -282,59 +302,118 @@
 
     @AfterClass
     public static void tearDownOnce() throws Exception {
-        deleteCpuData();
-    
-        server.stop();
-        server.join();
+        try {
+            deleteCpuData();
         
-        stopStorage();
-        removeSetupCompleteStampFiles();
-    
-        Files.copy(backupUsers, new File(THERMOSTAT_USERS_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
-        Files.copy(backupRoles, new File(THERMOSTAT_ROLES_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
+            server.stop();
+            server.join();
+
+            stopStorage();
+            removeSetupCompleteStampFiles();
+        } catch (Exception e) {
+            System.out.println("AN ERROR OCCURRED!");
+            e.printStackTrace();
+            throw e;
+        } finally {
+            Files.copy(backupUsers, new File(THERMOSTAT_USERS_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
+            Files.copy(backupRoles, new File(THERMOSTAT_ROLES_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
+            Files.copy(backupWebAuth, new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), StandardCopyOption.REPLACE_EXISTING);
+            System.out.println("RESTORED web.auth!");
+        }
     }
 
     // PRE: storage started with --permitLocalhostException
     private static void setupMongodbUser() throws Exception {
-        // The actual setup is only required for devel builds.
-        // Release builds won't have a web.xml with actual username/passwords
-        // in it, so starting backing storage (i.e. mongodb) with the 
-        // --permitLocalhostException option is sufficient.
+        // The actual setup is only required for devel builds. Release builds
+        // won't have users or roles configured, so starting backing storage
+        // (i.e. mongodb) with the --permitLocalhostException option is
+        // sufficient.
+
         if (isDevelopmentBuild()) {
-            
-            // Remove the mongodb-user-added.stamp file,
-            // but keep the main setup file around so as to be able to
-            // actually launch thermostat.
-            removeSetupCompleteStampFiles();
-            createFakeSetupCompleteFile();
-            
             String mongodbUsername = getMongodbUsername();
             String mongodbPassword = getMongodbPassword();
-            String creds = String.format("%s\n%s\n", mongodbUsername,
-                                                     mongodbPassword);
-            String[] addUserArgs = new String[] {
-                    "add-mongodb-user",
-                    "-d", "mongodb://127.0.0.1:27518"
-            };
-            
-            // This should be an equivalent of:
-            // $ echo -e "mongodbUsername\nmongodbPassword\n" | \
-            //   thermostat add-mongodb-user -d mongodb://127.0.0.1:27518
-            Spawn addUser = spawnThermostat(addUserArgs);
-            addUser.send(creds);
+
+            final String HOST = "127.0.0.1";
+            final String PORT = "27518";
+
             try {
-                addUser.expect("mongodb user setup complete");
+                System.out.println("THERMOSTAT_HOME: " + getThermostatHome());
+                System.out.println("USER_THERMOSTAT_HOME: " + getUserThermostatHome());
+
+                // create directories that we use later down to store stuff in
+                // things fail silently if the directories do not exist
+                new File(getUserThermostatHome() + "/data/db").mkdirs();
+                new File(getUserThermostatHome() + "/logs/").mkdirs();
+                new File(getUserThermostatHome() + "/run/").mkdirs();
+                new File(getUserThermostatHome() + "/etc/").mkdirs();
+                new File(getUserThermostatHome() + "/cache/").mkdirs();
+
+                ExpectJ mongod = new ExpectJ(TIMEOUT_IN_SECONDS);
+                final String MONGOD_COMMAND = "mongod "
+                        + "--quiet "
+                        + "--fork "
+                        + "--noauth "
+                        + "--nohttpinterface "
+                        + "--bind_ip " + HOST + " "
+                        + "--port " + PORT + " "
+                        + "--dbpath " + getUserThermostatHome() + "/data/db "
+                        + "--logpath " + getUserThermostatHome() + "/logs/db.log "
+                        + "--pidfilepath " + getUserThermostatHome() + "/run/db.pid";
+                System.out.println(MONGOD_COMMAND);
+                Spawn mongodSpawn = mongod.spawn(MONGOD_COMMAND);
+                mongodSpawn.expectClose(TIMEOUT_IN_SECONDS);
+
+                System.out.println("Started mongod");
+                TimeUnit.SECONDS.sleep(5);
+
+                ExpectJ mongo = new ExpectJ(TIMEOUT_IN_SECONDS);
+                Spawn mongoSpawn = mongo.spawn("mongo " + HOST + ":" + PORT);
+                mongoSpawn.send("use thermostat\n");
+                mongoSpawn.send(String.format("db.addUser({ user: \"%s\", pwd: \"%s\", roles: [ \"readWrite\" ] })\n",
+                        mongodbUsername, mongodbPassword));
+                mongoSpawn.send("quit()\n");
+                mongoSpawn.expectClose();
+
+                mongo = new ExpectJ(TIMEOUT_IN_SECONDS);
+                mongoSpawn = mongo.spawn("mongo " + HOST + ":" + PORT);
+                mongoSpawn.send("use thermostat\n");
+                mongoSpawn.expect("switched to db thermostat");
+                mongoSpawn.send(String.format("db.auth(\"%s\", \"%s\")\n", mongodbUsername, mongodbPassword));
+                mongoSpawn.expect("1");
+
+                // now insert some fake data and display some information that
+                // might be useful for post-mortem analysis if this test fails
+                mongoSpawn.send("db[\"fake\"].insert({foo:\"bar\", baz: 1})\n");
+                mongoSpawn.send("db[\"fake\"].findOne()\n");
+                mongoSpawn.send("show collections\n");
+                mongoSpawn.send("show users\n");
+
+                mongoSpawn.send("use admin\n");
+                mongoSpawn.expect("switched to db admin");
+                mongoSpawn.send("db.shutdownServer()\n");
+                mongoSpawn.send("quit()\n");
+                mongoSpawn.expectClose();
+
             } catch (TimeoutException | IOException e) {
-                // failed to set up mongodb user, stop storage and bail.
-                stopStorage();
                 throw e;
             }
-            addUser.expectClose();
         } else {
             System.out.println("Not a development build. Skipping mongodb setup.");
         }
     }
 
+    private static void createWebAuthFile() throws IOException {
+        if (isDevelopmentBuild()) {
+            System.out.println("WRITING auth file: " + getMongodbUsername() + "/" + getMongodbPassword());
+            List<String> lines = new ArrayList<String>();
+            lines.add("storage.username = " + getMongodbUsername());
+            lines.add("storage.password = " + getMongodbPassword());
+            Files.write(new File(THERMOSTAT_WEB_AUTH_FILE).toPath(), lines, StandardCharsets.UTF_8);
+        } else {
+            throw new AssertionError("testing a build !");
+        }
+    }
+
     private static String getMongodbUsername() {
         assertTrue(isDevelopmentBuild());
         
@@ -366,12 +445,12 @@
 
             @Override
             public String getUsername() {
-                return null;
+                return getMongodbUsername();
             }
 
             @Override
             public char[] getPassword() {
-                return null;
+                return getMongodbPassword().toCharArray();
             }
             
         };
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/Activator.java	Wed May 20 14:40:55 2015 -0400
+++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/Activator.java	Thu May 21 15:36:44 2015 -0400
@@ -40,8 +40,6 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
-import com.redhat.thermostat.common.cli.CommandRegistry;
-import com.redhat.thermostat.common.cli.CommandRegistryImpl;
 import com.redhat.thermostat.storage.core.StorageProvider;
 import com.redhat.thermostat.storage.mongodb.MongoStorageProvider;
 
@@ -49,20 +47,16 @@
 
     @SuppressWarnings("rawtypes")
     private ServiceRegistration reg;
-    private CommandRegistry cmdReg;
     
     @Override
     public void start(BundleContext context) throws Exception {
         StorageProvider prov = new MongoStorageProvider();
         reg = context.registerService(StorageProvider.class.getName(), prov, null);
-        cmdReg = new CommandRegistryImpl(context);
-        cmdReg.registerCommand(AddUserCommandDispatcher.COMMAND_NAME, new AddUserCommandDispatcher(context));
     }
 
     @Override
     public void stop(BundleContext context) throws Exception {
         reg.unregister();
-        cmdReg.unregisterCommands();
     }
 
 }
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommand.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Objects;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.common.tools.StorageAuthInfoGetter;
-import com.redhat.thermostat.shared.config.CommonPaths;
-import com.redhat.thermostat.shared.locale.LocalizedString;
-import com.redhat.thermostat.shared.locale.Translate;
-import com.redhat.thermostat.storage.core.DbService;
-import com.redhat.thermostat.storage.core.DbServiceFactory;
-import com.redhat.thermostat.storage.core.QueuedStorage;
-import com.redhat.thermostat.storage.core.Storage;
-import com.redhat.thermostat.storage.core.StorageCredentials;
-
-/**
- * This command needs to be in the mongodb storage bundle since it
- * uses MongoStorage directly (casts to it).
- *
- */
-public class AddUserCommand extends BaseAddUserCommand {
-    
-    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
-    static final String DB_URL_ARG = "dbUrl";
-    private final BundleContext context;
-    private final StorageCredentials emptyCredentials;
-    
-    AddUserCommand(BundleContext context) {
-        this.context = context;
-        // These are empty credentials we'll use for the initial connect. We
-        // connect with them when the local host exception is turned off.
-        emptyCredentials = new StorageCredentials() {
-            
-            @Override
-            public String getUsername() {
-                return null;
-            }
-            
-            @Override
-            public char[] getPassword() {
-                return null;
-            }
-        };
-    }
-
-    // PRE: storage started with --permitLocalHostException.
-    // FIXME: Is there anything we can do to ensure this precondition?
-    @Override
-    public void run(CommandContext ctx) throws CommandException {
-        // Check if mongodb stamp file exists.
-        ServiceReference commonPathRef = context.getServiceReference(CommonPaths.class.getName());
-        requireNonNull(commonPathRef, t.localize(LocaleResources.COMMON_PATHS_SERVICE_UNAVAILABLE));
-        CommonPaths commonPath = (CommonPaths)context.getService(commonPathRef);
-        File dataDir = commonPath.getUserPersistentDataDirectory();
-        // Since this is backing storage specific, it's most likely not a good
-        // candidate for CommonPaths
-        File mongodbSetupStamp = new File(dataDir, BaseAddUserCommand.MONGODB_STAMP_FILE_NAME);
-        if (mongodbSetupStamp.exists()) {
-            String msg = t.localize(LocaleResources.MONGODB_SETUP_FILE_EXISTS,
-                                    mongodbSetupStamp.getAbsolutePath()).getContents();
-            ctx.getConsole().getOutput().println(msg);
-            return;
-        }
-        
-        ServiceReference dbServiceRef = context.getServiceReference(DbService.class);
-        if (dbServiceRef != null) {
-            // Already connected, bail out
-            throw new CommandException(t.localize(LocaleResources.ALREADY_CONNECTED_TO_STORAGE_WARNING));
-        }
-        String dbUrl = ctx.getArguments().getArgument(DB_URL_ARG);
-        // dbUrl is a required argument. This should never happen
-        Objects.requireNonNull(dbUrl);
-        // we only understand "mongodb://" URLs
-        if (!dbUrl.startsWith("mongodb://")) {
-            throw new CommandException(t.localize(LocaleResources.UNKNOWN_STORAGE_URL));
-        }
-        
-        // Register empty credentials so that connection succeeds
-        ServiceRegistration reg = context.registerService(StorageCredentials.class.getName(), emptyCredentials, null);
-        DbServiceFactory factory = new DbServiceFactory();
-        DbService service = factory.createDbService(dbUrl);
-        // this synchronously connects to storage
-        service.connect();
-        // Unregister empty credentials
-        reg.unregister();
-        
-        ServiceReference storageRef = context.getServiceReference(Storage.class.getName());
-        requireNonNull(storageRef, t.localize(LocaleResources.STORAGE_SERVICE_UNAVAILABLE));
-        @SuppressWarnings("unchecked")
-        // FIXME: Hack alarm. We use knowledge that via MongoStorageProvider we
-        //        have a MongoStorage instance wrapped in QueuedStorage. What's
-        //        more, we use the "delegate" field name in order to get at the
-        //        MongoStorage instance, which we cast to. I'm not sure if adding
-        //        method in BackingStorage (the interface) directly would be 
-        //        any better than this. After all, this is very backing storage
-        //        impl specific. For now do this hack :-/  
-        QueuedStorage storage = (QueuedStorage)context.getService(storageRef);
-        MongoStorage mongoStorage = getDelegate(storage);
-        requireNonNull(mongoStorage, t.localize(LocaleResources.MONGOSTORAGE_RETRIEVAL_FAILED));
-        StorageAuthInfoGetter getter = null;
-        try {
-            LocalizedString userPrompt = new LocalizedString("Please enter the username you'd like to add to mongodb storage at " + dbUrl + ": ");
-            LocalizedString passWordPrompt = new LocalizedString("Please enter the desired password of this user: ");
-            getter = new StorageAuthInfoGetter(ctx.getConsole(), userPrompt, passWordPrompt);
-        } catch (IOException e) {
-            throw new CommandException(t.localize(LocaleResources.ADDING_USER_FAILED));
-        }
-        ConsoleStorageCredentials creds = new ConsoleStorageCredentials(getter);
-        addUser(mongoStorage, creds);
-        
-        // create the STAMP file
-        try {
-            mongodbSetupStamp.createNewFile();
-        } catch (IOException e) {
-            String msg = t.localize(LocaleResources.STAMP_FILE_CREATION_FAILED,
-                                    mongodbSetupStamp.getAbsolutePath()).getContents();
-            ctx.getConsole().getError().println(msg);
-            throw new CommandException(new LocalizedString(msg));
-        }
-        
-        String msg = t.localize(LocaleResources.MONGODB_USER_SETUP_COMPLETE).getContents();
-        ctx.getConsole().getOutput().println(msg);
-    }
-    
-    // package-private for testing
-    void addUser(MongoStorage mongoStorage, StorageCredentials creds) {
-        // It's important that getUsername is called prior getPassword.
-        // otherwise prompts don't make much sense.
-        String username = creds.getUsername();
-        char[] pwd = creds.getPassword();
-        mongoStorage.addUser(username, pwd);
-        // zero out password. We no longer use it.
-        Arrays.fill(pwd, '\0');
-    }
-
-    // package-private for testing
-    MongoStorage getDelegate(QueuedStorage storage) {
-        try {
-            Field field = storage.getClass().getDeclaredField("delegate");
-            field.setAccessible(true);
-            MongoStorage mongo = (MongoStorage)field.get(storage);
-            return mongo;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-    
-    @Override
-    public boolean isStorageRequired() {
-        return false;
-    }
-
-}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcher.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.shared.locale.Translate;
-
-/**
- * Dispatcher making sure either -d or -s has been provided.
- *
- */
-class AddUserCommandDispatcher extends BaseAddUserCommand {
-    
-    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
-    private static final String START_STORAGE_ARG = "startStorage";
-    private static final String DB_URL_ARG = "dbUrl";
-    static final String COMMAND_NAME = "add-mongodb-user";
-    private final BundleContext context;
-    private BaseAddUserCommand command;
-    
-    AddUserCommandDispatcher(BundleContext context, BaseAddUserCommand cmd) {
-        this.context = context;
-        this.command = cmd;
-    }
-
-    AddUserCommandDispatcher(BundleContext context) {
-        this(context, new AddUserCommand(context));
-    }
-    
-    @Override
-    public void run(CommandContext ctx) throws CommandException {
-        if (ctx.getArguments().hasArgument(START_STORAGE_ARG)) {
-            // decorate and run
-            command = new StartStopAddUserCommandDecorator(context, command);
-        } else if (!ctx.getArguments().hasArgument(DB_URL_ARG)) {
-            throw new CommandException(t.localize(LocaleResources.DISPATCHER_WRONG_OPTION));
-        }
-        command.run(ctx);
-    }
-
-}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommand.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import com.redhat.thermostat.common.cli.AbstractCommand;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-
-/**
- * 
- * Base class for user setup decorators.
- * 
- * @see AddUserCommand
- * @see StartStopAddUserCommandDecorator
- *
- */
-abstract class BaseAddUserCommand extends AbstractCommand {
-    
-    static final String MONGODB_STAMP_FILE_NAME = "mongodb-user-done.stamp";
-    
-    @Override
-    abstract public void run(CommandContext ctx) throws CommandException;
-    
-    @Override
-    public boolean isStorageRequired() {
-        return false;
-    }
-}
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java	Wed May 20 14:40:55 2015 -0400
+++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java	Thu May 21 15:36:44 2015 -0400
@@ -115,7 +115,7 @@
 
     private void authenticate(String username, char[] password) {
         if (! db.authenticate(username, password)) {
-            throw new MongoException("Invalid username/password");
+            throw new MongoException("Invalid username/password: " + username + "/" + new String(password));
         }
     }
 
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java	Wed May 20 14:40:55 2015 -0400
+++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorage.java	Thu May 21 15:36:44 2015 -0400
@@ -703,18 +703,6 @@
                     categoryInfo, true, false);
         
     }
-    
-    /*
-     * Used by add-user command.
-     * 
-     * Pre: must be connected to storage already
-     */
-    void addUser(String username, char[] password) {
-        // only create user if not already existing
-        if (!db.authenticate(username, password)) {
-            db.addUser(username, password);
-        }
-    }
 
 }
 
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/StartStopAddUserCommandDecorator.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.cli.AbstractStateNotifyingCommand;
-import com.redhat.thermostat.common.cli.Arguments;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandContextFactory;
-import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.common.tools.ApplicationState;
-import com.redhat.thermostat.launcher.Launcher;
-import com.redhat.thermostat.shared.config.CommonPaths;
-import com.redhat.thermostat.shared.locale.Translate;
-
-/*
- * A command which adds a mongdb user by using AddUserCommand. It has been
- * introduced in order to aid boot-strapping of thermostat deployments. In order
- * to set up a user in mongodb, storage needs to be started with the
- * --permitLocalhostException option first. Then the credentials need to be
- * injected and storage stopped again. This command performs all three
- * required steps.
- */
-public class StartStopAddUserCommandDecorator extends BaseAddUserCommand {
-
-    public static final String COMMAND_NAME = "admin-mongodb-creds-setup";
-    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
-    private final BundleContext context;
-    private final List<ActionListener<ApplicationState>> listeners;
-    private final CountDownLatch setupFinishedBarrier;
-    private final BaseAddUserCommand decoratee;
-    private boolean setupSuccessful;
-    private Launcher launcher;
-    private CommandContext cmdCtx;
-    
-    StartStopAddUserCommandDecorator(BundleContext context, BaseAddUserCommand command) {
-        this.context = context;
-        this.listeners = new ArrayList<>(1);
-        this.setupFinishedBarrier = new CountDownLatch(1);
-        this.setupSuccessful = true;
-        this.decoratee = command;
-    }
-    
-    @Override
-    public void run(CommandContext ctx) throws CommandException {
-        cmdCtx = ctx;
-        if (!stampFileExists()) {
-            startStorageAndRunDecoratee();
-            stopStorage();
-        }
-        // if stamp file exists, there is nothing to do.
-        String msg;
-        if (setupSuccessful) {
-            msg = t.localize(LocaleResources.USER_SETUP_COMPLETE).getContents();
-            cmdCtx.getConsole().getOutput().println(msg);
-        } else {
-            msg = t.localize(LocaleResources.USER_SETUP_FAILED).getContents();
-            cmdCtx.getConsole().getOutput().println(msg);
-        }
-    }
-
-    private void stopStorage() throws CommandException {
-        listeners.clear();
-        CountDownLatch storageStoppedlatch = new CountDownLatch(1);
-        StorageStoppedListener listener = new StorageStoppedListener(storageStoppedlatch);
-        String[] storageStopArgs = new String[] {
-                "storage", "--stop"
-        };
-        listeners.add(listener);
-        launcher.run(storageStopArgs, listeners, false);
-        try {
-            storageStoppedlatch.await();
-        } catch (InterruptedException e) {
-            setupSuccessful = false;
-            throw new CommandException(t.localize(LocaleResources.INTERRUPTED_WAITING_FOR_STORAGE_STOP), e);
-        }
-        if (!listener.storageStopPassed) {
-            setupSuccessful = false;
-            String msg = t.localize(LocaleResources.STORAGE_STOP_FAILED).getContents();
-            cmdCtx.getConsole().getError().println(msg);
-        }
-    }
-
-    private void startStorageAndRunDecoratee() throws CommandException {
-        ServiceReference launcherRef = context.getServiceReference(Launcher.class);
-        if (launcherRef == null) {
-            throw new CommandException(t.localize(LocaleResources.LAUNCHER_SERVICE_UNAVAILABLE));
-        }
-        launcher = (Launcher) context.getService(launcherRef);
-        StorageStartedListener listener = new StorageStartedListener();
-        listeners.add(listener);
-        String[] storageStartArgs = new String[] { "storage", "--start", "--permitLocalhostException"};
-        launcher.run(storageStartArgs, listeners, false);
-        try {
-            setupFinishedBarrier.await();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private boolean stampFileExists() throws CommandException {
-        ServiceReference commonPathRef = context.getServiceReference(CommonPaths.class.getName());
-        if (commonPathRef == null) {
-            throw new CommandException(t.localize(LocaleResources.COMMON_PATHS_SERVICE_UNAVAILABLE));
-        }
-        CommonPaths commonPath = (CommonPaths)context.getService(commonPathRef);
-        File dataDir = commonPath.getUserPersistentDataDirectory();
-        // Since this is backing storage specific, it's most likely not a good
-        // candidate for CommonPaths
-        File mongodbSetupStamp = new File(dataDir, BaseAddUserCommand.MONGODB_STAMP_FILE_NAME);
-        if (mongodbSetupStamp.exists()) {
-            String msg = t.localize(LocaleResources.MONGODB_SETUP_FILE_EXISTS,
-                                    mongodbSetupStamp.getAbsolutePath()).getContents();
-            cmdCtx.getConsole().getOutput().println(msg);
-            return true;
-        } else {
-            return false;
-        }
-    }
-    
-    private class StorageStartedListener implements ActionListener<ApplicationState> {
-     
-        @Override
-        public void actionPerformed(ActionEvent<ApplicationState> actionEvent) {
-            if (actionEvent.getSource() instanceof AbstractStateNotifyingCommand) {
-                AbstractStateNotifyingCommand storage = (AbstractStateNotifyingCommand) actionEvent.getSource();
-                // Implementation detail: there is a single StorageCommand instance registered
-                // as an OSGi service.  We remove ourselves as listener so that we don't get
-                // notified in the case that the command is invoked by some other means later.
-                storage.getNotifier().removeActionListener(this);
-                
-                try {
-                    switch (actionEvent.getActionId()) {
-                    case START:
-                        // Payload is connection URL
-                        Object payload = actionEvent.getPayload();
-                        if (payload == null || !(payload instanceof String)) {
-                            setupSuccessful = false;
-                            throw new CommandException(t.localize(LocaleResources.UNRECOGNIZED_PAYLOAD_FROM_STORAGE_CMD));
-                        }
-                        final String dbUrl = (String)payload;
-                        try {
-                            CommandContext ctx = getAddUserCommandContext(dbUrl);
-                            decoratee.run(ctx);
-                        } catch (CommandException e) {
-                            cmdCtx.getConsole().getError().println(e.getMessage());
-                            String msg = t.localize(LocaleResources.ADDING_USER_FAILED).getContents();
-                            cmdCtx.getConsole().getError().println(msg);
-                        }
-                        break;
-                    case FAIL:
-                        // nothing
-                        break;
-                    default:
-                        // nothing
-                        break;
-                    }
-                } catch (CommandException e) {
-                    cmdCtx.getConsole().getError().println(e.getMessage());
-                } finally {
-                    setupFinishedBarrier.countDown();
-                }
-            }
-            
-        }
-        
-        private CommandContext getAddUserCommandContext(final String dbUrl) {
-            CommandContextFactory factory = new CommandContextFactory(context);
-            CommandContext ctx = factory.createContext(new Arguments() {
-                
-                @Override
-                public boolean hasArgument(String name) {
-                    if (name.equals(AddUserCommand.DB_URL_ARG)) {
-                        return true;
-                    }
-                    return false;
-                }
-                
-                @Override
-                public List<String> getNonOptionArguments() {
-                    return Collections.emptyList();
-                }
-                
-                @Override
-                public String getArgument(String name) {
-                    if (name.equals(AddUserCommand.DB_URL_ARG)) {
-                        return dbUrl;
-                    }
-                    return null;
-                }
-            });
-            return ctx;
-        }
-    }
-    
-    private static class StorageStoppedListener implements ActionListener<ApplicationState> {
-
-        private boolean storageStopPassed;
-        private final CountDownLatch storageStoppedLatch;
-        private StorageStoppedListener(CountDownLatch latch) {
-            storageStoppedLatch = latch;
-        }
-        
-        @Override
-        public void actionPerformed(ActionEvent<ApplicationState> actionEvent) {
-            if (actionEvent.getSource() instanceof AbstractStateNotifyingCommand) {
-                AbstractStateNotifyingCommand storage = (AbstractStateNotifyingCommand) actionEvent.getSource();
-                // remove ourselves so that we get called more than once.
-                storage.getNotifier().removeActionListener(this);
-                switch(actionEvent.getActionId()) {
-                case STOP:
-                    storageStopPassed = true;
-                    storageStoppedLatch.countDown();
-                    break;
-                default:
-                    storageStoppedLatch.countDown();
-                    break;
-                
-                }
-            }
-        }
-        
-    }
-}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandDispatcherTest.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.common.cli.Arguments;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandContextFactory;
-import com.redhat.thermostat.common.cli.CommandException;
-
-public class AddUserCommandDispatcherTest {
-
-    @Test
-    public void canRunUndecorated() {
-        BundleContext context = mock(BundleContext.class);
-        BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class);
-        AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd);
-        CommandContextFactory factory = new CommandContextFactory(context);
-        Arguments args = mock(Arguments.class);
-        when(args.hasArgument(eq("dbUrl"))).thenReturn(true);
-        CommandContext ctx = factory.createContext(args);
-        
-        // This should not throw any exception
-        try {
-            dispatcher.run(ctx);
-        } catch (CommandException e) {
-            fail(e.getMessage());
-        }
-    }
-    
-    @Test(expected = CommandException.class )
-    public void failsToRunWithNoArguments() throws CommandException {
-        BundleContext context = mock(BundleContext.class);
-        BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class);
-        AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd);
-        CommandContextFactory factory = new CommandContextFactory(context);
-        Arguments args = mock(Arguments.class);
-        when(args.hasArgument(any(String.class))).thenReturn(false);
-        CommandContext ctx = factory.createContext(args);
-        
-        // this throws CommandException
-        dispatcher.run(ctx);
-    }
-    
-    @Test
-    public void decoratesIfStorageStartOptionGiven() {
-        BundleContext context = mock(BundleContext.class);
-        BaseAddUserCommand mockCmd = mock(BaseAddUserCommand.class);
-        AddUserCommandDispatcher dispatcher = new AddUserCommandDispatcher(context, mockCmd);
-        CommandContextFactory factory = new CommandContextFactory(context);
-        Arguments args = mock(Arguments.class);
-        when(args.hasArgument(eq("startStorage"))).thenReturn(true);
-        CommandContext ctx = factory.createContext(args);
-        
-        try {
-            dispatcher.run(ctx);
-            fail("CommonPaths not available, should have thrown exception");
-        } catch (CommandException e) {
-            boolean passed = false;
-            for( StackTraceElement elmt: e.getStackTrace()) {
-                // StartStopAddUserCommandDecorator should be in stack trace
-                if (elmt.getClassName().equals(StartStopAddUserCommandDecorator.class.getName())) {
-                    passed = true;
-                    break;
-                }
-            }
-            assertTrue("Expected mocked BaseAddUserCommand to be decorated", passed);
-        }
-    }
-    
-    @Test
-    public void testCommandName() {
-        assertEquals("add-mongodb-user", AddUserCommandDispatcher.COMMAND_NAME);
-    }
-}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/AddUserCommandTest.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.mongodb.DB;
-import com.redhat.thermostat.storage.core.QueuedStorage;
-import com.redhat.thermostat.storage.core.Storage;
-import com.redhat.thermostat.storage.core.StorageCredentials;
-
-//There is a bug (resolved as wontfix) in powermock which results in
-//java.lang.LinkageError if javax.management.* classes aren't ignored by
-//Powermock. More here: http://code.google.com/p/powermock/issues/detail?id=277
-//SSL tests need this and having that annotation on method level doesn't seem
-//to solve the issue.
-@PowerMockIgnore( {"javax.management.*"})
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ DB.class })
-public class AddUserCommandTest {
-
-    /*
-     * Verifies that credentials' methods are called in the right order and
-     * the password array is filled with zeros after use.
-     */
-    @Test
-    public void verifyAddUser() {
-        DB db = PowerMockito.mock(DB.class);
-        CountDownLatch latch = new CountDownLatch(1);
-        MongoStorage storage = new MongoStorage(db, latch);
-        
-        StorageCredentials creds = mock(StorageCredentials.class);
-        String username = "fooUser";
-        char[] password = new char[] { 'f', 'o', 'o' };
-        when(creds.getUsername()).thenReturn(username);
-        when(creds.getPassword()).thenReturn(password);
-        InOrder inOrder = inOrder(creds);
-        
-        AddUserCommand command = new AddUserCommand(null /* unused */);
-        command.addUser(storage, creds);
-        
-        // password should have been zero-filled
-        assertTrue(Arrays.equals(new char[] { '\0', '\0', '\0' }, password));
-        // First username, then password should get called.
-        inOrder.verify(creds).getUsername();
-        inOrder.verify(creds).getPassword();
-    }
-    
-    /*
-     * Verifies if the delegate can be retrieved from QueuedStorage since
-     * AddUserCommand relies on this. In particular the delegate needs to be
-     * a MongoStorage instance.
-     */
-    @Test
-    public void verifyGettingDelegateWorks() {
-        DB db = PowerMockito.mock(DB.class);
-        CountDownLatch latch = new CountDownLatch(1);
-        // Delegate must be mongostorage
-        MongoStorage storage = new MongoStorage(db, latch);
-        
-        QueuedStorage qStorage = new QueuedStorage(storage);
-        AddUserCommand command = new AddUserCommand(null /* unused */);
-        Storage actual = command.getDelegate(qStorage);
-        
-        assertSame(storage, actual);
-    }
-}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/BaseAddUserCommandTest.java	Wed May 20 14:40:55 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012-2015 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.storage.mongodb.internal;
-
-import static org.junit.Assert.assertFalse;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-
-public class BaseAddUserCommandTest {
-
-    @Test
-    public void storageRequiredFalse() {
-        TestAddUserCommand cmd = new TestAddUserCommand();
-        assertFalse(cmd.isStorageRequired());
-    }
-    
-    private static class TestAddUserCommand extends BaseAddUserCommand {
-
-        @Override
-        public void run(CommandContext ctx) throws CommandException {
-            // no-op
-        }
-        
-    }
-}
--- a/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageTest.java	Wed May 20 14:40:55 2015 -0400
+++ b/storage/mongo/src/test/java/com/redhat/thermostat/storage/mongodb/internal/MongoStorageTest.java	Thu May 21 15:36:44 2015 -0400
@@ -904,48 +904,6 @@
         assertFalse(bool2.getValue());
     }
     
-    /*
-     * AddUserCommand family use this API. Tests that working
-     * credentials don't get recreated, since this would fail
-     * anyway.
-     */
-    @Test
-    public void verifyExistingUserIsNotAdded() throws Exception {
-        DB db = PowerMockito.mock(DB.class);
-        CountDownLatch latch = new CountDownLatch(1);
-        MongoStorage storage = new MongoStorage(db, latch);
-        
-        String username = "testUser";
-        char password[] = new char[] { 'f', 'o', 'o' };
-        when(db.authenticate(eq(username), eq(password))).thenReturn(true);
-        
-        // This should not have called db.addUser() 
-        storage.addUser(username, password);
-        
-        verify(db, times(0)).addUser(any(String.class), any(char[].class));
-    }
-    
-    /*
-     * AddUserCommand family use this API. Tests that working
-     * credentials don't get recreated, since this would fail
-     * anyway.
-     */
-    @Test
-    public void verifyNotExistingUserAdded() throws Exception {
-        DB db = PowerMockito.mock(DB.class);
-        CountDownLatch latch = new CountDownLatch(1);
-        MongoStorage storage = new MongoStorage(db, latch);
-        
-        String username = "testUser";
-        char password[] = new char[] { 'f', 'o', 'o' };
-        when(db.authenticate(eq(username), eq(password))).thenReturn(false);
-        
-        // This should not have called db.addUser() 
-        storage.addUser(username, password);
-        
-        verify(db).addUser(eq(username), eq(password));
-    }
-    
     private static class FakeDataClass implements Pojo {};
 }