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