From c2d7e44f722f3c14af036553fdc001408f47343a Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Tue, 26 Aug 2014 18:28:55 +0200 Subject: [PATCH] Fix some quality flaws --- .../org/sonar/process/MonitoredProcess.java | 9 +-- .../org/sonar/process/ProcessLogging.java | 2 +- .../main/java/org/sonar/process/Props.java | 43 +++++++++----- ...{ProcessTest.java => BaseProcessTest.java} | 5 +- ...rTest.java => BaseProcessWrapperTest.java} | 6 +- .../sonar/process/ConfigurationUtilsTest.java | 2 +- ...{MonitorTest.java => MonitorTestBase.java} | 4 +- .../sonar/process/MonitoredProcessTest.java | 4 +- .../java/org/sonar/process/PropsTest.java | 46 +++++++-------- .../java/org/sonar/search/SearchServer.java | 59 ++++++++----------- .../java/org/sonar/server/app/Connectors.java | 36 +++++------ .../org/sonar/server/app/EmbeddedTomcat.java | 2 +- .../java/org/sonar/server/app/Logging.java | 10 ++-- .../java/org/sonar/server/app/Webapp.java | 10 ++-- .../main/java/org/sonar/application/App.java | 35 +++++------ .../sonar/application/DefaultSettings.java | 2 +- .../org/sonar/application/JdbcSettings.java | 2 +- .../org/sonar/application/PropsBuilder.java | 2 +- .../application/DefaultSettingsTest.java | 12 ++-- .../sonar/application/JdbcSettingsTest.java | 8 +-- .../sonar/application/PropsBuilderTest.java | 16 ++--- 21 files changed, 152 insertions(+), 163 deletions(-) rename server/process/sonar-process/src/test/java/org/sonar/process/{ProcessTest.java => BaseProcessTest.java} (95%) rename server/process/sonar-process/src/test/java/org/sonar/process/{ProcessWrapperTest.java => BaseProcessWrapperTest.java} (96%) rename server/process/sonar-process/src/test/java/org/sonar/process/{MonitorTest.java => MonitorTestBase.java} (97%) diff --git a/server/process/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java b/server/process/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java index d9187c3e6d4..5f0c03bea7a 100644 --- a/server/process/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java +++ b/server/process/sonar-process/src/main/java/org/sonar/process/MonitoredProcess.java @@ -19,7 +19,6 @@ */ package org.sonar.process; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +34,6 @@ public abstract class MonitoredProcess implements ProcessMXBean { private static final long AUTOKILL_TIMEOUT_MS = 30000L; private static final long AUTOKILL_CHECK_DELAY_MS = 2000L; public static final String NAME_PROPERTY = "pName"; - public static final String MISSING_NAME_ARGUMENT = "Missing Name argument"; private Long lastPing; private final String name; @@ -56,12 +54,7 @@ public abstract class MonitoredProcess implements ProcessMXBean { protected MonitoredProcess(Props props, boolean monitor) { this.isMonitored = monitor; this.props = props; - this.name = props.of(NAME_PROPERTY); - - // Testing required properties - if (StringUtils.isEmpty(name)) { - throw new IllegalStateException(MISSING_NAME_ARGUMENT); - } + this.name = props.nonNullValue(NAME_PROPERTY); JmxUtils.registerMBean(this, name); ProcessUtils.addSelfShutdownHook(this); diff --git a/server/process/sonar-process/src/main/java/org/sonar/process/ProcessLogging.java b/server/process/sonar-process/src/main/java/org/sonar/process/ProcessLogging.java index 6b2e49e55fd..dacddd91847 100644 --- a/server/process/sonar-process/src/main/java/org/sonar/process/ProcessLogging.java +++ b/server/process/sonar-process/src/main/java/org/sonar/process/ProcessLogging.java @@ -35,7 +35,7 @@ public class ProcessLogging { JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(context); context.reset(); - context.putProperty(PATH_LOGS_PROPERTY, props.of(PATH_LOGS_PROPERTY)); + context.putProperty(PATH_LOGS_PROPERTY, props.nonNullValue(PATH_LOGS_PROPERTY)); doConfigure(configurator, logbackXmlResource); } catch (JoranException ignored) { // StatusPrinter will handle this diff --git a/server/process/sonar-process/src/main/java/org/sonar/process/Props.java b/server/process/sonar-process/src/main/java/org/sonar/process/Props.java index d6e2795a597..b868702eafc 100644 --- a/server/process/sonar-process/src/main/java/org/sonar/process/Props.java +++ b/server/process/sonar-process/src/main/java/org/sonar/process/Props.java @@ -23,6 +23,7 @@ import org.apache.commons.lang.StringUtils; import javax.annotation.CheckForNull; import javax.annotation.Nullable; + import java.io.File; import java.util.Properties; @@ -41,7 +42,7 @@ public class Props { } @CheckForNull - public String of(String key) { + public String value(String key) { String value = properties.getProperty(key); if (value != null && encryption.isEncrypted(value)) { value = encryption.decrypt(value); @@ -49,29 +50,41 @@ public class Props { return value; } - public String of(String key, @Nullable String defaultValue) { - String s = of(key); + public String nonNullValue(String key) { + String value = value(key); + if (value == null) { + throw new IllegalArgumentException("Missing property: " + key); + } + return value; + } + + @CheckForNull + public String value(String key, @Nullable String defaultValue) { + String s = value(key); return s == null ? defaultValue : s; } - public boolean booleanOf(String key) { - String s = of(key); + public boolean valueAsBoolean(String key) { + String s = value(key); return s != null && Boolean.parseBoolean(s); } - public boolean booleanOf(String key, boolean defaultValue) { - String s = of(key); + public boolean valueAsBoolean(String key, boolean defaultValue) { + String s = value(key); return s != null ? Boolean.parseBoolean(s) : defaultValue; } - @CheckForNull - public File fileOf(String key) { - String s = of(key); - return s != null ? new File(s) : null; + public File nonNullValueAsFile(String key) { + String s = value(key); + if (s == null) { + throw new IllegalArgumentException("Property " + key + " is missing"); + } + return new File(s); } - public Integer intOf(String key) { - String s = of(key); + @CheckForNull + public Integer valueAsInt(String key) { + String s = value(key); if (s != null && !"".equals(s)) { try { return Integer.parseInt(s); @@ -82,8 +95,8 @@ public class Props { return null; } - public int intOf(String key, int defaultValue) { - Integer i = intOf(key); + public int valueAsInt(String key, int defaultValue) { + Integer i = valueAsInt(key); return i == null ? defaultValue : i; } diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/ProcessTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessTest.java similarity index 95% rename from server/process/sonar-process/src/test/java/org/sonar/process/ProcessTest.java rename to server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessTest.java index f8b9430298f..2045cd4516d 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/ProcessTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessTest.java @@ -29,7 +29,7 @@ import java.io.File; import java.io.IOException; import java.net.ServerSocket; -public abstract class ProcessTest { +public abstract class BaseProcessTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -49,11 +49,10 @@ public abstract class ProcessTest { dummyAppJar = FileUtils.toFile(getClass().getResource("/sonar-dummy-app.jar")); } - @After public void tearDown() { if (proc != null) { - proc.destroy(); + ProcessUtils.destroyQuietly(proc); } } diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/ProcessWrapperTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessWrapperTest.java similarity index 96% rename from server/process/sonar-process/src/test/java/org/sonar/process/ProcessWrapperTest.java rename to server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessWrapperTest.java index 2a7f10ce3b7..b217edb2584 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/ProcessWrapperTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/BaseProcessWrapperTest.java @@ -30,7 +30,7 @@ import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Fail.fail; -public class ProcessWrapperTest extends ProcessTest { +public class BaseProcessWrapperTest extends BaseProcessTest { @Test public void has_dummy_app() { @@ -100,7 +100,7 @@ public class ProcessWrapperTest extends ProcessTest { props.set("spaceHome", home.getAbsolutePath()); // 3 start dummy app - File effectiveHome = props.fileOf("spaceHome"); + File effectiveHome = props.nonNullValueAsFile("spaceHome"); String cp = FilenameUtils.concat(new File(effectiveHome, "lib").getAbsolutePath(), "*"); System.out.println("cp = " + cp); @@ -115,4 +115,4 @@ public class ProcessWrapperTest extends ProcessTest { assertThat(process.isAlive()).isFalse(); assertCanStart(process); } -} \ No newline at end of file +} diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java index 40585642954..de928b93850 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java @@ -76,7 +76,7 @@ public class ConfigurationUtilsTest { FileUtils.write(propsFile, "foo=bar"); Props result = ConfigurationUtils.loadPropsFromCommandLineArgs(new String[] {propsFile.getAbsolutePath()}); - assertThat(result.of("foo")).isEqualTo("bar"); + assertThat(result.value("foo")).isEqualTo("bar"); assertThat(result.rawProperties()).hasSize(1); } diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/MonitorTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/MonitorTestBase.java similarity index 97% rename from server/process/sonar-process/src/test/java/org/sonar/process/MonitorTest.java rename to server/process/sonar-process/src/test/java/org/sonar/process/MonitorTestBase.java index e10a158ed87..0980251cdc7 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/MonitorTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/MonitorTestBase.java @@ -25,7 +25,7 @@ import org.junit.Test; import static org.fest.assertions.Assertions.assertThat; -public class MonitorTest extends ProcessTest { +public class MonitorTestBase extends BaseProcessTest { Monitor monitor; @@ -75,4 +75,4 @@ public class MonitorTest extends ProcessTest { assertThat(monitor.isAlive()).isFalse(); assertThat(process.isAlive()).isFalse(); } -} \ No newline at end of file +} diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/MonitoredProcessTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/MonitoredProcessTest.java index ef0379925c8..c753bd00422 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/MonitoredProcessTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/MonitoredProcessTest.java @@ -35,8 +35,8 @@ public class MonitoredProcessTest { try { new DummyProcess(new Props(properties), true); fail(); - } catch (Exception e) { - assertThat(e.getMessage()).isEqualTo("Missing Name argument"); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).isEqualTo("Missing property: pName"); } properties.setProperty(MonitoredProcess.NAME_PROPERTY, DummyProcess.NAME); diff --git a/server/process/sonar-process/src/test/java/org/sonar/process/PropsTest.java b/server/process/sonar-process/src/test/java/org/sonar/process/PropsTest.java index 2af69ef1ca0..5d283b44f8f 100644 --- a/server/process/sonar-process/src/test/java/org/sonar/process/PropsTest.java +++ b/server/process/sonar-process/src/test/java/org/sonar/process/PropsTest.java @@ -34,10 +34,10 @@ public class PropsTest { p.setProperty("foo", "bar"); Props props = new Props(p); - assertThat(props.of("foo")).isEqualTo("bar"); - assertThat(props.of("foo", "default value")).isEqualTo("bar"); - assertThat(props.of("unknown")).isNull(); - assertThat(props.of("unknown", "default value")).isEqualTo("default value"); + assertThat(props.value("foo")).isEqualTo("bar"); + assertThat(props.value("foo", "default value")).isEqualTo("bar"); + assertThat(props.value("unknown")).isNull(); + assertThat(props.value("unknown", "default value")).isEqualTo("default value"); } @Test @@ -47,12 +47,12 @@ public class PropsTest { p.setProperty("blank", ""); Props props = new Props(p); - assertThat(props.intOf("foo")).isEqualTo(33); - assertThat(props.intOf("foo", 44)).isEqualTo(33); - assertThat(props.intOf("blank")).isNull(); - assertThat(props.intOf("blank", 55)).isEqualTo(55); - assertThat(props.intOf("unknown")).isNull(); - assertThat(props.intOf("unknown", 44)).isEqualTo(44); + assertThat(props.valueAsInt("foo")).isEqualTo(33); + assertThat(props.valueAsInt("foo", 44)).isEqualTo(33); + assertThat(props.valueAsInt("blank")).isNull(); + assertThat(props.valueAsInt("blank", 55)).isEqualTo(55); + assertThat(props.valueAsInt("unknown")).isNull(); + assertThat(props.valueAsInt("unknown", 44)).isEqualTo(44); } @Test @@ -62,7 +62,7 @@ public class PropsTest { Props props = new Props(p); try { - props.intOf("foo"); + props.valueAsInt("foo"); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessage("Value of property foo is not an integer: bar"); @@ -76,9 +76,9 @@ public class PropsTest { p.setProperty("bar", "false"); Props props = new Props(p); - assertThat(props.booleanOf("foo")).isTrue(); - assertThat(props.booleanOf("bar")).isFalse(); - assertThat(props.booleanOf("unknown")).isFalse(); + assertThat(props.valueAsBoolean("foo")).isTrue(); + assertThat(props.valueAsBoolean("bar")).isFalse(); + assertThat(props.valueAsBoolean("unknown")).isFalse(); } @Test @@ -88,10 +88,10 @@ public class PropsTest { p.setProperty("bar", "false"); Props props = new Props(p); - assertThat(props.booleanOf("unset", false)).isFalse(); - assertThat(props.booleanOf("unset", true)).isTrue(); - assertThat(props.booleanOf("foo", false)).isTrue(); - assertThat(props.booleanOf("bar", true)).isFalse(); + assertThat(props.valueAsBoolean("unset", false)).isFalse(); + assertThat(props.valueAsBoolean("unset", true)).isTrue(); + assertThat(props.valueAsBoolean("foo", false)).isTrue(); + assertThat(props.valueAsBoolean("bar", true)).isFalse(); } @Test @@ -102,9 +102,9 @@ public class PropsTest { props.setDefault("foo", "foo_def"); props.setDefault("bar", "bar_def"); - assertThat(props.of("foo")).isEqualTo("foo_value"); - assertThat(props.of("bar")).isEqualTo("bar_def"); - assertThat(props.of("other")).isNull(); + assertThat(props.value("foo")).isEqualTo("foo_value"); + assertThat(props.value("bar")).isEqualTo("bar_def"); + assertThat(props.value("other")).isNull(); } @Test @@ -115,8 +115,8 @@ public class PropsTest { props.set("foo", "new_foo"); props.set("bar", "new_bar"); - assertThat(props.of("foo")).isEqualTo("new_foo"); - assertThat(props.of("bar")).isEqualTo("new_bar"); + assertThat(props.value("foo")).isEqualTo("new_foo"); + assertThat(props.value("bar")).isEqualTo("new_bar"); } @Test diff --git a/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java b/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java index 873e8b95ab0..6988264f15f 100644 --- a/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java +++ b/server/sonar-search/src/main/java/org/sonar/search/SearchServer.java @@ -66,7 +66,7 @@ public class SearchServer extends MonitoredProcess { this.isBlocking = blocking; new MinimumViableSystem().check(); - String esNodesInets = props.of(ES_CLUSTER_INET); + String esNodesInets = props.value(ES_CLUSTER_INET); if (StringUtils.isNotEmpty(esNodesInets)) { Collections.addAll(nodes, esNodesInets.split(",")); } @@ -77,7 +77,7 @@ public class SearchServer extends MonitoredProcess { this.isBlocking = true; new MinimumViableSystem().check(); - String esNodesInets = props.of(ES_CLUSTER_INET); + String esNodesInets = props.value(ES_CLUSTER_INET); if (StringUtils.isNotEmpty(esNodesInets)) { Collections.addAll(nodes, esNodesInets.split(",")); } @@ -94,9 +94,8 @@ public class SearchServer extends MonitoredProcess { @Override protected void doStart() { - - Integer port = props.intOf(ES_PORT_PROPERTY); - String clusterName = props.of(ES_CLUSTER_PROPERTY); + Integer port = props.valueAsInt(ES_PORT_PROPERTY); + String clusterName = props.value(ES_CLUSTER_PROPERTY); LoggerFactory.getLogger(SearchServer.class).info("Starting ES[{}] on port: {}", clusterName, port); @@ -105,7 +104,7 @@ public class SearchServer extends MonitoredProcess { // Disable MCast .put("discovery.zen.ping.multicast.enabled", "false") - // Index storage policies + // Index storage policies .put("index.merge.policy.max_merge_at_once", "200") .put("index.merge.policy.segments_per_tier", "200") .put("index.number_of_shards", "1") @@ -114,15 +113,15 @@ public class SearchServer extends MonitoredProcess { .put("indices.store.throttle.type", "merge") .put("indices.store.throttle.max_bytes_per_sec", "200mb") - // Install our own listUpdate scripts + // Install our own listUpdate scripts .put("script.default_lang", "native") .put("script.native." + ListUpdate.NAME + ".type", ListUpdate.UpdateListScriptFactory.class.getName()) - // Node is pure transport + // Node is pure transport .put("transport.tcp.port", port) .put("http.enabled", false) - // Setting up ES paths + // Setting up ES paths .put("path.data", esDataDir().getAbsolutePath()) .put("path.work", esWorkDir().getAbsolutePath()) .put("path.logs", esLogDir().getAbsolutePath()); @@ -140,10 +139,10 @@ public class SearchServer extends MonitoredProcess { // Set cluster coordinates esSettings.put("cluster.name", clusterName); - esSettings.put("node.rack_id", StringUtils.defaultIfEmpty(props.of(SONAR_NODE_NAME), "unknown")); + esSettings.put("node.rack_id", props.value(SONAR_NODE_NAME, "unknown")); esSettings.put("cluster.routing.allocation.awareness.attributes", "rack_id"); if (props.contains(SONAR_NODE_NAME)) { - esSettings.put("node.name", props.of(SONAR_NODE_NAME)); + esSettings.put("node.name", props.value(SONAR_NODE_NAME)); } else { try { esSettings.put("node.name", InetAddress.getLocalHost().getHostName()); @@ -184,40 +183,40 @@ public class SearchServer extends MonitoredProcess { // Disallow dynamic mapping (too expensive) .put("index.mapper.dynamic", false) - // Sortable text analyzer + // Sortable text analyzer .put("index.analysis.analyzer.sortable.type", "custom") .put("index.analysis.analyzer.sortable.tokenizer", "keyword") .putArray("index.analysis.analyzer.sortable.filter", "trim", "lowercase", "truncate") - // Edge NGram index-analyzer + // Edge NGram index-analyzer .put("index.analysis.analyzer.index_grams.type", "custom") .put("index.analysis.analyzer.index_grams.tokenizer", "whitespace") .putArray("index.analysis.analyzer.index_grams.filter", "trim", "lowercase", "gram_filter") - // Edge NGram search-analyzer + // Edge NGram search-analyzer .put("index.analysis.analyzer.search_grams.type", "custom") .put("index.analysis.analyzer.search_grams.tokenizer", "whitespace") .putArray("index.analysis.analyzer.search_grams.filter", "trim", "lowercase") - // Word index-analyzer + // Word index-analyzer .put("index.analysis.analyzer.index_words.type", "custom") .put("index.analysis.analyzer.index_words.tokenizer", "standard") .putArray("index.analysis.analyzer.index_words.filter", "standard", "word_filter", "lowercase", "stop", "asciifolding", "porter_stem") - // Word search-analyzer + // Word search-analyzer .put("index.analysis.analyzer.search_words.type", "custom") .put("index.analysis.analyzer.search_words.tokenizer", "standard") .putArray("index.analysis.analyzer.search_words.filter", "standard", "lowercase", "stop", "asciifolding", "porter_stem") - // Edge NGram filter + // Edge NGram filter .put("index.analysis.filter.gram_filter.type", "edgeNGram") .put("index.analysis.filter.gram_filter.min_gram", 2) .put("index.analysis.filter.gram_filter.max_gram", 15) .putArray("index.analysis.filter.gram_filter.token_chars", "letter", "digit", "punctuation", "symbol") - // Word filter + // Word filter .put("index.analysis.filter.word_filter.type", "word_delimiter") .put("index.analysis.filter.word_filter.generate_word_parts", true) .put("index.analysis.filter.word_filter.catenate_words", true) @@ -228,46 +227,38 @@ public class SearchServer extends MonitoredProcess { .put("index.analysis.filter.word_filter.split_on_numerics", true) .put("index.analysis.filter.word_filter.stem_english_possessive", true) - // Path Analyzer + // Path Analyzer .put("index.analysis.analyzer.path_analyzer.type", "custom") .put("index.analysis.analyzer.path_analyzer.tokenizer", "path_hierarchy"); } private File esHomeDir() { - String homeDir = props.of(SONAR_PATH_HOME); - if (StringUtils.isEmpty(homeDir)) { - throw new IllegalStateException("property 'sonar.path.home' is required"); - } else { - return new File(homeDir); - } + return props.nonNullValueAsFile(SONAR_PATH_HOME); } private File esDataDir() { - String dataDir = props.of(SONAR_PATH_DATA); + String dataDir = props.value(SONAR_PATH_DATA); if (StringUtils.isNotEmpty(dataDir)) { return new File(dataDir, "es"); - } else { - return new File(esHomeDir(), "data/es"); } + return new File(esHomeDir(), "data/es"); } private File esLogDir() { - String logDir = props.of(SONAR_PATH_LOG); + String logDir = props.value(SONAR_PATH_LOG); if (StringUtils.isNotEmpty(logDir)) { return new File(logDir); - } else { - return new File(esHomeDir(), "log"); } + return new File(esHomeDir(), "log"); } private File esWorkDir() { - String workDir = props.of(SONAR_PATH_TEMP); + String workDir = props.value(SONAR_PATH_TEMP); if (StringUtils.isNotEmpty(workDir)) { return new File(workDir); - } else { - return new File(esHomeDir(), "temp"); } + return new File(esHomeDir(), "temp"); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java b/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java index 13276f34dbf..340c3b3ccbf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java @@ -70,7 +70,7 @@ class Connectors { private static Connector newHttpConnector(Props props) { Connector connector = null; // Not named "sonar.web.http.port" to keep backward-compatibility - int port = props.intOf("sonar.web.port", 9000); + int port = props.valueAsInt("sonar.web.port", 9000); if (port > DISABLED_PORT) { connector = newConnector(props, HTTP_PROTOCOL, "http"); connector.setPort(port); @@ -82,7 +82,7 @@ class Connectors { @Nullable private static Connector newAjpConnector(Props props) { Connector connector = null; - int port = props.intOf("sonar.ajp.port", DISABLED_PORT); + int port = props.valueAsInt("sonar.ajp.port", DISABLED_PORT); if (port > DISABLED_PORT) { connector = newConnector(props, AJP_PROTOCOL, "http"); connector.setPort(port); @@ -94,24 +94,24 @@ class Connectors { @Nullable private static Connector newHttpsConnector(Props props) { Connector connector = null; - int port = props.intOf("sonar.web.https.port", DISABLED_PORT); + int port = props.valueAsInt("sonar.web.https.port", DISABLED_PORT); if (port > DISABLED_PORT) { connector = newConnector(props, HTTP_PROTOCOL, "https"); connector.setPort(port); connector.setSecure(true); connector.setScheme("https"); - setConnectorAttribute(connector, "keyAlias", props.of("sonar.web.https.keyAlias")); - String keyPassword = props.of("sonar.web.https.keyPass", "changeit"); + setConnectorAttribute(connector, "keyAlias", props.value("sonar.web.https.keyAlias")); + String keyPassword = props.value("sonar.web.https.keyPass", "changeit"); setConnectorAttribute(connector, "keyPass", keyPassword); - setConnectorAttribute(connector, "keystorePass", props.of("sonar.web.https.keystorePass", keyPassword)); - setConnectorAttribute(connector, "keystoreFile", props.of("sonar.web.https.keystoreFile")); - setConnectorAttribute(connector, "keystoreType", props.of("sonar.web.https.keystoreType", "JKS")); - setConnectorAttribute(connector, "keystoreProvider", props.of("sonar.web.https.keystoreProvider")); - setConnectorAttribute(connector, "truststorePass", props.of("sonar.web.https.truststorePass", "changeit")); - setConnectorAttribute(connector, "truststoreFile", props.of("sonar.web.https.truststoreFile")); - setConnectorAttribute(connector, "truststoreType", props.of("sonar.web.https.truststoreType", "JKS")); - setConnectorAttribute(connector, "truststoreProvider", props.of("sonar.web.https.truststoreProvider")); - setConnectorAttribute(connector, "clientAuth", props.of("sonar.web.https.clientAuth", "false")); + setConnectorAttribute(connector, "keystorePass", props.value("sonar.web.https.keystorePass", keyPassword)); + setConnectorAttribute(connector, "keystoreFile", props.value("sonar.web.https.keystoreFile")); + setConnectorAttribute(connector, "keystoreType", props.value("sonar.web.https.keystoreType", "JKS")); + setConnectorAttribute(connector, "keystoreProvider", props.value("sonar.web.https.keystoreProvider")); + setConnectorAttribute(connector, "truststorePass", props.value("sonar.web.https.truststorePass", "changeit")); + setConnectorAttribute(connector, "truststoreFile", props.value("sonar.web.https.truststoreFile")); + setConnectorAttribute(connector, "truststoreType", props.value("sonar.web.https.truststoreType", "JKS")); + setConnectorAttribute(connector, "truststoreProvider", props.value("sonar.web.https.truststoreProvider")); + setConnectorAttribute(connector, "clientAuth", props.value("sonar.web.https.clientAuth", "false")); setConnectorAttribute(connector, "sslProtocol", "TLS"); setConnectorAttribute(connector, "SSLEnabled", true); info("HTTPS connector is enabled on port " + port); @@ -122,7 +122,7 @@ class Connectors { private static Connector newConnector(Props props, String protocol, String scheme) { Connector connector = new Connector(protocol); connector.setURIEncoding("UTF-8"); - connector.setProperty("address", props.of("sonar.web.host", "0.0.0.0")); + connector.setProperty("address", props.value("sonar.web.host", "0.0.0.0")); configurePool(props, connector, scheme); configureCompression(connector); return connector; @@ -130,9 +130,9 @@ class Connectors { private static void configurePool(Props props, Connector connector, String scheme) { connector.setProperty("acceptorThreadCount", String.valueOf(2)); - connector.setProperty("minSpareThreads", String.valueOf(props.intOf("sonar.web." + scheme + ".minThreads", 5))); - connector.setProperty("maxThreads", String.valueOf(props.intOf("sonar.web." + scheme + ".maxThreads", 50))); - connector.setProperty("acceptCount", String.valueOf(props.intOf("sonar.web." + scheme + ".acceptCount", 25))); + connector.setProperty("minSpareThreads", String.valueOf(props.valueAsInt("sonar.web." + scheme + ".minThreads", 5))); + connector.setProperty("maxThreads", String.valueOf(props.valueAsInt("sonar.web." + scheme + ".maxThreads", 50))); + connector.setProperty("acceptCount", String.valueOf(props.valueAsInt("sonar.web." + scheme + ".acceptCount", 25))); } private static void configureCompression(Connector connector) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java index f86e5cc369d..8a80a6c05ec 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java @@ -80,7 +80,7 @@ class EmbeddedTomcat implements Terminable { } private File tomcatBasedir() { - return new File(props.of("sonar.path.temp"), "tc"); + return new File(props.value("sonar.path.temp"), "tc"); } boolean isReady() { diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Logging.java b/server/sonar-server/src/main/java/org/sonar/server/app/Logging.java index 0610bcdd7ed..777a06883cb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Logging.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Logging.java @@ -66,11 +66,11 @@ class Logging { * Configure Logback from classpath, with configuration from sonar.properties */ private static void configureLogback(Props props) { - String configProfilingLevel = props.of(Profiling.CONFIG_PROFILING_LEVEL, "NONE"); + String configProfilingLevel = props.value(Profiling.CONFIG_PROFILING_LEVEL, "NONE"); Profiling.Level profilingLevel = Profiling.Level.fromConfigString(configProfilingLevel); - String consoleEnabled = props.of(CONFIG_LOG_CONSOLE, "false"); + String consoleEnabled = props.value(CONFIG_LOG_CONSOLE, "false"); Map variables = ImmutableMap.of( - "sonar.path.logs", props.of("sonar.path.logs"), + "sonar.path.logs", props.nonNullValue("sonar.path.logs"), "LOGFILE_LOGGING_FORMAT", profilingLevel == Profiling.Level.FULL ? LOGFILE_FULL_LOGGING_FORMAT : LOGFILE_STANDARD_LOGGING_FORMAT, "CONSOLE_LOGGING_FORMAT", profilingLevel == Profiling.Level.FULL ? CONSOLE_FULL_LOGGING_FORMAT : CONSOLE_STANDARD_LOGGING_FORMAT, "CONSOLE_ENABLED", consoleEnabled); @@ -84,10 +84,10 @@ class Logging { } private static void configureLogbackAccess(Tomcat tomcat, Props props) { - if (props.booleanOf(PROPERTY_ENABLE_ACCESS_LOGS, true)) { + if (props.valueAsBoolean(PROPERTY_ENABLE_ACCESS_LOGS, true)) { LogbackValve valve = new LogbackValve(); valve.setQuiet(true); - valve.setFilename(new File(props.of("sonar.path.web"), ACCESS_RELATIVE_PATH).getAbsolutePath()); + valve.setFilename(new File(props.nonNullValue("sonar.path.web"), ACCESS_RELATIVE_PATH).getAbsolutePath()); tomcat.getHost().getPipeline().addValve(valve); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java index 45b5be863a8..006bbafd237 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java @@ -70,7 +70,7 @@ class Webapp { } static String getContextPath(Props props) { - String context = props.of(PROPERTY_CONTEXT, ""); + String context = props.value(PROPERTY_CONTEXT, ""); if ("/".equals(context)) { context = ""; } else if (!"".equals(context) && !context.startsWith("/")) { @@ -81,10 +81,10 @@ class Webapp { static void configureRails(Props props, Context context) { // sonar.dev is kept for backward-compatibility - if (props.booleanOf("sonar.dev", false)) { + if (props.valueAsBoolean("sonar.dev", false)) { props.set("sonar.web.dev", "true"); } - if (props.booleanOf("sonar.web.dev", false)) { + if (props.valueAsBoolean("sonar.web.dev", false)) { context.addParameter(RAILS_ENV, "development"); context.addParameter(JRUBY_MAX_RUNTIMES, "3"); LoggerFactory.getLogger(Webapp.class).warn("WEB DEVELOPMENT MODE IS ENABLED - DO NOT USE FOR PRODUCTION USAGE"); @@ -95,9 +95,9 @@ class Webapp { } static String webappPath(Props props) { - String webDir = props.of("sonar.web.dev.sources"); + String webDir = props.value("sonar.web.dev.sources"); if (StringUtils.isEmpty(webDir)) { - webDir = new File(props.of("sonar.path.home"), "web").getAbsolutePath(); + webDir = new File(props.value("sonar.path.home"), "web").getAbsolutePath(); } LoggerFactory.getLogger(Webapp.class).info(String.format("Webapp directory: %s", webDir)); return webDir; diff --git a/sonar-application/src/main/java/org/sonar/application/App.java b/sonar-application/src/main/java/org/sonar/application/App.java index 43c192bf716..784d75ef299 100644 --- a/sonar-application/src/main/java/org/sonar/application/App.java +++ b/sonar-application/src/main/java/org/sonar/application/App.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import org.sonar.process.JmxUtils; import org.sonar.process.MinimumViableSystem; import org.sonar.process.Monitor; -import org.sonar.process.MonitoredProcess; import org.sonar.process.ProcessLogging; import org.sonar.process.ProcessMXBean; import org.sonar.process.ProcessUtils; @@ -35,8 +34,6 @@ import org.sonar.process.Props; import org.sonar.search.SearchServer; import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; import java.util.Properties; /** @@ -60,13 +57,13 @@ public class App implements ProcessMXBean { monitor.start(); - File homeDir = props.fileOf("sonar.path.home"); - File tempDir = props.fileOf("sonar.path.temp"); + File homeDir = props.nonNullValueAsFile("sonar.path.home"); + File tempDir = props.nonNullValueAsFile("sonar.path.temp"); elasticsearch = new ProcessWrapper(JmxUtils.SEARCH_SERVER_NAME); elasticsearch .setWorkDir(homeDir) - .setJmxPort(props.intOf(DefaultSettings.SEARCH_JMX_PORT)) - .addJavaOpts(props.of(DefaultSettings.SEARCH_JAVA_OPTS)) + .setJmxPort(props.valueAsInt(DefaultSettings.SEARCH_JMX_PORT)) + .addJavaOpts(props.value(DefaultSettings.SEARCH_JAVA_OPTS)) .setTempDirectory(tempDir.getAbsoluteFile()) .setClassName("org.sonar.search.SearchServer") .addProperties(props.rawProperties()) @@ -78,19 +75,19 @@ public class App implements ProcessMXBean { logger.info("search server is up"); // do not yet start SQ in cluster mode. See SONAR-5483 & SONAR-5391 - if (StringUtils.isEmpty(props.of(DefaultSettings.CLUSTER_MASTER, null))) { + if (StringUtils.isEmpty(props.value(DefaultSettings.CLUSTER_MASTER))) { server = new ProcessWrapper(JmxUtils.WEB_SERVER_NAME) .setWorkDir(homeDir) - .setJmxPort(props.intOf(DefaultSettings.WEB_JMX_PORT)) - .addJavaOpts(props.of(DefaultSettings.WEB_JAVA_OPTS)) + .setJmxPort(props.valueAsInt(DefaultSettings.WEB_JMX_PORT)) + .addJavaOpts(props.nonNullValue(DefaultSettings.WEB_JAVA_OPTS)) .setTempDirectory(tempDir.getAbsoluteFile()) - // required for logback tomcat valve - .setLogDir(props.fileOf("sonar.path.logs")) + // required for logback tomcat valve + .setLogDir(props.nonNullValueAsFile("sonar.path.logs")) .setClassName("org.sonar.server.app.WebServer") .addProperties(props.rawProperties()) .addClasspath("./lib/common/*") .addClasspath("./lib/server/*"); - String driverPath = props.of(JdbcSettings.PROPERTY_DRIVER_PATH); + String driverPath = props.value(JdbcSettings.PROPERTY_DRIVER_PATH); if (driverPath != null) { server.addClasspath(driverPath); } @@ -150,27 +147,23 @@ public class App implements ProcessMXBean { } public static void main(String[] args) { - new MinimumViableSystem().check(); CommandLineParser cli = new CommandLineParser(); Properties rawProperties = cli.parseArguments(args); - Props props = null; + Props props; try { props = new PropsBuilder(rawProperties, new JdbcSettings()).build(); new ProcessLogging().configure(props, "/org/sonar/application/logback.xml"); - } catch (IOException e) { - throw new IllegalStateException(e.getMessage()); - } catch (URISyntaxException e) { - throw new IllegalStateException(e.getMessage()); + } catch (Exception e) { + throw new IllegalStateException(e); } App app = new App(); - try { // start and wait for shutdown command if (props.contains(SearchServer.ES_CLUSTER_INET)) { - LoggerFactory.getLogger(App.class).info("SonarQube slave configured to join SonarQube master : {}", props.of(SearchServer.ES_CLUSTER_INET)); + LoggerFactory.getLogger(App.class).info("SonarQube slave configured to join SonarQube master : {}", props.value(SearchServer.ES_CLUSTER_INET)); } app.start(props); } catch (InterruptedException e) { diff --git a/sonar-application/src/main/java/org/sonar/application/DefaultSettings.java b/sonar-application/src/main/java/org/sonar/application/DefaultSettings.java index e6d737487ac..0a85182cc21 100644 --- a/sonar-application/src/main/java/org/sonar/application/DefaultSettings.java +++ b/sonar-application/src/main/java/org/sonar/application/DefaultSettings.java @@ -55,7 +55,7 @@ class DefaultSettings { // init ports for (Map.Entry entry : defaultPorts().entrySet()) { String key = entry.getKey(); - int port = props.intOf(key, -1); + int port = props.valueAsInt(key, -1); if (port == -1) { // default port props.set(key, String.valueOf((int) entry.getValue())); diff --git a/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java b/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java index 300de2421dd..ff88ae0f9c0 100644 --- a/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java +++ b/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java @@ -50,7 +50,7 @@ public class JdbcSettings { } public void checkAndComplete(File homeDir, Props props) { - String url = props.of(DefaultSettings.JDBC_URL); + String url = props.value(DefaultSettings.JDBC_URL); Provider provider = driverProvider(url); checkUrlParameters(provider, url); String driverPath = driverPath(homeDir, provider); diff --git a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java index 0793a314163..f736658db7b 100644 --- a/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java +++ b/sonar-application/src/main/java/org/sonar/application/PropsBuilder.java @@ -111,7 +111,7 @@ class PropsBuilder { } private File configureDir(Props props, String propKey, String defaultRelativePath) { - String path = props.of(propKey, defaultRelativePath); + String path = props.value(propKey, defaultRelativePath); File d = new File(path); if (!d.isAbsolute()) { d = new File(homeDir, path); diff --git a/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java index 15892f29942..16a9cc9f1f8 100644 --- a/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java +++ b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java @@ -33,10 +33,10 @@ public class DefaultSettingsTest { Props props = new Props(new Properties()); DefaultSettings.init(props); - assertThat(props.of("sonar.search.javaOpts")).contains("-Xmx"); - assertThat(props.intOf("sonar.web.jmxPort")).isEqualTo(9003); - assertThat(props.intOf("sonar.search.jmxPort")).isEqualTo(9002); - assertThat(props.of("sonar.jdbc.username")).isEqualTo("sonar"); + assertThat(props.value("sonar.search.javaOpts")).contains("-Xmx"); + assertThat(props.valueAsInt("sonar.web.jmxPort")).isEqualTo(9003); + assertThat(props.valueAsInt("sonar.search.jmxPort")).isEqualTo(9002); + assertThat(props.value("sonar.jdbc.username")).isEqualTo("sonar"); } @Test @@ -46,7 +46,7 @@ public class DefaultSettingsTest { Props props = new Props(p); DefaultSettings.init(props); - assertThat(props.of("sonar.jdbc.username")).isEqualTo("angela"); + assertThat(props.value("sonar.jdbc.username")).isEqualTo("angela"); } @Test @@ -56,6 +56,6 @@ public class DefaultSettingsTest { Props props = new Props(p); DefaultSettings.init(props); - assertThat(props.intOf("sonar.web.jmxPort")).isGreaterThan(0); + assertThat(props.valueAsInt("sonar.web.jmxPort")).isGreaterThan(0); } } diff --git a/sonar-application/src/test/java/org/sonar/application/JdbcSettingsTest.java b/sonar-application/src/test/java/org/sonar/application/JdbcSettingsTest.java index d7c44d3caf4..ad603c4e453 100644 --- a/sonar-application/src/test/java/org/sonar/application/JdbcSettingsTest.java +++ b/sonar-application/src/test/java/org/sonar/application/JdbcSettingsTest.java @@ -89,7 +89,7 @@ public class JdbcSettingsTest { Props props = new Props(new Properties()); props.set("sonar.jdbc.url", "jdbc:oracle:thin:@localhost/XE"); settings.checkAndComplete(home, props); - assertThat(props.fileOf(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); + assertThat(props.nonNullValueAsFile(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); } @Test @@ -98,7 +98,7 @@ public class JdbcSettingsTest { Props props = new Props(new Properties()); props.set("sonar.jdbc.url", "jdbc:h2:tcp://localhost:9092/sonar"); settings.checkAndComplete(home, props); - assertThat(props.fileOf(JdbcSettings.PROPERTY_DRIVER_PATH)).isNull(); + assertThat(props.value(JdbcSettings.PROPERTY_DRIVER_PATH)).isNull(); } @Test @@ -110,7 +110,7 @@ public class JdbcSettingsTest { Props props = new Props(new Properties()); props.set("sonar.jdbc.url", "jdbc:postgresql://localhost/sonar"); settings.checkAndComplete(home, props); - assertThat(props.fileOf(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); + assertThat(props.nonNullValueAsFile(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); } @Test @@ -122,7 +122,7 @@ public class JdbcSettingsTest { Props props = new Props(new Properties()); props.set("sonar.jdbc.url", "jdbc:jtds:sqlserver://localhost/sonar;SelectMethod=Cursor"); settings.checkAndComplete(home, props); - assertThat(props.fileOf(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); + assertThat(props.nonNullValueAsFile(JdbcSettings.PROPERTY_DRIVER_PATH)).isEqualTo(driverFile); } @Test diff --git a/sonar-application/src/test/java/org/sonar/application/PropsBuilderTest.java b/sonar-application/src/test/java/org/sonar/application/PropsBuilderTest.java index 0c89e72dd97..be6387c212c 100644 --- a/sonar-application/src/test/java/org/sonar/application/PropsBuilderTest.java +++ b/sonar-application/src/test/java/org/sonar/application/PropsBuilderTest.java @@ -60,20 +60,20 @@ public class PropsBuilderTest { Props props = new PropsBuilder(rawProperties, jdbcSettings, homeDir).build(); - assertThat(props.fileOf("sonar.path.logs")).isEqualTo(logsDir); - assertThat(props.fileOf("sonar.path.home")).isEqualTo(homeDir); + assertThat(props.nonNullValueAsFile("sonar.path.logs")).isEqualTo(logsDir); + assertThat(props.nonNullValueAsFile("sonar.path.home")).isEqualTo(homeDir); // create /temp - File tempDir = props.fileOf("sonar.path.temp"); + File tempDir = props.nonNullValueAsFile("sonar.path.temp"); assertThat(tempDir).isDirectory().exists(); assertThat(tempDir.getName()).isEqualTo("temp"); assertThat(tempDir.getParentFile()).isEqualTo(homeDir); - assertThat(props.of("foo")).isEqualTo("bar"); - assertThat(props.of("unknown")).isNull(); + assertThat(props.value("foo")).isEqualTo("bar"); + assertThat(props.value("unknown")).isNull(); // default properties - assertThat(props.intOf("sonar.search.port")).isEqualTo(9001); + assertThat(props.valueAsInt("sonar.search.port")).isEqualTo(9001); } @Test @@ -113,8 +113,8 @@ public class PropsBuilderTest { rawProperties.setProperty("sonar.origin", "raw"); Props props = new PropsBuilder(rawProperties, jdbcSettings, homeDir).build(); - assertThat(props.of("sonar.jdbc.username")).isEqualTo("angela"); + assertThat(props.value("sonar.jdbc.username")).isEqualTo("angela"); // command-line arguments override sonar.properties file - assertThat(props.of("sonar.origin")).isEqualTo("raw"); + assertThat(props.value("sonar.origin")).isEqualTo("raw"); } } -- 2.39.5