changeset 2604:1fcf53b27d26

[web-storage] Optionally avoid starting of backing storage. Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-March/022295.html
author Severin Gehwolf <sgehwolf@redhat.com>
date Wed, 01 Mar 2017 18:41:34 +0100
parents 02f866dff054
children b51cb6d91023
files distribution/config/web-storage-service.properties web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfiguration.java web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommand.java web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommand.java web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfigurationTest.java web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommandTest.java web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommandTest.java
diffstat 7 files changed, 210 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/distribution/config/web-storage-service.properties	Mon Feb 27 14:52:50 2017 +0100
+++ b/distribution/config/web-storage-service.properties	Wed Mar 01 18:41:34 2017 +0100
@@ -36,3 +36,10 @@
 # request logging.
 #REQUEST_LOG_FILENAME=jetty-yyyy_mm_dd.request.log
 
+# Optional configuration so as to control
+# whether backing storage gets started with the
+# front-end web endpoint.
+#
+# Uncomment the line below in order to
+# disable starting of backing storage.
+#START_BACKING_STORAGE=false
--- a/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfiguration.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfiguration.java	Wed Mar 01 18:41:34 2017 +0100
@@ -146,6 +146,20 @@
         return webArchiveDir;
     }
     
+    boolean isBackingStorageStart() {
+        String storageProp = systemConfiguration.getProperty(ConfigKeys.START_BACKING_STORAGE.name());
+        // user config overrides system config
+        String userProp = userConfiguration.getProperty(ConfigKeys.START_BACKING_STORAGE.name());
+        if (userProp != null) {
+            storageProp = userProp;
+        }
+        if (storageProp == null) {
+            // default to true if neither system nor user config is present
+            return true;
+        }
+        return Boolean.parseBoolean(storageProp);
+    }
+    
     boolean isEnableTLS() {
         String sslProp = systemConfiguration.getProperty(ConfigKeys.USE_SSL.name());
         // user config overrides system config
@@ -224,6 +238,10 @@
         /* Filename of the request log. It's relative to thermostat's
          * logs directory.
          */
-        REQUEST_LOG_FILENAME
+        REQUEST_LOG_FILENAME,
+        /*
+         * Determine whether backing storage should get started too
+         */
+        START_BACKING_STORAGE
     }
 }
--- a/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommand.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommand.java	Wed Mar 01 18:41:34 2017 +0100
@@ -98,6 +98,42 @@
 
     @Override
     public void run(CommandContext ctx) throws CommandException {
+        EmbeddedServletContainerConfiguration config = getConfiguration(commonPaths);
+        handler.setConfig(config);
+        
+        if (config.isBackingStorageStart()) {
+            startStorage();
+        }
+
+        jettyLauncher = getJettyContainerLauncher(config, sslConfig);
+        CountDownLatch webStartedLatch = new CountDownLatch(1);
+        // start web container with the web archive deployed
+        jettyLauncher.startContainer(webStartedLatch);
+        try {
+            webStartedLatch.await();
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        if (!jettyLauncher.isStartupSuccessFul()) {
+            if (config.isBackingStorageStart()) {
+                stopStorage(launcher);
+            }
+            getNotifier().fireAction(ApplicationState.FAIL);
+            throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_JETTY));
+        }
+
+        Signal.handle(new Signal("INT"), handler);
+        Signal.handle(new Signal("TERM"), handler);
+
+        //Wait for SIGINT/SIGTERM
+        try {
+            shutdownLatch.await();
+        } catch (InterruptedException e) {
+            handler.handle(new Signal("INT"));
+        }
+    }
+
+    private void startStorage() throws CommandException {
         // start storage
         final CountDownLatch storageLatch = new CountDownLatch(1);
         StorageStartedListener storageListener = new StorageStartedListener(storageLatch);
@@ -117,32 +153,6 @@
             getNotifier().fireAction(ApplicationState.FAIL);
             throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_STORAGE));
         }
