changeset 2292:12e2aa7b6c42

Add silent setup option and make it default for thermostat local Reviewed-by: neugens, jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-May/018700.html Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-May/018787.html
author Anirudhan Mukundan <amukunda@redhat.com>
date Wed, 11 May 2016 12:02:41 -0400
parents 9bfc2723bbfc
children e8aa651b0627
files setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupCommand.java setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/model/ThermostatQuickSetup.java setup/command/src/test/java/com/redhat/thermostat/setup/command/internal/SetupCommandTest.java setup/command/src/test/java/com/redhat/thermostat/setup/command/internal/model/ThermostatQuickSetupTest.java setup/distribution/thermostat-plugin.xml
diffstat 6 files changed, 389 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupCommand.java	Fri May 06 16:02:47 2016 +0200
+++ b/setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupCommand.java	Wed May 11 12:02:41 2016 -0400
@@ -38,6 +38,7 @@
 
 import java.awt.EventQueue;
 import java.awt.GraphicsEnvironment;
+import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -59,6 +60,7 @@
 import com.redhat.thermostat.launcher.Launcher;
 import com.redhat.thermostat.service.process.UNIXProcessHandler;
 import com.redhat.thermostat.setup.command.internal.cli.CLISetup;
+import com.redhat.thermostat.setup.command.internal.model.ThermostatQuickSetup;
 import com.redhat.thermostat.setup.command.internal.model.ThermostatSetup;
 import com.redhat.thermostat.shared.config.CommonPaths;
 import com.redhat.thermostat.shared.locale.Translate;
@@ -69,6 +71,8 @@
     private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     private static final String ORIG_CMD_ARGUMENT_NAME = "origArgs";
     private static final String NON_GUI_OPTION_NAME = "nonGui";
+    private static final String SILENT_OPTION_NAME = "silent";
+    private static final String LOCAL_COMMAND_NAME = "local";
     private static final Logger logger = LoggingUtils.getLogger(SetupCommand.class);
     private final DependencyServices dependentServices = new DependencyServices();
     private SetupWindow mainWindow;
@@ -106,6 +110,8 @@
 
             if (args.hasArgument(NON_GUI_OPTION_NAME) || isHeadless()) {
                 runCLISetup(setup, ctx.getConsole());
+            } else if (args.hasArgument(SILENT_OPTION_NAME) || isSilentSetupRequired(origArgsList)) {
+                runSilentSetup(setup);
             } else {
                 runGUISetup(setup);
             }
@@ -133,6 +139,19 @@
         cliSetup.run();
     }
 
