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: [email protected]
For additional commands, e-mail: [email protected]