You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ma...@apache.org on 2014/10/08 18:34:10 UTC

svn commit: r1630167 - in /qpid/trunk/qpid/java: bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/ bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ broker-core/src/main/java/org/apache/qpid/server/model/

Author: macbean
Date: Wed Oct  8 16:34:10 2014
New Revision: 1630167

URL: http://svn.apache.org/r1630167
Log:
QPID-6134: [Java Broker] Restarting a node that has detected an intruder should go back into the ERROR state not ACTIVE

Modified:
    qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java

Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1630167&r1=1630166&r2=1630167&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java Wed Oct  8 16:34:10 2014
@@ -335,6 +335,24 @@ public class BDBHAVirtualHostNodeImpl ex
             throw new IllegalStateException("Environment facade is not created");
         }
 
+        try
+        {
+            Set<ReplicationNode> remoteNodes = environmentFacade.getEnvironment().getGroup().getNodes();
+            for (ReplicationNode node : remoteNodes)
+            {
+                String nodeAddress = node.getHostName() + ":" + node.getPort();
+                if (!_permittedNodes.contains(nodeAddress))
+                {
+                    shutdownOnIntruder(nodeAddress);
+                    throw new IllegalStateException("Intruder node detected: " + nodeAddress);
+                }
+            }
+        }
+        catch (DatabaseException dbe)
+        {
+            environmentFacade.handleDatabaseException("DB exception while checking for intruder node", dbe);
+        }
+
         if (_environmentFacade.compareAndSet(null, environmentFacade))
         {
             environmentFacade.setStateChangeListener(new EnvironmentStateChangeListener());
@@ -1047,7 +1065,7 @@ public class BDBHAVirtualHostNodeImpl ex
 
         private boolean processIntruderNode(ReplicationNode node)
         {
-            String hostAndPort = node.getHostName() + ":" + node.getPort();
+            final String hostAndPort = node.getHostName() + ":" + node.getPort();
             getEventLogger().message(getGroupLogSubject(), HighAvailabilityMessages.INTRUDER_DETECTED(node.getName(), hostAndPort));
 
             boolean inManagementMode = getParent(Broker.class).isManagementMode();
@@ -1069,35 +1087,16 @@ public class BDBHAVirtualHostNodeImpl ex
                                            BDBHAVirtualHostNodeImpl.this.getName(),
                                            _lastRole.get(),
                                            String.valueOf(BDBHAVirtualHostNodeImpl.this.getPermittedNodes()) ));
-
                 getTaskExecutor().submit(new Task<Void>()
                 {
                     @Override
                     public Void execute()
                     {
-                        State state = getState();
-                        if (state != State.ERRORED)
-                        {
-                            try
-                            {
-                                stopAndSetStateTo(State.ERRORED);
-                            }
-                            catch(Exception e)
-                            {
-                                LOGGER.error("Unexpected exception on closing the node when intruder is detected ", e);
-                            }
-                            finally
-                            {
-                                closeEnvironment();
-
-                                _lastRole.set(NodeRole.DETACHED);
-                                attributeSet(ROLE, _role, NodeRole.DETACHED);
-                            }
-                            notifyStateChanged(state, State.ERRORED);
-                        }
+                        shutdownOnIntruder(hostAndPort);
                         return null;
                     }
                 });
+
                 return false;
             }
         }
@@ -1119,6 +1118,28 @@ public class BDBHAVirtualHostNodeImpl ex
         }
     }
 
+    protected void shutdownOnIntruder(String intruderHostAndPort)
+    {
+        LOGGER.info("Intruder detected (" + intruderHostAndPort + "), stopping and setting state to ERRORED");
+
+        State initialState = getState();
+        try
+        {
+            stopAndSetStateTo(State.ERRORED);
+        }
+        catch (Exception e)
+        {
+            LOGGER.error("Unexpected exception on closing the node when intruder is detected ", e);
+        }
+        finally
+        {
+            closeEnvironment();
+            _lastRole.set(NodeRole.DETACHED);
+            attributeSet(ROLE, _role, NodeRole.DETACHED);
+        }
+        notifyStateChanged(initialState, State.ERRORED);
+    }
+
     private abstract class VirtualHostNodeGroupTask implements Task<Void>
     {
         @Override

Modified: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java?rev=1630167&r1=1630166&r2=1630167&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java Wed Oct  8 16:34:10 2014
@@ -42,6 +42,7 @@ import com.sleepycat.je.rep.ReplicatedEn
 import com.sleepycat.je.rep.ReplicationConfig;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfigurationChangeListener;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.RemoteReplicationNode;
@@ -489,21 +490,70 @@ public class BDBHAVirtualHostNodeTest ex
         nonMasterNode.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, amendedPermittedNodes));
     }
 