-
-        EmbeddedServletContainerConfiguration config = getConfiguration(commonPaths);
-        jettyLauncher = getJettyContainerLauncher(config, sslConfig);
-        CountDownLatch webStartedLatch = new CountDownLatch(1);
-        // start web container with the web archive deployed
-        jettyLauncher.startContainer(webStartedLatch);
-        try {
-            webStartedLatch.await();
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        if (!jettyLauncher.isStartupSuccessFul()) {
-            stopStorage(launcher);
-            getNotifier().fireAction(ApplicationState.FAIL);
-            throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_JETTY));
-        }
-
-        Signal.handle(new Signal("INT"), handler);
-        Signal.handle(new Signal("TERM"), handler);
-
-        //Wait for SIGINT/SIGTERM
-        try {
-            shutdownLatch.await();
-        } catch (InterruptedException e) {
-            handler.handle(new Signal("INT"));
-        }
     }
 
     // testing hook
@@ -171,11 +181,15 @@
 
     private class CustomSignalHandler implements SignalHandler {
 
+        private EmbeddedServletContainerConfiguration config;
+        
         @Override
         public void handle(Signal arg0) {
             try {
                 jettyLauncher.stopContainer();
-                stopStorage(launcher);
+                if (config.isBackingStorageStart()) {
+                    stopStorage(launcher);
+                }
             } catch (Exception ex) {
                 // We don't want any exception to hold back the signal handler, otherwise
                 // there will be no way to actually stop Thermostat.
@@ -186,6 +200,10 @@
             // if verbose mode is turned on via the system property.
             shutdown(ExitStatus.EXIT_SUCCESS);
         }
+        
+        private void setConfig(EmbeddedServletContainerConfiguration config) {
+            this.config = config;
+        }
     }
 
     private void shutdown(int shutDownStatus) {
--- a/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommand.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/main/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommand.java	Wed Mar 01 18:41:34 2017 +0100
@@ -94,24 +94,11 @@
             throw new CommandException(translator.localize(LocaleResources.LAUNCHER_UNAVAILABLE));
         }
         Launcher launcher = (Launcher) context.getService(launcherRef);
-        // start storage
-        final CountDownLatch storageLatch = new CountDownLatch(1);
-        StorageStartedListener storageListener = new StorageStartedListener(storageLatch);
-        listeners.add(storageListener);
-        String[] storageArgs = new String[] {
-                "storage", "--start"
-        };
-        launcher.run(storageArgs, listeners, false);
-        listeners.clear();
-        try {
-            storageLatch.await();
-        } catch (InterruptedException e) {
-            getNotifier().fireAction(ApplicationState.FAIL, e);
-            throw new CommandException(translator.localize(LocaleResources.STORAGE_WAIT_INTERRUPTED));
-        }
-        if (!storageListener.isStartupSuccessful()) {
-            getNotifier().fireAction(ApplicationState.FAIL);
-            throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_STORAGE));
+        EmbeddedServletContainerConfiguration config = getConfiguration(paths);
+        
+        // start storage only if so desired
+        if (config.isBackingStorageStart()) {
+            startStorage(launcher);
         }
 
         ServiceReference sslConfigRef = context.getServiceReference(SSLConfiguration.class.getName());
@@ -121,7 +108,6 @@
         }
         SSLConfiguration sslConfig = (SSLConfiguration) context.getService(sslConfigRef);
 
-        EmbeddedServletContainerConfiguration config = getConfiguration(paths);
         JettyContainerLauncher jettyLauncher = getJettyContainerLauncher(config, sslConfig);
         CountDownLatch webStartedLatch = new CountDownLatch(1);
         // start web container with the web archive deployed
@@ -132,7 +118,9 @@
             // ignore
         }
         if (!jettyLauncher.isStartupSuccessFul()) {
-            stopStorage(launcher);
+            if (config.isBackingStorageStart()) {
+                stopStorage(launcher);
+            }
             getNotifier().fireAction(ApplicationState.FAIL);
             throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_JETTY));
         }