+    // package-private for testing
+    void runSilentSetup(ThermostatSetup setup) throws CommandException {
+        try {
+            new ThermostatQuickSetup(setup).run();
+        } catch (IOException e) {
+            throw new CommandException(t.localize(LocaleResources.SETUP_FAILED), e);
+        }
+    }
+
+    private boolean isSilentSetupRequired(String[] args) {
+        return args != null && args[0].equals(LOCAL_COMMAND_NAME);
+    }
+
     private void runGUISetup(ThermostatSetup setup) throws CommandException {
         try {
             setLookAndFeel();
@@ -219,7 +238,8 @@
         private static final String SINGLE_DASH = "-";
         private static final String DOUBLE_DASH = "--";
         private static final String NON_GUI_SHORT_OPT = "c";
-        
+        private static final String SILENT_SHORT_OPT = "s";
+
         private final Arguments argsDelegate;
         private final String[] origArgs;
         private final Map<String, String> additionalOptions;
@@ -248,6 +268,8 @@
                     String cleanedOp = opt.substring(1);
                     if (cleanedOp.equals(NON_GUI_SHORT_OPT)) {
                         options.put(NON_GUI_OPTION_NAME, Boolean.TRUE.toString());
+                    } else if (cleanedOp.equals(SILENT_SHORT_OPT)) {
+                        options.put(SILENT_OPTION_NAME, Boolean.TRUE.toString());
                     }
                     continue;
                 } else {
--- a/setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java	Fri May 06 16:02:47 2016 +0200
+++ b/setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java	Wed May 11 12:02:41 2016 -0400
@@ -83,6 +83,7 @@
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.setup.command.internal.model.CredentialGenerator;
+import com.redhat.thermostat.setup.command.internal.model.ThermostatQuickSetup;
 import com.redhat.thermostat.setup.command.internal.model.ThermostatSetup;
 import com.redhat.thermostat.shared.locale.Translate;
 
@@ -344,77 +345,33 @@
     }
 
     private void runSetup() {
-        finishAction = new SwingWorker<IOException, Void>() {
+        finishAction = new SetupSwingWorker() {
             @Override
-            public IOException doInBackground() {
-                try {
-                    doSynchronouslyOnEdt(new Runnable() {
-                        @Override
-                        public void run() {
-                            frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-                            startView.disableButtons();
-                            mongoUserSetupView.disableButtons();
-                            userPropertiesView.disableButtons();
-                        }
-                    });
-                } catch (InvocationTargetException | InterruptedException e) {
-                    e.printStackTrace();
-                }
+            void doSetup() throws IOException {
                 thermostatSetup.createMongodbUser(storageUsername, storagePassword);
-                try {
-                    if (thermostatSetup.isWebAppInstalled()) {
-                        thermostatSetup.createAgentUser(agentUsername, agentPassword);
-                        thermostatSetup.createClientAdminUser(clientUsername, clientPassword);
-                    }
-                    thermostatSetup.commit();
-                    return null;
-                } catch (IOException e) {
-                    shutdown();
-                    return e;
+                if (thermostatSetup.isWebAppInstalled()) {
+                    thermostatSetup.createAgentUser(agentUsername, agentPassword);
+                    thermostatSetup.createClientAdminUser(clientUsername, clientPassword);
                 }
-            }
-
-            @Override
-            public void done() {
-                startView.enableButtons();
-                mongoUserSetupView.enableButtons();
-                userPropertiesView.enableButtons();
-                frame.setCursor(Cursor.getDefaultCursor());
-                shutdown();
+                thermostatSetup.commit();
             }
         };
         finishAction.execute();
     }
 
     private void runQuickSetup() {
-        if(thermostatSetup.isWebAppInstalled()) {
-            CredentialGenerator storage = new CredentialGenerator(translator.localize(LocaleResources.MONGO_USER_PREFIX).getContents());
-            CredentialGenerator agent = new CredentialGenerator(translator.localize(LocaleResources.AGENT_USER_PREFIX).getContents());
-            CredentialGenerator client = new CredentialGenerator(translator.localize(LocaleResources.CLIENT_USER_PREFIX).getContents());
+        final ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
 
-            storageUsername = storage.generateRandomUsername();
-            storagePassword = storage.generateRandomPassword();
-            agentUsername = agent.generateRandomUsername();
-            agentPassword = agent.generateRandomPassword();
-            clientUsername = client.generateRandomUsername();
-            clientPassword = client.generateRandomPassword();
-        } else {
-            CredentialGenerator user = new CredentialGenerator(translator.localize(LocaleResources.USER_PREFIX).getContents());
+        setupCompleteView.setClientCredentials(quickSetup.getClientUsername(), quickSetup.getClientPassword());
+        setupCompleteView.setAgentCredentials(quickSetup.getAgentUsername(), quickSetup.getAgentPassword());
 
-            String username = user.generateRandomUsername();
-            char[] password = user.generateRandomPassword();
-            storageUsername = username;
-            storagePassword = password;
-            agentUsername = username;
-            agentPassword = password;
-            clientUsername = username;
-            clientPassword = password;
-        }
-
-        setupCompleteView.setClientCredentials(clientUsername, clientPassword);
-        setupCompleteView.setAgentCredentials(agentUsername, agentPassword);
-
-        runSetup();
+        finishAction = new SetupSwingWorker() {
+            @Override
+            void doSetup() throws IOException {
+                quickSetup.run();
+            }
+        };
+        finishAction.execute();
     }
 
     private void showView(SetupView view) {
@@ -436,6 +393,44 @@
         shutdown.countDown();
     }
 
+    private abstract class SetupSwingWorker extends SwingWorker<IOException, Void> {
+        @Override
+        public IOException doInBackground() {
+            try {
+                doSynchronouslyOnEdt(new Runnable() {
+                    @Override
+                    public void run() {
+                        frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+                        startView.disableButtons();
+                        mongoUserSetupView.disableButtons();
+                        userPropertiesView.disableButtons();
+                    }
+                });
+            } catch (InvocationTargetException | InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            try {
+                doSetup();
+                return null;
+            } catch (IOException e) {
+                shutdown();
+                return e;
+            }
+        }
+
+        @Override
+        public void done() {
+            startView.enableButtons();
+            mongoUserSetupView.enableButtons();
+            userPropertiesView.enableButtons();
+            frame.setCursor(Cursor.getDefaultCursor());
+            shutdown();
+        }
+
+        abstract void doSetup() throws IOException;
+    }
+
     private static class ErrorDialog extends JDialog {
 
         static JDialog createDialog(JFrame parent, String reason, Throwable throwable) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup/command/src/main/java/com/redhat/thermostat/setup/command/internal/model/ThermostatQuickSetup.java	Wed May 11 12:02:41 2016 -0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012-2016 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.setup.command.internal.model;
+
+import com.redhat.thermostat.setup.command.internal.LocaleResources;
+import com.redhat.thermostat.shared.locale.Translate;
+
+import java.io.IOException;
+
+public class ThermostatQuickSetup {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private ThermostatSetup thermostatSetup;
+
+    private String storageUsername;
+    private String agentUsername;
+    private String clientUsername;
+    private char[] storagePassword;
+    private char[] agentPassword;
+    private char[] clientPassword;
+
+    public ThermostatQuickSetup(ThermostatSetup thermostatSetup) {
+        this.thermostatSetup = thermostatSetup;
+        generateCredentials();
+    }
+
+    private void generateCredentials() {
+        if(thermostatSetup.isWebAppInstalled()) {
+            CredentialGenerator storage = new CredentialGenerator(translator.localize(LocaleResources.MONGO_USER_PREFIX).getContents());
+            CredentialGenerator agent = new CredentialGenerator(translator.localize(LocaleResources.AGENT_USER_PREFIX).getContents());
+            CredentialGenerator client = new CredentialGenerator(translator.localize(LocaleResources.CLIENT_USER_PREFIX).getContents());
+
+            storageUsername = storage.generateRandomUsername();
+            storagePassword = storage.generateRandomPassword();
+            agentUsername = agent.generateRandomUsername();
+            agentPassword = agent.generateRandomPassword();
+            clientUsername = client.generateRandomUsername();
+            clientPassword = client.generateRandomPassword();
+        } else {
+            CredentialGenerator user = new CredentialGenerator(translator.localize(LocaleResources.USER_PREFIX).getContents());
+
+            String username = user.generateRandomUsername();
+            char[] password = user.generateRandomPassword();
+            storageUsername = username;
+            storagePassword = password;
+            agentUsername = username;
+            agentPassword = password;
+            clientUsername = username;
+            clientPassword = password;
+        }
+    }
+
+    public void run() throws IOException {
+        thermostatSetup.createMongodbUser(storageUsername, storagePassword);
+        if (thermostatSetup.isWebAppInstalled()) {
+            thermostatSetup.createAgentUser(agentUsername, agentPassword);
+            thermostatSetup.createClientAdminUser(clientUsername, clientPassword);
+        }
+
+        thermostatSetup.commit();
+    }
+
+    public String getAgentUsername() {
+        return agentUsername;
+    }
+
+    public char[] getAgentPassword() {
+        return agentPassword;
+    }
+
+    public String getClientUsername() {
+        return clientUsername;
+    }
+
+    public char[] getClientPassword() {
+        return clientPassword;
+    }
+
+}
\ No newline at end of file
--- a/setup/command/src/test/java/com/redhat/thermostat/setup/command/internal/SetupCommandTest.java	Fri May 06 16:02:47 2016 +0200
+++ b/setup/command/src/test/java/com/redhat/thermostat/setup/command/internal/SetupCommandTest.java	Wed May 11 12:02:41 2016 -0400
@@ -41,6 +41,8 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.matches;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -286,6 +288,46 @@
         testExitStatus(args, ExitStatus.EXIT_SUCCESS);
     }
 
+    @Test
+    public void testExitStatusNonZeroWhenSilentSetupFails() {
+        cmd = new SetupCommand() {
+            @Override
+            void runSilentSetup(ThermostatSetup setup) throws CommandException {
+                throw new CommandException(new LocalizedString("Setup fail exception"));
+            }
+
+            @Override
+            ThermostatSetup createSetup() {
+                return thermostatSetup;
+            }
+        };
+
+        Arguments args = mock(Arguments.class);
+        when(args.hasArgument("silent")).thenReturn(true);
+
+        testExitStatus(args, ExitStatus.EXIT_ERROR);
+    }
+
+    @Test
+    public void testExitStatusZeroWhenSilentSetupSuccess() {
+        cmd = new SetupCommand() {
+            @Override
+            void runSilentSetup(ThermostatSetup setup) throws CommandException {
+                // do nothing
+            }
+
+            @Override
+            ThermostatSetup createSetup() {
+                return thermostatSetup;
+            }
+        };
+
+        Arguments args = mock(Arguments.class);
+        when(args.hasArgument("silent")).thenReturn(true);
+
+        testExitStatus(args, ExitStatus.EXIT_SUCCESS);
+    }
+
     private void testExitStatus(Arguments setupArgs, int exitVal) {
         setServices();
 
@@ -381,7 +423,32 @@
         verify(thermostatSetup).createClientAdminUser(eq("client"), argThat(matchesPassword(new char[] { 'c' })));
         verify(thermostatSetup).createMongodbUser(eq("mongo"), argThat(matchesPassword(new char[] { 'm' })));
     }
-    
+
+    @Test
+    public void verifySilentSetupRunsWithLocalCommand() throws CommandException {
+        cmd = new SetupCommand() {
+            @Override
+            ThermostatSetup createSetup() {
+                return thermostatSetup;
+            }
+        };
+
+        setServices();
+
+        Arguments args = mock(Arguments.class);
+        CommandContext ctxt = mock(CommandContext.class);
+        when(ctxt.getArguments()).thenReturn(args);
+        when(args.hasArgument("origArgs")).thenReturn(true);
+        when(args.getArgument("origArgs")).thenReturn("local");
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(true);
+
+        cmd.run(ctxt);
+
+        verify(thermostatSetup).createAgentUser(matches("agent-[a-zA-Z0-9]+"), any(char[].class));
+        verify(thermostatSetup).createClientAdminUser(matches("client-[a-zA-Z0-9]+"), any(char[].class));
+        verify(thermostatSetup).createMongodbUser(matches("mongodb-[a-zA-Z0-9]+"), any(char[].class));
+    }
+
     private CharArrayMatcher matchesPassword(char[] expected) {
         return new CharArrayMatcher(expected);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup/command/src/test/java/com/redhat/thermostat/setup/command/internal/model/ThermostatQuickSetupTest.java	Wed May 11 12:02:41 2016 -0400
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012-2016 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.setup.command.internal.model;
+
+import com.redhat.thermostat.setup.command.internal.LocaleResources;
+import com.redhat.thermostat.shared.locale.Translate;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ThermostatQuickSetupTest {
+    private ThermostatSetup thermostatSetup;
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    @Before
+    public void setup() {
+        thermostatSetup = mock(ThermostatSetup.class);
+    }
+
+    @Test
+    public void testAgentUsername() {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(true);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+        String username = quickSetup.getAgentUsername();
+        Assert.assertTrue(username.startsWith(translator.localize(LocaleResources.AGENT_USER_PREFIX).getContents()));
+    }
+
+    @Test
+    public void testAgentUsernameWebAppNotInstalled() {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(false);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+        String username = quickSetup.getAgentUsername();
+        Assert.assertTrue(username.startsWith(translator.localize(LocaleResources.USER_PREFIX).getContents()));
+    }
+
+    @Test
+    public void testClientUsername() {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(true);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+        String username = quickSetup.getClientUsername();
+        Assert.assertTrue(username.startsWith(translator.localize(LocaleResources.CLIENT_USER_PREFIX).getContents()));
+    }
+
+    @Test
+    public void testClientUsernameWebAppNotInstalled() {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(false);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+        String username = quickSetup.getClientUsername();
+        Assert.assertTrue(username.startsWith(translator.localize(LocaleResources.USER_PREFIX).getContents()));
+    }
+
+    @Test
+    public void testRun() throws IOException {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(true);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+
+        quickSetup.run();
+
+        verify(thermostatSetup, times(1)).createMongodbUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(1)).createAgentUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(1)).createClientAdminUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(1)).commit();
+    }
+
+
+    @Test
+    public void testRunWebAppNotInstalled() throws IOException {
+        when(thermostatSetup.isWebAppInstalled()).thenReturn(false);
+        ThermostatQuickSetup quickSetup = new ThermostatQuickSetup(thermostatSetup);
+
+        quickSetup.run();
+
+        verify(thermostatSetup, times(1)).createMongodbUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(0)).createAgentUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(0)).createClientAdminUser(anyString(), any(char[].class));
+        verify(thermostatSetup, times(1)).commit();
+    }
+
+}
--- a/setup/distribution/thermostat-plugin.xml	Fri May 06 16:02:47 2016 +0200
+++ b/setup/distribution/thermostat-plugin.xml	Wed May 11 12:02:41 2016 -0400
@@ -58,6 +58,12 @@
           <required>false</required>
           <description>Don't use the graphical user interface, but use the command line instead for interactive questions.</description>
         </option>
+        <option>
+          <long>silent</long>
+          <short>s</short>
+          <required>false</required>
+          <description>Run quick setup and auto-generate all required credentials.</description>
+        </option>
       </options>
       <environments>
         <environment>cli</environment>