diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-09-18 15:38:49 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-09-26 23:49:37 +0200 |
commit | df538630ea2ae47b725414257f65a8a9e28722bb (patch) | |
tree | 6d30b4a2e45fd54a115775b11c625f1cdb24bd68 /server/sonar-main | |
parent | e4c401f8bc9100fec7fd28bb93469d3de199f5f7 (diff) | |
download | sonarqube-df538630ea2ae47b725414257f65a8a9e28722bb.tar.gz sonarqube-df538630ea2ae47b725414257f65a8a9e28722bb.zip |
SONAR-9802 ability to execute distributed calls
See HazelcastMember#call(DistributedCall, ...)
Diffstat (limited to 'server/sonar-main')
5 files changed, 44 insertions, 84 deletions
diff --git a/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java b/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java index a2b9cbd7d70..0498f2e4100 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java +++ b/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java @@ -42,7 +42,7 @@ public class AppStateFactory { public AppState create() { if (ClusterSettings.isClusterEnabled(settings)) { HazelcastMember hzMember = createHzMember(settings.getProps()); - return new ClusterAppStateImpl(hzMember); + return new ClusterAppStateImpl(settings, hzMember); } return new AppStateImpl(); } diff --git a/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java b/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java index 4862cfa89de..8589e29414a 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java @@ -28,8 +28,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.application.cluster.ClusterAppState; -import org.sonar.application.cluster.health.SearchNodeHealthProvider; import org.sonar.application.command.CommandFactory; import org.sonar.application.command.EsCommand; import org.sonar.application.command.JavaCommand; @@ -41,10 +39,7 @@ import org.sonar.application.process.ProcessLauncher; import org.sonar.application.process.ProcessLifecycleListener; import org.sonar.application.process.ProcessMonitor; import org.sonar.application.process.SQProcess; -import org.sonar.process.NetworkUtils; import org.sonar.process.ProcessId; -import org.sonar.application.cluster.health.HealthStateSharing; -import org.sonar.application.cluster.health.HealthStateSharingImpl; public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLifecycleListener, AppStateListener { @@ -65,7 +60,6 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi private final AtomicInteger stopCountDown = new AtomicInteger(0); private StopperThread stopperThread; private RestarterThread restarterThread; - private HealthStateSharing healthStateSharing; private long processWatcherDelayMs = SQProcess.DEFAULT_WATCHER_DELAY_MS; public SchedulerImpl(AppSettings settings, AppReloader appReloader, CommandFactory commandFactory, @@ -105,7 +99,6 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi } private void tryToStartAll() { - tryToStartHealthStateSharing(); tryToStartEs(); tryToStartWeb(); tryToStartCe(); @@ -144,18 +137,6 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi } } - private void tryToStartHealthStateSharing() { - if (healthStateSharing == null - && appState instanceof ClusterAppState - && ClusterSettings.isLocalElasticsearchEnabled(settings)) { - ClusterAppState clusterAppState = (ClusterAppState) appState; - this.healthStateSharing = new HealthStateSharingImpl( - clusterAppState.getHazelcastMember(), - new SearchNodeHealthProvider(settings.getProps(), clusterAppState, NetworkUtils.INSTANCE)); - this.healthStateSharing.start(); - } - } - private boolean isEsClientStartable() { boolean requireLocalEs = ClusterSettings.isLocalElasticsearchEnabled(settings); return appState.isOperational(ProcessId.ELASTICSEARCH, requireLocalEs); @@ -190,7 +171,6 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi stopProcess(ProcessId.COMPUTE_ENGINE); stopProcess(ProcessId.WEB_SERVER); stopProcess(ProcessId.ELASTICSEARCH); - stopHealthStateSharing(); } /** @@ -204,12 +184,6 @@ public class SchedulerImpl implements Scheduler, ProcessEventListener, ProcessLi } } - private void stopHealthStateSharing() { - if (healthStateSharing != null) { - healthStateSharing.stop(); - } - } - /** * Blocks until all processes are stopped. Pending restart, if * any, is disabled. diff --git a/server/sonar-main/src/main/java/org/sonar/application/cluster/ClusterAppStateImpl.java b/server/sonar-main/src/main/java/org/sonar/application/cluster/ClusterAppStateImpl.java index 80940e96b38..3c23a5501eb 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/cluster/ClusterAppStateImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/cluster/ClusterAppStateImpl.java @@ -39,7 +39,13 @@ import java.util.concurrent.locks.Lock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.application.AppStateListener; +import org.sonar.application.cluster.health.HealthStateSharing; +import org.sonar.application.cluster.health.HealthStateSharingImpl; +import org.sonar.application.cluster.health.SearchNodeHealthProvider; +import org.sonar.application.config.AppSettings; +import org.sonar.application.config.ClusterSettings; import org.sonar.process.MessageException; +import org.sonar.process.NetworkUtils; import org.sonar.process.ProcessId; import org.sonar.process.cluster.NodeType; import org.sonar.process.cluster.hz.HazelcastMember; @@ -60,14 +66,20 @@ public class ClusterAppStateImpl implements ClusterAppState { private final ReplicatedMap<ClusterProcess, Boolean> operationalProcesses; private final String operationalProcessListenerUUID; private final String nodeDisconnectedListenerUUID; + private HealthStateSharing healthStateSharing = null; - public ClusterAppStateImpl(HazelcastMember hzMember) { + public ClusterAppStateImpl(AppSettings settings, HazelcastMember hzMember) { this.hzMember = hzMember; // Get or create the replicated map operationalProcesses = (ReplicatedMap) hzMember.getReplicatedMap(OPERATIONAL_PROCESSES); operationalProcessListenerUUID = operationalProcesses.addEntryListener(new OperationalProcessListener()); nodeDisconnectedListenerUUID = hzMember.getCluster().addMembershipListener(new NodeDisconnectedListener()); + + if (ClusterSettings.isLocalElasticsearchEnabled(settings)) { + this.healthStateSharing = new HealthStateSharingImpl(hzMember, new SearchNodeHealthProvider(settings.getProps(), this, NetworkUtils.INSTANCE)); + this.healthStateSharing.start(); + } } @Override @@ -184,6 +196,9 @@ public class ClusterAppStateImpl implements ClusterAppState { @Override public void close() { if (hzMember != null) { + if (healthStateSharing != null) { + healthStateSharing.stop(); + } try { // Removing listeners operationalProcesses.removeEntryListener(operationalProcessListenerUUID); diff --git a/server/sonar-main/src/test/java/org/sonar/application/cluster/ClusterAppStateImplTest.java b/server/sonar-main/src/test/java/org/sonar/application/cluster/ClusterAppStateImplTest.java index 72e117924a2..bf93a7b88c5 100644 --- a/server/sonar-main/src/test/java/org/sonar/application/cluster/ClusterAppStateImplTest.java +++ b/server/sonar-main/src/test/java/org/sonar/application/cluster/ClusterAppStateImplTest.java @@ -19,6 +19,7 @@ */ package org.sonar.application.cluster; +import java.net.InetAddress; import org.junit.Rule; import org.junit.Test; import org.junit.rules.DisableOnDebug; @@ -26,14 +27,18 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TestRule; import org.junit.rules.Timeout; import org.sonar.application.AppStateListener; +import org.sonar.application.config.TestAppSettings; import org.sonar.process.MessageException; +import org.sonar.process.NetworkUtils; import org.sonar.process.ProcessId; +import org.sonar.process.cluster.NodeType; +import org.sonar.process.cluster.hz.HazelcastMember; +import org.sonar.process.cluster.hz.HazelcastMemberBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.sonar.application.cluster.HazelcastTesting.newHzMember; import static org.sonar.process.cluster.hz.HazelcastObjects.CLUSTER_NAME; import static org.sonar.process.cluster.hz.HazelcastObjects.SONARQUBE_VERSION; @@ -47,7 +52,7 @@ public class ClusterAppStateImplTest { @Test public void tryToLockWebLeader_returns_true_only_for_the_first_call() throws Exception { - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { assertThat(underTest.tryToLockWebLeader()).isEqualTo(true); assertThat(underTest.tryToLockWebLeader()).isEqualTo(false); } @@ -56,7 +61,7 @@ public class ClusterAppStateImplTest { @Test public void test_listeners() throws InterruptedException { AppStateListener listener = mock(AppStateListener.class); - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { underTest.addListener(listener); underTest.setOperational(ProcessId.ELASTICSEARCH); @@ -72,7 +77,7 @@ public class ClusterAppStateImplTest { @Test public void registerSonarQubeVersion_publishes_version_on_first_call() { - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { underTest.registerSonarQubeVersion("6.4.1.5"); assertThat(underTest.getHazelcastMember().getAtomicReference(SONARQUBE_VERSION).get()) @@ -82,7 +87,7 @@ public class ClusterAppStateImplTest { @Test public void registerClusterName_publishes_clusterName_on_first_call() { - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { underTest.registerClusterName("foo"); assertThat(underTest.getHazelcastMember().getAtomicReference(CLUSTER_NAME).get()) @@ -92,7 +97,7 @@ public class ClusterAppStateImplTest { @Test public void reset_always_throws_ISE() { - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("state reset is not supported in cluster mode"); @@ -103,7 +108,7 @@ public class ClusterAppStateImplTest { @Test public void registerSonarQubeVersion_throws_ISE_if_initial_version_is_different() throws Exception { // Now launch an instance that try to be part of the hzInstance cluster - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { // Register first version underTest.getHazelcastMember().getAtomicReference(SONARQUBE_VERSION).set("6.6.0.1111"); @@ -117,7 +122,7 @@ public class ClusterAppStateImplTest { @Test public void registerClusterName_throws_MessageException_if_clusterName_is_different() throws Exception { - try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(newHzMember())) { + try (ClusterAppStateImpl underTest = new ClusterAppStateImpl(new TestAppSettings(), newHzMember())) { // Register first version underTest.getHazelcastMember().getAtomicReference(CLUSTER_NAME).set("goodClusterName"); @@ -128,4 +133,18 @@ public class ClusterAppStateImplTest { underTest.registerClusterName("badClusterName"); } } + + private static HazelcastMember newHzMember() { + // use loopback for support of offline builds + InetAddress loopback = InetAddress.getLoopbackAddress(); + + return new HazelcastMemberBuilder() + .setNodeType(NodeType.APPLICATION) + .setProcessId(ProcessId.COMPUTE_ENGINE) + .setClusterName("foo") + .setNodeName("bar") + .setPort(NetworkUtils.INSTANCE.getNextAvailablePort(loopback)) + .setNetworkInterface(loopback.getHostAddress()) + .build(); + } } diff --git a/server/sonar-main/src/test/java/org/sonar/application/cluster/HazelcastTesting.java b/server/sonar-main/src/test/java/org/sonar/application/cluster/HazelcastTesting.java deleted file mode 100644 index cf8fea2bb26..00000000000 --- a/server/sonar-main/src/test/java/org/sonar/application/cluster/HazelcastTesting.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2017 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.application.cluster; - -import java.net.InetAddress; -import org.sonar.process.NetworkUtils; -import org.sonar.process.ProcessId; -import org.sonar.process.cluster.NodeType; -import org.sonar.process.cluster.hz.HazelcastMember; -import org.sonar.process.cluster.hz.HazelcastMemberBuilder; - -public class HazelcastTesting { - - private HazelcastTesting() { - // do not instantiate - } - - public static HazelcastMember newHzMember() { - // use loopback for support of offline builds - InetAddress loopback = InetAddress.getLoopbackAddress(); - - return new HazelcastMemberBuilder() - .setNodeType(NodeType.APPLICATION) - .setProcessId(ProcessId.COMPUTE_ENGINE) - .setClusterName("foo") - .setNodeName("bar") - .setPort(NetworkUtils.INSTANCE.getNextAvailablePort(loopback)) - .setNetworkInterface(loopback.getHostAddress()) - .build(); - } -} |