@@ -155,7 +143,9 @@
             } catch (InterruptedException e) { } // ignore
         } finally {
             jettyLauncher.stopContainer();
-            stopStorage(launcher);
+            if (config.isBackingStorageStart()) {
+                stopStorage(launcher);
+            }
         };
 
         if (agentStarted) {
@@ -163,6 +153,27 @@
         }
     }
     
+    private void startStorage(Launcher launcher) throws CommandException {
+        final CountDownLatch storageLatch = new CountDownLatch(1);
+        StorageStartedListener storageListener = new StorageStartedListener(storageLatch);
+        listeners.add(storageListener);
+        String[] storageArgs = new String[] {
+                "storage", "--start"
+        };
+        launcher.run(storageArgs, listeners, false);
+        listeners.clear();
+        try {
+            storageLatch.await();
+        } catch (InterruptedException e) {
+            getNotifier().fireAction(ApplicationState.FAIL, e);
+            throw new CommandException(translator.localize(LocaleResources.STORAGE_WAIT_INTERRUPTED));
+        }
+        if (!storageListener.isStartupSuccessful()) {
+            getNotifier().fireAction(ApplicationState.FAIL);
+            throw new CommandException(translator.localize(LocaleResources.ERROR_STARTING_STORAGE));
+        }
+    }
+
     // testing hook
     EmbeddedServletContainerConfiguration getConfiguration(CommonPaths paths) {
         return new EmbeddedServletContainerConfiguration(paths);
--- a/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfigurationTest.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/EmbeddedServletContainerConfigurationTest.java	Wed Mar 01 18:41:34 2017 +0100
@@ -56,7 +56,7 @@
 import com.redhat.thermostat.web.endpoint.internal.EmbeddedServletContainerConfiguration.ConfigKeys;
 
 public class EmbeddedServletContainerConfigurationTest {
-    
+
     /*
      * empty configs defaults to false
      */
@@ -67,7 +67,7 @@
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
         assertFalse(config.isEnableTLS());
     }
-    
+
     /*
      * Verifies that user config overrides system config
      */
@@ -80,7 +80,55 @@
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
         assertTrue(config.isEnableTLS());
     }
-    
+
+    /*
+     * Empty configs defaults to true
+     */
+    @Test
+    public void canGetIsBackingStorageStartNothingSpecified() {
+        Properties systemConfig = new Properties();
+        Properties userConfig = new Properties();
+        EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
+        assertTrue(config.isBackingStorageStart());
+    }
+
+    /*
+     * System config should be taken into account. No override by user config.
+     */
+    @Test
+    public void canGetIsBackingStorageStartSystemSpecified() {
+        Properties systemConfig = new Properties();
+        systemConfig.put(ConfigKeys.START_BACKING_STORAGE.name(), "false");
+        Properties userConfig = new Properties();
+        EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
+        assertFalse(config.isBackingStorageStart());
+    }
+
+    /*
+     * User config overrides system.
+     */
+    @Test
+    public void canGetIsBackingStorageStartUserOverridesSystem() {
+        Properties systemConfig = new Properties();
+        systemConfig.put(ConfigKeys.START_BACKING_STORAGE.name(), "false");
+        Properties userConfig = new Properties();
+        userConfig.put(ConfigKeys.START_BACKING_STORAGE.name(), "true");
+        EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
+        assertTrue(config.isBackingStorageStart());
+    }
+
+    /*
+     * No system config only user config.
+     */
+    @Test
+    public void canGetIsBackingStorageStartUserOverridesNoSystemConfig() {
+        Properties systemConfig = new Properties();
+        Properties userConfig = new Properties();
+        userConfig.put(ConfigKeys.START_BACKING_STORAGE.name(), "false");
+        EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
+        assertFalse(config.isBackingStorageStart());
+    }
+
     /*
      * Verifies that system config works
      */
