This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/master by this push:
     new c551df7  ARTEMIS-2868 Protect Topology Updates from Split Brain on 
broker shutdown as well
     new 02b8135  This closes #3239
c551df7 is described below

commit c551df770c50f04d7d95378fbfb8997cd43ec335
Author: Clebert Suconic <[email protected]>
AuthorDate: Fri Aug 7 11:03:04 2020 -0400

    ARTEMIS-2868 Protect Topology Updates from Split Brain on broker shutdown 
as well
---
 .../apache/activemq/artemis/cli/commands/Stop.java |  3 ++-
 .../artemis/core/client/impl/Topology.java         |  6 +++++
 .../artemis/core/client/impl/TopologyManager.java  |  1 +
 .../server/cluster/impl/ClusterConnectionImpl.java | 22 ++++++++++++++----
 .../artemis/tests/smoke/common/SmokeTestBase.java  | 10 ++++++++
 .../tests/smoke/dnsswitch/DNSSwitchTest.java       | 27 ++++++++++++++++++----
 6 files changed, 59 insertions(+), 10 deletions(-)

diff --git 
a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Stop.java 
b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Stop.java
index 5f89253..c071dac 100644
--- 
a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Stop.java
+++ 
b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Stop.java
@@ -24,6 +24,7 @@ import org.apache.activemq.artemis.dto.BrokerDTO;
 @Command(name = "stop", description = "stops the broker instance")
 public class Stop extends Configurable {
 
+   public static final String STOP_FILE_NAME = "STOP_ME";
    @Override
    public Object execute(ActionContext context) throws Exception {
       super.execute(context);
@@ -31,7 +32,7 @@ public class Stop extends Configurable {
 
       File file = broker.server.getConfigurationFile().getParentFile();
 
-      File stopFile = new File(file, "STOP_ME");
+      File stopFile = new File(file, STOP_FILE_NAME);
 
       stopFile.createNewFile();
 
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/Topology.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/Topology.java
index 432d49b..749f167 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/Topology.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/Topology.java
@@ -310,6 +310,12 @@ public final class Topology {
    boolean removeMember(final long uniqueEventID, final String nodeId) {
       TopologyMemberImpl member;
 
+
+      if (manager != null && !manager.removeMember(uniqueEventID, nodeId)) {
+         logger.debugf("TopologyManager rejected the update towards %s", 
nodeId);
+         return false;
+      }
+
       synchronized (this) {
          member = topology.get(nodeId);
          if (member != null) {
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyManager.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyManager.java
index 611bf73..76c9e24 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyManager.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyManager.java
@@ -19,4 +19,5 @@ package org.apache.activemq.artemis.core.client.impl;
 
 public interface TopologyManager {
    boolean updateMember(long uniqueEventID, String nodeId, TopologyMemberImpl 
memberInput);
+   boolean removeMember(long uniqueEventID, String nodeId);
 }
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
index 5abba5d..03c5c0c 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java
@@ -521,17 +521,29 @@ public final class ClusterConnectionImpl implements 
ClusterConnection, AfterConn
    @Override
    public boolean updateMember(long uniqueEventID, String nodeId, 
TopologyMemberImpl memberInput) {
       if (splitBrainDetection && 
nodeId.equals(nodeManager.getNodeId().toString())) {
-         TopologyMemberImpl member = topology.getMember(nodeId);
-         if (member != null) {
-            if (member.getLive() != null && memberInput.getLive() != null && 
!member.getLive().isSameParams(connector)) {
-               ActiveMQServerLogger.LOGGER.possibleSplitBrain(nodeId, 
memberInput.toString());
-            }
+         if (memberInput.getLive() != null && 
!memberInput.getLive().isSameParams(connector)) {
+            ActiveMQServerLogger.LOGGER.possibleSplitBrain(nodeId, 
memberInput.toString());
          }
          memberInput.setLive(connector);
       }
       return true;
    }
 
+   /**
+    * From topologyManager
+    * @param uniqueEventID
+    * @param nodeId
+    * @return
+    */
+   @Override
+   public boolean removeMember(final long uniqueEventID, final String nodeId) {
+      if (splitBrainDetection && 
nodeId.equals(nodeManager.getNodeId().toString())) {
+         ActiveMQServerLogger.LOGGER.possibleSplitBrain(nodeId, nodeId);
+         return false;
+      }
+      return true;
+   }
+
    @Override
    public void setSplitBrainDetection(boolean splitBrainDetection) {
       this.splitBrainDetection = splitBrainDetection;
diff --git 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
index 543de50..964b749 100644
--- 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
+++ 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
@@ -18,12 +18,15 @@
 package org.apache.activemq.artemis.tests.smoke.common;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.activemq.artemis.cli.commands.Stop;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.util.ServerUtil;
 import org.junit.After;
+import org.junit.Assert;
 
 public class SmokeTestBase extends ActiveMQTestBase {
    Set<Process> processes = new HashSet<>();
@@ -51,6 +54,13 @@ public class SmokeTestBase extends ActiveMQTestBase {
       }
    }
 
+   protected static void stopServerWithFile(String serverLocation) throws 
IOException {
+      File serverPlace = new File(serverLocation);
+      File etcPlace = new File(serverPlace, "etc");
+      File stopMe = new File(etcPlace, Stop.STOP_FILE_NAME);
+      Assert.assertTrue(stopMe.createNewFile());
+   }
+
    public static String getServerLocation(String serverName) {
       return basedir + "/target/" + serverName;
    }
diff --git 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
index 2be1541..e426dba 100644
--- 
a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
+++ 
b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
@@ -663,13 +663,25 @@ public class DNSSwitchTest extends SmokeTestBase {
 
    }
 
-
    @Test
-   public void testWithoutPing() throws Throwable {
-      spawnRun(serverLocation, "testWithoutPing", 
getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP));
+   public void testWithoutPingKill() throws Throwable {
+      spawnRun(serverLocation, "testWithoutPing", 
getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP), "1");
    }
 
+   @Test
+   public void testWithoutPingRestart() throws Throwable {
+      spawnRun(serverLocation, "testWithoutPing", 
getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP), "0");
+   }
+   /**
+    * arg[0] = constant "testWithoutPing" to be used on reflection through 
main(String arg[])
+    * arg[1] = serverlive
+    * arg[2] = server backup
+    * arg[3] = 1 | 0 (kill the backup = 1, stop the backup = 0);
+    * @param args
+    * @throws Throwable
+    */
    public static void testWithoutPing(String[] args) throws Throwable {
+      boolean killTheBackup = Integer.parseInt(args[3]) == 1;
       NetUtil.netUp(FIRST_IP, "lo:first");
       NetUtil.netUp(SECOND_IP, "lo:second");
 
@@ -719,7 +731,13 @@ public class DNSSwitchTest extends SmokeTestBase {
          System.out.println("Forcing backup down and restarting it");
          
System.out.println("*******************************************************************************************************************************");
 
-         serverBackup.destroyForcibly();
+         if (killTheBackup) {
+            serverBackup.destroyForcibly();
+         } else {
+            String serverLocation = args[2];
+            stopServerWithFile(serverLocation);
+            Assert.assertTrue(serverBackup.waitFor(10, TimeUnit.SECONDS));
+         }
 
          cleanupData(SERVER_BACKUP);
 
@@ -740,6 +758,7 @@ public class DNSSwitchTest extends SmokeTestBase {
 
    }
 
+
    private static void connectAndWaitBackup() throws Exception {
       ActiveMQConnectionFactory connectionFactory = new 
ActiveMQConnectionFactory("tcp://FIRST:61616?ha=true");
       Assert.assertTrue(connectionFactory.getServerLocator().isHA());

Reply via email to