diff options
author | Michal Duda <michal.duda@sonarsource.com> | 2019-05-16 12:36:17 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-05-21 20:21:07 +0200 |
commit | dfcb1c01a430cf3317d12ff4448fc700b9979d4f (patch) | |
tree | 07a32c098cc59661abf85ff15bdff909e2cfd4b0 /server/sonar-process | |
parent | 42aa152b7b174ce55796b8b00758d1fe63643cb7 (diff) | |
download | sonarqube-dfcb1c01a430cf3317d12ff4448fc700b9979d4f.tar.gz sonarqube-dfcb1c01a430cf3317d12ff4448fc700b9979d4f.zip |
SONAR-11720 Set different memory defaults for EE+
Diffstat (limited to 'server/sonar-process')
3 files changed, 136 insertions, 14 deletions
diff --git a/server/sonar-process/build.gradle b/server/sonar-process/build.gradle index 4f6c00cbf54..d458ec793f0 100644 --- a/server/sonar-process/build.gradle +++ b/server/sonar-process/build.gradle @@ -15,7 +15,8 @@ dependencies { compile 'com.hazelcast:hazelcast' compile 'org.slf4j:jul-to-slf4j' compile 'org.slf4j:slf4j-api' - + compile project(':sonar-core') + compileOnly 'com.google.code.findbugs:jsr305' compileOnly 'com.google.protobuf:protobuf-java' compileOnly 'org.nanohttpd:nanohttpd' diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java index cf9dce23bd5..fd0a8b7dad2 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java @@ -22,12 +22,18 @@ package org.sonar.process; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.sonar.core.extension.CoreExtension; +import org.sonar.core.extension.ServiceLoaderWrapper; + +import static java.lang.String.format; /** * Constants shared by search, web server and app processes. @@ -35,6 +41,8 @@ import javax.annotation.Nullable; */ public class ProcessProperties { + private final ServiceLoaderWrapper serviceLoaderWrapper; + public enum Property { JDBC_URL("sonar.jdbc.url"), JDBC_USERNAME("sonar.jdbc.username", ""), @@ -151,11 +159,11 @@ public class ProcessProperties { } } - private ProcessProperties() { - // only static stuff + public ProcessProperties(ServiceLoaderWrapper serviceLoaderWrapper) { + this.serviceLoaderWrapper = serviceLoaderWrapper; } - public static void completeDefaults(Props props) { + public void completeDefaults(Props props) { // init string properties for (Map.Entry<Object, Object> entry : defaults().entrySet()) { props.setDefault(entry.getKey().toString(), entry.getValue().toString()); @@ -164,14 +172,30 @@ public class ProcessProperties { fixPortIfZero(props, Property.SEARCH_HOST.getKey(), Property.SEARCH_PORT.getKey()); } - public static Properties defaults() { + private Properties defaults() { Properties defaults = new Properties(); defaults.putAll(Arrays.stream(Property.values()) .filter(Property::hasDefaultValue) .collect(Collectors.toMap(Property::getKey, Property::getDefaultValue))); + defaults.putAll(loadDefaultsFromExtensions()); return defaults; } + private Map<String, String> loadDefaultsFromExtensions() { + Map<String, String> propertyDefaults = new HashMap<>(); + Set<CoreExtension> extensions = serviceLoaderWrapper.load(); + for (CoreExtension ext : extensions) { + for (Map.Entry<String, String> property : ext.getExtensionProperties().entrySet()) { + if (propertyDefaults.put(property.getKey(), property.getValue()) != null) { + throw new IllegalStateException(format("Configuration error: property definition named '%s' found in multiple extensions.", + property.getKey())); + } + } + } + + return propertyDefaults; + } + private static void fixPortIfZero(Props props, String addressPropertyKey, String portPropertyKey) { String port = props.value(portPropertyKey); if ("0".equals(port)) { diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java index 24b0f49c810..7a5d004249c 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java @@ -19,19 +19,34 @@ */ package org.sonar.process; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import java.net.InetAddress; +import java.util.Map; import java.util.Properties; +import org.junit.Rule; import org.junit.Test; -import org.sonar.test.TestUtils; +import org.junit.rules.ExpectedException; +import org.sonar.core.extension.CoreExtension; +import org.sonar.core.extension.ServiceLoaderWrapper; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ProcessPropertiesTest { + private ServiceLoaderWrapper serviceLoaderWrapper = mock(ServiceLoaderWrapper.class); + private ProcessProperties processProperties = new ProcessProperties(serviceLoaderWrapper); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Test public void completeDefaults_adds_default_values() { Props props = new Props(new Properties()); - ProcessProperties.completeDefaults(props); + + processProperties.completeDefaults(props); assertThat(props.value("sonar.search.javaOpts")).contains("-Xmx"); assertThat(props.valueAsInt("sonar.jdbc.maxActive")).isEqualTo(60); @@ -44,21 +59,22 @@ public class ProcessPropertiesTest { Properties p = new Properties(); p.setProperty("sonar.jdbc.username", "angela"); Props props = new Props(p); - ProcessProperties.completeDefaults(props); + + processProperties.completeDefaults(props); assertThat(props.value("sonar.jdbc.username")).isEqualTo("angela"); } @Test - public void completeDefaults_set_default_elasticsearch_port_and_bind_address() throws Exception{ + public void completeDefaults_set_default_elasticsearch_port_and_bind_address() throws Exception { Properties p = new Properties(); Props props = new Props(p); - ProcessProperties.completeDefaults(props); + + processProperties.completeDefaults(props); String address = props.value("sonar.search.host"); assertThat(address).isNotEmpty(); assertThat(InetAddress.getByName(address).isLoopbackAddress()).isTrue(); - assertThat(props.valueAsInt("sonar.search.port")).isEqualTo(9001); } @@ -68,12 +84,93 @@ public class ProcessPropertiesTest { p.setProperty("sonar.search.port", "0"); Props props = new Props(p); - ProcessProperties.completeDefaults(props); + processProperties.completeDefaults(props); + assertThat(props.valueAsInt("sonar.search.port")).isGreaterThan(0); } @Test - public void private_constructor() { - assertThat(TestUtils.hasOnlyPrivateConstructors(ProcessProperties.class)).isTrue(); + public void defaults_loads_properties_defaults_from_base_and_extensions() { + Props p = new Props(new Properties()); + when(serviceLoaderWrapper.load()).thenReturn(ImmutableSet.of(new FakeExtension1(), new FakeExtension3())); + + processProperties.completeDefaults(p); + + assertThat(p.value("sonar.some.property")).isEqualTo("1"); + assertThat(p.value("sonar.some.property2")).isEqualTo("455"); + assertThat(p.value("sonar.some.property4")).isEqualTo("abc"); + assertThat(p.value("sonar.some.property5")).isEqualTo("def"); + assertThat(p.value("sonar.some.property5")).isEqualTo("def"); + assertThat(p.value("sonar.search.port")).isEqualTo("9001"); + } + + @Test + public void defaults_throws_exception_on_same_property_defined_more_than_once_in_extensions() { + Props p = new Props(new Properties()); + when(serviceLoaderWrapper.load()).thenReturn(ImmutableSet.of(new FakeExtension1(), new FakeExtension2())); + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Configuration error: property definition named 'sonar.some.property2' found in multiple extensions."); + + processProperties.completeDefaults(p); + } + + private class FakeExtension1 implements CoreExtension { + + @Override + public String getName() { + return "fakeExt1"; + } + + @Override + public void load(Context context) { + // do nothing + } + + @Override + public Map<String, String> getExtensionProperties() { + return ImmutableMap.of( + "sonar.some.property", "1", + "sonar.some.property2", "455"); + } + } + + private class FakeExtension2 implements CoreExtension { + + @Override + public String getName() { + return "fakeExt2"; + } + + @Override + public void load(Context context) { + // do nothing + } + + @Override + public Map<String, String> getExtensionProperties() { + return ImmutableMap.of( + "sonar.some.property2", "5435", + "sonar.some.property3", "32131"); + } + } + + private class FakeExtension3 implements CoreExtension { + + @Override + public String getName() { + return "fakeExt3"; + } + + @Override + public void load(Context context) { + // do nothing + } + + @Override + public Map<String, String> getExtensionProperties() { + return ImmutableMap.of( + "sonar.some.property4", "abc", + "sonar.some.property5", "def"); + } } } |