@@ -92,7 +140,7 @@
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
         assertTrue(config.isEnableTLS());
     }
-    
+
     @Test
     public void garbageSSLConfigValsDoNotFail() {
         Properties systemConfig = new Properties();
@@ -120,7 +168,7 @@
         assertEquals(host, hostPort.getHost());
         assertEquals(port, hostPort.getPort());
     }
-    
+
     /*
      * If both system *and* user config are specified, user config wins.
      */
@@ -141,7 +189,7 @@
         assertEquals(userHost, hostPort.getHost());
         assertEquals(userPort, hostPort.getPort());
     }
-    
+
     /*
      * If neither system nor user config has the CONFIG_LISTEN_ADDRESS key
      * config is invalid.
@@ -154,7 +202,7 @@
         // this should throw InvalidConfigException
         config.getHostsPortsConfig();
     }
-    
+
     /*
      * Implementation detail. The host/port parser supports parsing lists.
      * However, in this context only one listen address can be specified. This
@@ -184,7 +232,7 @@
             // pass
         }
     }
-    
+
     /*
      * Config should not throw and exception on instantiation if user config
      * file does not exist.
@@ -203,7 +251,7 @@
             fail("Instantiation should not throw ICE due to missing files: " + e.getMessage());
         }
     }
-    
+
     /*
      * Config should not throw and exception on instantiation if system config
      * file does not exist.
@@ -222,7 +270,7 @@
             fail("Instantiation should not throw ICE due to missing files: " + e.getMessage());
         }
     }
-    
+
     /*
      * Config should not throw and exception on instantiation if user config
      * and system config file does not exist.
@@ -240,22 +288,22 @@
             fail("Instantiation should not throw ICE due to missing files: " + e.getMessage());
         }
     }
-    
+
     @Test
     public void testGetWebArchivePath() {
         CommonPaths paths = mock(CommonPaths.class);
         File fooThermostatHome = new File("/foo/path");
         when(paths.getSystemThermostatHome()).thenReturn(fooThermostatHome);
-        
+
         // Any non-null file will do for user/system config files
         File irrelevantForTest = new File("irrelevant");
-        
+
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(paths, irrelevantForTest, irrelevantForTest);
         File expected = new File(fooThermostatHome, "webapp");
         File actual = config.getAbsolutePathToExplodedWebArchive();
         assertEquals(expected.getAbsolutePath(), actual.getAbsolutePath());
     }
-    
+
     /*
      * If a request log configuration is set, be sure config paths are available
      */
@@ -272,7 +320,7 @@
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(paths, systemConfig, userConfig);
         assertTrue("Should have request log config", config.hasRequestLogConfig());
         assertEquals("/test/userhome/logs/logfile.log", config.getAbsolutePathToRequestLog());
-        
+
         // user config only
         userConfig = new Properties();
         systemConfig = new Properties();
@@ -280,7 +328,7 @@
         config = new EmbeddedServletContainerConfiguration(paths, systemConfig, userConfig);
         assertTrue("Should have request log config", config.hasRequestLogConfig());
         assertEquals("/test/userhome/logs/userlogFile.log", config.getAbsolutePathToRequestLog());
-        
+
         // user and system config
         userConfig = new Properties();
         systemConfig = new Properties();
@@ -291,7 +339,7 @@
         assertEquals("User config overrides system config",
                      "/test/userhome/logs/userlogFile.log",
                      config.getAbsolutePathToRequestLog());
-        
+
         // no config
         userConfig = new Properties();
         systemConfig = new Properties();
@@ -300,21 +348,21 @@
         assertNull("No config specified",
                      config.getAbsolutePathToRequestLog());
     }
-    
+
     @Test
     public void canGetConnectionURL() {
         doConnectionUrlTest("http://[1fff:0:a88:85a3::ac1f]:8999/thermostat/storage", "[1fff:0:a88:85a3::ac1f]:8999", false);
         doConnectionUrlTest("http://host1.example.com:8888/thermostat/storage", "host1.example.com:8888", false);
         doConnectionUrlTest("https://host1.example.com:8998/thermostat/storage", "host1.example.com:8998", true);
     }