+    public void testIntruderProtection() throws Exception
+    {
+        int nodePortNumber = _portHelper.getNextAvailable();
+        int intruderPortNumber = _portHelper.getNextAvailable();
+
+        String helperAddress = "localhost:" + nodePortNumber;
+        String groupName = "group";
+        String nodeName = "node";
+
+        Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, nodePortNumber, intruderPortNumber);
+        BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(node1Attributes);
+
+        Map<String, Object> intruderAttributes = _helper.createNodeAttributes("intruder", groupName, "localhost:" + intruderPortNumber, helperAddress, nodeName);
+        intruderAttributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
+        BDBHAVirtualHostNode<?> intruder = _helper.createAndStartHaVHN(intruderAttributes);
+
+        final CountDownLatch stopLatch = new CountDownLatch(1);
+        ConfigurationChangeListener listener = new NoopConfigurationChangeListener()
+        {
+            @Override
+            public void stateChanged(ConfiguredObject<?> object, State oldState, State newState)
+            {
+                if (newState == State.ERRORED)
+                {
+                    stopLatch.countDown();
+                }
+            }
+        };
+        node.addChangeListener(listener);
+
+        List<String> permittedNodes = new ArrayList<String>();
+        permittedNodes.add(helperAddress);
+        node.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes));
+
+        assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS));
+
+        // Try top re start the ERRORED node and ensure exception is thrown
+        try
+        {
+            node.start();
+            fail("Restart of node should have thrown exception");
+        }
+        catch (IllegalStateException ise)
+        {
+            assertEquals("Unexpected exception when restarting node post intruder detection", "Intruder node detected: " + "localhost:" + intruderPortNumber, ise.getMessage());
+        }
+        _helper.awaitForAttributeChange(node, AbstractConfiguredObject.STATE, State.ERRORED);
+    }
+
     public void testIntruderProtectionInManagementMode() throws Exception
     {
-        int node1PortNumber = _portHelper.getNextAvailable();
-        int node2PortNumber = _portHelper.getNextAvailable();
+        int nodePortNumber = _portHelper.getNextAvailable();
+        int intruderPortNumber = _portHelper.getNextAvailable();
 
-        String helperAddress = "localhost:" + node1PortNumber;
+        String helperAddress = "localhost:" + nodePortNumber;
         String groupName = "group";
-        String nodeName = "node1";
+        String nodeName = "node";
 
-        Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, node1PortNumber, node2PortNumber);
-        BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes);
+        Map<String, Object> nodeAttributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, nodePortNumber, intruderPortNumber);
+        BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(nodeAttributes);
 
-        Map<String, Object> node2Attributes = _helper.createNodeAttributes("node2", groupName, "localhost:" + node2PortNumber, helperAddress, nodeName);
-        node2Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
-        BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes);
+        Map<String, Object> intruderAttributes = _helper.createNodeAttributes("intruder", groupName, "localhost:" + intruderPortNumber, helperAddress, nodeName);
+        intruderAttributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
+        BDBHAVirtualHostNode<?> intruder = _helper.createAndStartHaVHN(intruderAttributes);
 
         final CountDownLatch stopLatch = new CountDownLatch(1);
         ConfigurationChangeListener listener = new NoopConfigurationChangeListener()
@@ -517,21 +567,19 @@ public class BDBHAVirtualHostNodeTest ex
                 }
             }
         };
-        node1.addChangeListener(listener);
+        node.addChangeListener(listener);
 
         List<String> permittedNodes = new ArrayList<String>();
         permittedNodes.add(helperAddress);
-        node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes));
+        node.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes));
 
         assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS));
 
+        // test that if management mode is enabled then the node can start without exception
         when(_helper.getBroker().isManagementMode()).thenReturn(true);
-        node1.start();
-
-        _helper.awaitRemoteNodes(node1, 1);
+        node.start();
 
-        BDBHARemoteReplicationNode<?> remote = _helper.findRemoteNode(node1, node2.getName());
-        remote.delete();
+        _helper.awaitForAttributeChange(node, AbstractConfiguredObject.STATE, State.ERRORED);
     }
 
     public void testPermittedNodesChangedOnReplicaNodeOnlyOnceAfterBeingChangedOnMaster() throws Exception

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1630167&r1=1630166&r2=1630167&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Wed Oct  8 16:34:10 2014
@@ -949,7 +949,12 @@ public abstract class AbstractConfigured
                                 if(desiredState == getDesiredState() && desiredState != state)
                                 {
                                     attainStateIfOpenedOrReopenFailed();
-                                    return getState();
+                                    final State currentState = getState();
+                                    if (currentState != state)
+                                    {
+                                        notifyStateChanged(state, currentState);
+                                    }
+                                    return currentState;
                                 }
                                 else
                                 {



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org