-    
+
     @Test
     public void canGetContextPath() {
         String expectedContextPath = "/thermostat/storage";
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration((Properties)null /* unused */, (Properties)null /* unused */);
         assertEquals(expectedContextPath, config.getContextPath());
     }
-    
+
     private void doConnectionUrlTest(String expectedUrl, String hostPortToken, boolean enableSSL) {
         Properties systemConfig = new Properties();
         Properties userConfig = new Properties();
@@ -325,17 +373,17 @@
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(systemConfig, userConfig);
         assertEquals(expectedUrl, config.getConnectionUrl());
     }
-    
+
     @Test
     public void canGetPathToJaasConfig() throws InvalidConfigurationException {
         CommonPaths paths = mock(CommonPaths.class);
         String fooThHome = "/foo/path/etc";
         File fooThermostatHome = new File(fooThHome);
         when(paths.getSystemConfigurationDirectory()).thenReturn(fooThermostatHome);
-        
+
         // Any non-null file will do for user/system config files
         File irrelevantForTest = new File("irrelevant");
-        
+
         EmbeddedServletContainerConfiguration config = new EmbeddedServletContainerConfiguration(paths, irrelevantForTest, irrelevantForTest);
         String actual = config.getAbsolutePathToJaasConfig();
         assertEquals(fooThHome + "/thermostat_jaas.conf", actual);
--- a/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommandTest.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebStorageLauncherCommandTest.java	Wed Mar 01 18:41:34 2017 +0100
@@ -37,9 +37,6 @@
 package com.redhat.thermostat.web.endpoint.internal;
 
 import static org.junit.Assert.assertFalse;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.doAnswer;
@@ -53,7 +50,6 @@
 import java.util.Collection;
 import java.util.Properties;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -176,10 +172,22 @@
         command.run(mockCommandContext);
     }
 
-    @SuppressWarnings("unchecked")
     @Test
     public void testRunOnce() throws CommandException {
+        boolean startBackingStorage = true;
+        doTestRunOnce(startBackingStorage);
+    }
+
+    @Test
+    public void testRunOnceNoBackingStorage() throws CommandException {
+        boolean startBackingStorage = false;
+        doTestRunOnce(startBackingStorage);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void doTestRunOnce(boolean startBackingStorage) throws CommandException {
         final EmbeddedServletContainerConfiguration mockConfig = mock(EmbeddedServletContainerConfiguration.class);
+        when(mockConfig.isBackingStorageStart()).thenReturn(startBackingStorage);
         when(mockConfig.getConnectionUrl()).thenReturn("Test String");
 
         WebStorageLauncherCommand command = new WebStorageLauncherCommand(shutdownLatch) {
@@ -200,13 +208,18 @@
 
         command.run(mockCommandContext);
 
-        verify(mockLauncher, times(1)).run(eq(STORAGE_START_ARGS), isA(Collection.class), eq(false));
+        int numberOfTimesBackingStorage = 0;
+        if (startBackingStorage) {
+            numberOfTimesBackingStorage++;
+        }
+        verify(mockLauncher, times(numberOfTimesBackingStorage)).run(eq(STORAGE_START_ARGS), isA(Collection.class), eq(false));
     }
 
     @Test(expected = CommandException.class)
     public void testStorageFailStart()  throws CommandException {
         final EmbeddedServletContainerConfiguration mockConfig = mock(EmbeddedServletContainerConfiguration.class);
         when(mockConfig.getConnectionUrl()).thenReturn("Test String");
+        when(mockConfig.isBackingStorageStart()).thenReturn(true);
 
         WebStorageLauncherCommand command = new WebStorageLauncherCommand(shutdownLatch) {
             @Override
--- a/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommandTest.java	Mon Feb 27 14:52:50 2017 +0100
+++ b/web/endpoint-plugin/web-service/src/test/java/com/redhat/thermostat/web/endpoint/internal/WebappLauncherCommandTest.java	Wed Mar 01 18:41:34 2017 +0100
@@ -90,7 +90,7 @@
 import org.mockito.stubbing.Answer;
 
 public class WebappLauncherCommandTest {
-    
+
     private TestLogHandler handler;
     private Logger logger;
     private Launcher mockLauncher;
@@ -122,6 +122,7 @@
         context.registerService(Launcher.class, mockLauncher, null);
         context.registerService(SSLConfiguration.class, mock(SSLConfiguration.class), null);
         final EmbeddedServletContainerConfiguration mockConfig = mock(EmbeddedServletContainerConfiguration.class);
+        when(mockConfig.isBackingStorageStart()).thenReturn(true);
         when(mockConfig.getConnectionUrl()).thenReturn("Test String");
         mockJettyLauncher = mock(JettyContainerLauncher.class);
         doAnswer(new Answer<Void>() {
@@ -168,30 +169,30 @@
         WebappLauncherCommand cmd = new WebappLauncherCommand(null /* not used */);
         assertFalse(cmd.isStorageRequired());
     }
-    
+
     @Test
     public void testRunCommandWithNoConfigListenAddressSpecified() {
         CommonPaths paths = mock(CommonPaths.class);
-        
+
         File thermostatHomeNotExisting = new File("/thermostat-home/not-existing");
         when(paths.getSystemThermostatHome()).thenReturn(thermostatHomeNotExisting);
         // config needs non-null paths for configuration files. It does not
         // matter if that file actually exists. Using the fake THERMOSTAT_HOME
         // variable will do.
         File nonNullConfigFile = new File("doesn't matter");
-        
+
         String matchString = "CONFIG_LISTEN_ADDRESS";
         runTestWithPathsAndConfigFiles(paths, nonNullConfigFile, nonNullConfigFile, matchString);
     }
-    
+
     @Test
     public void testRunCommandWithWebArchiveNotExisting() throws Exception {
         CommonPaths paths = mock(CommonPaths.class);
-        
+
         File thermostatHomeNotExisting = new File("/thermostat-home/not-existing");
         when(paths.getSystemThermostatHome()).thenReturn(thermostatHomeNotExisting);
         File nonNullSysConfig = new File("no matter");
-        
+
         Properties userProperties = new Properties();
         userProperties.put(ConfigKeys.SERVLET_CONTAINER_BIND_ADDRESS.name(), "127.0.0.1:8888");
         File userPropsTempFile = File.createTempFile("thermostat", WebappLauncherCommandTest.class.getName());
@@ -202,11 +203,11 @@
             // ignore
         }
         assertTrue(userPropsTempFile.exists());
-        
+
         String matchString = "Exploded web archive";
         runTestWithPathsAndConfigFiles(paths, userPropsTempFile, nonNullSysConfig, matchString);
     }
-    
+
     private void runTestWithPathsAndConfigFiles(final CommonPaths paths, final File userConfig,
                                                 final File systemConfig, final String matchString) {
         StubBundleContext context = new StubBundleContext();
@@ -632,22 +633,22 @@
                 }
             }
         }
-        
+
     }
-    
+
     private static class TestLogHandler extends Handler {
-        
+
         private final String matchString;
         private boolean gotLogMessage = false;
-        
+
         private TestLogHandler(String matchString) {
             this.matchString = matchString;
         }
-        
+
         @Override
         public void publish(LogRecord record) {
             String logMessage = record.getMessage();
-            if (record.getLevel().intValue() >= Level.WARNING.intValue() && 
+            if (record.getLevel().intValue() >= Level.WARNING.intValue() &&
                     logMessage.contains(matchString)) {
                 gotLogMessage = true;
             };
@@ -663,5 +664,5 @@
             // no-op
         }
     }
-    
+
 }