summaryrefslogtreecommitdiff
path: root/qpid/java/bdbstore/src
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/bdbstore/src')
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java130
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHost.java2
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java72
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java2
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html4
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html4
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html4
-rw-r--r--qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html4
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java48
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java55
10 files changed, 211 insertions, 114 deletions
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
index 92115dd39f..d045ae01fa 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
@@ -95,7 +95,7 @@ import org.apache.qpid.server.util.DaemonThreadFactory;
public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChangeListener
{
public static final String MASTER_TRANSFER_TIMEOUT_PROPERTY_NAME = "qpid.bdb.ha.master_transfer_interval";
- public static final String DB_PING_SOCKET_TIMEOUT_PROPERTY_NAME = "qpid.bdb.ha.db_ping_socket_timeout";
+ public static final String DB_PING_SOCKET_TIMEOUT_PROPERTY_NAME = "qpid.bdb.replication.db_ping_socket_timeout";
public static final String REMOTE_NODE_MONITOR_INTERVAL_PROPERTY_NAME = "qpid.bdb.ha.remote_node_monitor_interval";
private static final Logger LOGGER = Logger.getLogger(ReplicatedEnvironmentFacade.class);
@@ -289,10 +289,20 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
{
try
{
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Closing replicated environment");
+ }
+
closeEnvironment();
}
finally
{
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Deregistering environment home " + _environmentDirectory);
+ }
+
EnvHomeRegistry.getInstance().deregisterHome(_environmentDirectory);
}
}
@@ -823,6 +833,11 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
private void closeEnvironment()
{
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Closing JE environment for " + _prettyGroupNodeName);
+ }
+
// Clean the log before closing. This makes sure it doesn't contain
// redundant data. Closing without doing this means the cleaner may not
// get a chance to finish.
@@ -1094,15 +1109,6 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
return environment;
}
- NodeState getRemoteNodeState(ReplicationNode repNode) throws IOException, ServiceConnectFailedException
- {
- if (repNode == null)
- {
- throw new IllegalArgumentException("Node cannot be null");
- }
- return new DbPing(repNode, (String)_configuration.getGroupName(), DB_PING_SOCKET_TIMEOUT).getNodeState();
- }
-
public int getNumberOfElectableGroupMembers()
{
if (_state.get() != State.OPEN)
@@ -1181,6 +1187,105 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
}
}
+ Set<String> getPermittedNodes()
+ {
+ return Collections.unmodifiableSet(_permittedNodes);
+ }
+
+ public static NodeState getRemoteNodeState(String groupName, ReplicationNode repNode) throws IOException, ServiceConnectFailedException
+ {
+ if (repNode == null)
+ {
+ throw new IllegalArgumentException("Node cannot be null");
+ }
+ return new DbPing(repNode, groupName, DB_PING_SOCKET_TIMEOUT).getNodeState();
+ }
+
+ public static Set<String> convertApplicationStateBytesToPermittedNodeList(byte[] applicationState)
+ {
+ if (applicationState == null || applicationState.length == 0)
+ {
+ return Collections.emptySet();
+ }
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ try
+ {
+ Map<String, Object> settings = objectMapper.readValue(applicationState, Map.class);
+ return new HashSet<String>((Collection<String>)settings.get(PERMITTED_NODE_LIST));
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Unexpected exception on de-serializing of application state", e);
+ }
+ }
+
+ public static void connectToHelperNodeAndCheckPermittedHosts(String nodeName, String hostPort, String groupName, String helperNodeName, String helperHostPort)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(String.format("Requesting state of the node '%s' at '%s'", helperNodeName, helperHostPort));
+ }
+
+ if (helperNodeName == null || "".equals(helperNodeName))
+ {
+ throw new IllegalConfigurationException(String.format("A helper node is not specified for node '%s'"
+ + " joining the group '%s'", nodeName, groupName));
+ }
+
+ Collection<String> permittedNodes = null;
+ try
+ {
+ ReplicationNodeImpl node = new ReplicationNodeImpl(helperNodeName, helperHostPort);
+ NodeState state = getRemoteNodeState(groupName, node);
+ byte[] applicationState = state.getAppState();
+ permittedNodes = convertApplicationStateBytesToPermittedNodeList(applicationState);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException(String.format("Cannot connect to '%s'", helperHostPort), e);
+ }
+ catch (ServiceConnectFailedException e)
+ {
+ throw new IllegalConfigurationException(String.format("Failure to connect to '%s'", helperHostPort), e);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(String.format("Unexpected exception on attempt to retrieve state from '%s' at '%s'",
+ helperNodeName, helperHostPort), e);
+ }
+
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(String.format("Attribute 'permittedNodes' on node '%s' is set to '%s'", helperNodeName, String.valueOf(permittedNodes)));
+ }
+
+ if (permittedNodes==null || !permittedNodes.contains(hostPort))
+ {
+ throw new IllegalConfigurationException(String.format("Node from '%s' is not permitted!", hostPort));
+ }
+ }
+
+ private void findMasterNodeStateAndApplyPermittedNodes(Collection<NodeState> nodeStates)
+ {
+ if (ReplicatedEnvironment.State.MASTER != _environment.getState())
+ {
+ for (NodeState nodeState : nodeStates)
+ {
+ if (nodeState.getNodeState() == ReplicatedEnvironment.State.MASTER)
+ {
+ byte[] applicationState = nodeState.getAppState();
+ Set<String> permittedNodes = convertApplicationStateBytesToPermittedNodeList(applicationState);
+ if (!_permittedNodes.equals(permittedNodes))
+ {
+ setPermittedNodes(permittedNodes);
+ }
+ break;
+ }
+ }
+ }
+ }
+
private void registerAppStateMonitorIfPermittedNodesSpecified()
{
if (!_permittedNodes.isEmpty())
@@ -1286,8 +1391,9 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
executeDatabasePingerOnNodeChangesIfMaster(nodeStates);
notifyGroupListenerAboutNodeStates(nodeStates);
- }
+ findMasterNodeStateAndApplyPermittedNodes(nodeStates.values());
+ }
}
finally
{
@@ -1384,7 +1490,7 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
NodeState nodeStateObject = null;
try
{
- nodeStateObject = getRemoteNodeState(node);
+ nodeStateObject = getRemoteNodeState((String)_configuration.getGroupName(), node);
}
catch (IOException | ServiceConnectFailedException e )
{
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHost.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHost.java
index 12511ad9e0..ac8d33685a 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHost.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHost.java
@@ -38,7 +38,7 @@ public interface BDBVirtualHost<X extends BDBVirtualHost<X>> extends VirtualHost
Math.min(200l*1024l*1024l,
Runtime.getRuntime().maxMemory()/20l));
- @ManagedAttribute(mandatory = true)
+ @ManagedAttribute(mandatory = true, defaultValue = "${qpid.work_dir}${file.separator}${this:name}${file.separator}messages")
String getStorePath();
@ManagedAttribute(mandatory = true, defaultValue = "0")
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
index cacb04736c..5489493f74 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
@@ -20,11 +20,9 @@
*/
package org.apache.qpid.server.virtualhostnode.berkeleydb;
-import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.PrivilegedAction;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -43,10 +41,8 @@ import com.sleepycat.je.rep.ReplicatedEnvironment;
import com.sleepycat.je.rep.ReplicationNode;
import com.sleepycat.je.rep.StateChangeEvent;
import com.sleepycat.je.rep.StateChangeListener;
-import com.sleepycat.je.rep.util.DbPing;
import com.sleepycat.je.rep.util.ReplicationGroupAdmin;
import com.sleepycat.je.rep.utilint.HostPortPair;
-import com.sleepycat.je.rep.utilint.ServiceDispatcher;
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
@@ -73,7 +69,6 @@ import org.apache.qpid.server.store.berkeleydb.replication.ReplicationGroupListe
import org.apache.qpid.server.util.ServerScopedRuntimeException;
import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl;
import org.apache.qpid.server.virtualhostnode.AbstractVirtualHostNode;
-import org.codehaus.jackson.map.ObjectMapper;
@ManagedObject( category = false, type = BDBHAVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE )
public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtualHostNodeImpl> implements
@@ -263,7 +258,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
{
try
{
- connectToHelperNodeAndCheckPermittedHosts(getHelperNodeName(), getHelperAddress(), getAddress());
+ ReplicatedEnvironmentFacade.connectToHelperNodeAndCheckPermittedHosts(getName(), getAddress(), getGroupName(), getHelperNodeName(), getHelperAddress());
}
catch(IllegalConfigurationException e)
{
@@ -706,71 +701,6 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
return getAddress().equals(getHelperAddress());
}
- private void connectToHelperNodeAndCheckPermittedHosts(String helperNodeName, String helperHostPort, String hostPort)
- {
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug(String.format("Requesting state of the node '%s' at '%s'", helperNodeName, helperHostPort));
- }
-
- if (_helperNodeName == null || "".equals(_helperNodeName))
- {
- throw new IllegalConfigurationException(String.format("An attribute '%s' is not set in node '%s'"
- + " on joining the group '%s'", HELPER_NODE_NAME, getName(), getGroupName()));
- }
-
- Collection<String> permittedNodes = null;
- try
- {
- ReplicatedEnvironmentFacade.ReplicationNodeImpl node = new ReplicatedEnvironmentFacade.ReplicationNodeImpl(helperNodeName, helperHostPort);
- NodeState state = new DbPing(node, getGroupName(), ReplicatedEnvironmentFacade.DB_PING_SOCKET_TIMEOUT).getNodeState();
- byte[] applicationState = state.getAppState();
- permittedNodes = bytesToPermittedNodeList(applicationState);
- }
- catch (IOException e)
- {
- throw new IllegalConfigurationException(String.format("Cannot connect to '%s'", helperHostPort), e);
- }
- catch (ServiceDispatcher.ServiceConnectFailedException e)
- {
- throw new IllegalConfigurationException(String.format("Failure to connect to '%s'", helperHostPort), e);
- }
- catch (Exception e)
- {
- throw new RuntimeException(String.format("Unexpected exception on attempt to retrieve state from '%s' at '%s'",
- helperNodeName, helperHostPort), e);
- }
-
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug(String.format("Attribute 'permittedNodes' on node '%s' is set to '%s'", helperNodeName, String.valueOf(permittedNodes)));
- }
-
- if (permittedNodes != null && !permittedNodes.isEmpty() && !permittedNodes.contains(hostPort))
- {
- throw new IllegalConfigurationException(String.format("Node from '%s' is not permitted!", hostPort));
- }
- }
-
- private Collection<String> bytesToPermittedNodeList(byte[] applicationState)
- {
- if (applicationState == null || applicationState.length == 0)
- {
- return Collections.emptySet();
- }
-
- ObjectMapper objectMapper = new ObjectMapper();
- try
- {
- Map<String, Object> settings = objectMapper.readValue(applicationState, Map.class);
- return (Collection<String>)settings.get(ReplicatedEnvironmentFacade.PERMITTED_NODE_LIST);
- }
- catch (Exception e)
- {
- throw new RuntimeException("Unexpected exception on de-serializing of application state", e);
- }
- }
-
private class RemoteNodesDiscoverer implements ReplicationGroupListener
{
@Override
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java
index 763b59146b..61b0d1882a 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java
@@ -26,6 +26,6 @@ public interface BDBVirtualHostNode<X extends BDBVirtualHostNode<X>> extends org
{
String STORE_PATH = "storePath";
- @ManagedAttribute(mandatory = true)
+ @ManagedAttribute(mandatory = true, defaultValue = "${qpid.work_dir}${file.separator}${this:name}${file.separator}config")
String getStorePath();
}
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
index f9e9d0a82f..9ce23084c5 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb/add.html
@@ -20,15 +20,13 @@
-->
<div>
<div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Store path*:</div>
+ <div class="formLabel-labelCell tableContainer-labelCell">Store path:</div>
<div class="formLabel-controlCell tableContainer-valueCell">
<input type="text" id="addVirtualHostNode.storePath"
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- required: true,
- missingMessage: 'Store path must be supplied',
title: 'Enter store path'" />
</div>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
index b08c734e35..820a94e754 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/existinggroup/add.html
@@ -81,15 +81,13 @@
</div>
</div>
<div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Store path*:</div>
+ <div class="formLabel-labelCell tableContainer-labelCell">Store path:</div>
<div class="formLabel-controlCell tableContainer-valueCell">
<input type="text" id="addVirtualHostNode.storePath"
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- required: true,
- missingMessage: 'Store path must be supplied',
title: 'Enter store path'" />
</div>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
index 3d06d15d5c..1d3b2a1906 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
@@ -45,15 +45,13 @@
</div>
</div>
<div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Store path*:</div>
+ <div class="formLabel-labelCell tableContainer-labelCell">Store path:</div>
<div class="formLabel-controlCell tableContainer-valueCell">
<input type="text" id="addVirtualHostNode.storePath"
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- required: true,
- missingMessage: 'Store path must be supplied',
title: 'Enter store path'" />
</div>
</div>
diff --git a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
index c18ca34fdb..189eb6f7b6 100644
--- a/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
+++ b/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
@@ -45,15 +45,13 @@
</div>
</div>
<div class="clear">
- <div class="formLabel-labelCell tableContainer-labelCell">Configuration store path*:</div>
+ <div class="formLabel-labelCell tableContainer-labelCell">Configuration store path:</div>
<div class="formLabel-controlCell tableContainer-valueCell">
<input type="text" id="editVirtualHostNode.storePath"
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="
name: 'storePath',
placeHolder: 'path/to/store',
- required: true,
- missingMessage: 'Store path must be supplied',
title: 'Enter configuration store path'" />
</div>
</div>
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java
index 44fc19e14f..5ed533f1e5 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java
@@ -656,7 +656,8 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase
permittedNodes.add("localhost:" + getNextAvailable(TEST_NODE_PORT + 1));
firstNode.setPermittedNodes(permittedNodes);
- NodeState nodeState = firstNode.getRemoteNodeState(new ReplicatedEnvironmentFacade.ReplicationNodeImpl(TEST_NODE_NAME, TEST_NODE_HOST_PORT));
+ ReplicatedEnvironmentFacade.ReplicationNodeImpl replicationNode = new ReplicatedEnvironmentFacade.ReplicationNodeImpl(TEST_NODE_NAME, TEST_NODE_HOST_PORT);
+ NodeState nodeState = ReplicatedEnvironmentFacade.getRemoteNodeState(TEST_GROUP_NAME, replicationNode);
ObjectMapper objectMapper = new ObjectMapper();
@@ -708,10 +709,52 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase
firstNode.setPermittedNodes(permittedNodes);
String nodeName = TEST_NODE_NAME + "_1";
+ createIntruder(nodeName, node1NodeHostPort);
+ assertTrue("Intruder node was not detected", intruderLatch.await(10, TimeUnit.SECONDS));
+ }
+
+ public void testIntruderNodeDetectionOnMasterAndReplicaNodes() throws Exception
+ {
+ final CountDownLatch intruderLatch = new CountDownLatch(2);
+ ReplicationGroupListener listener = new NoopReplicationGroupListener()
+ {
+ @Override
+ public void onIntruderNode(ReplicationNode node)
+ {
+ intruderLatch.countDown();
+ }
+ };
+
+ ReplicatedEnvironmentFacade firstNode = createMaster(listener);
+ int replica1Port = getNextAvailable(TEST_NODE_PORT + 1);
+ String node2NodeHostPort = "localhost:" + replica1Port;
+ String nodeName2 = TEST_NODE_NAME + "_1";
+ ReplicatedEnvironmentFacade secondNode = createReplica(nodeName2, node2NodeHostPort, listener);
+
+ Set<String> permittedNodes = new HashSet<String>();
+ permittedNodes.add("localhost:" + TEST_NODE_PORT);
+ permittedNodes.add(nodeName2);
+ firstNode.setPermittedNodes(permittedNodes);
+
+ int counter = 0;
+ while(secondNode.getPermittedNodes().isEmpty() && counter < 100)
+ {
+ counter++;
+ Thread.sleep(50);
+ }
+ assertEquals("Permitted nodes are not set on a replica", permittedNodes, secondNode.getPermittedNodes());
+
+ int intruderPort = getNextAvailable(replica1Port+ 1);
+ createIntruder("intruder", "localhost:" + intruderPort);
+ assertTrue("Intruder node was not detected", intruderLatch.await(10, TimeUnit.SECONDS));
+ }
+
+ private void createIntruder(String nodeName, String node1NodeHostPort)
+ {
File environmentPathFile = new File(_storePath, nodeName);
environmentPathFile.mkdirs();
- ReplicationConfig replicationConfig = new ReplicationConfig(TEST_GROUP_NAME, TEST_NODE_NAME + "_1", node1NodeHostPort);
+ ReplicationConfig replicationConfig = new ReplicationConfig(TEST_GROUP_NAME, nodeName, node1NodeHostPort);
replicationConfig.setHelperHosts(TEST_NODE_HOST_PORT);
EnvironmentConfig envConfig = new EnvironmentConfig();
@@ -730,7 +773,6 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase
intruder.close();
}
}
- assertTrue("Intruder node was not detected", intruderLatch.await(10, TimeUnit.SECONDS));
}
private ReplicatedEnvironmentFacade createMaster() throws Exception
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
index 45527313e6..ef1021160c 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
@@ -24,7 +24,6 @@ import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.*;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import org.apache.qpid.server.logging.EventLogger;
@@ -34,7 +33,6 @@ import org.apache.qpid.server.logging.messages.HighAvailabilityMessages;
import org.apache.qpid.server.model.SystemConfig;
import org.apache.qpid.test.utils.QpidTestCase;
import org.hamcrest.Description;
-import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
/**
@@ -360,22 +358,51 @@ public class BDBHAVirtualHostNodeOperationalLoggingTest extends QpidTestCase
reset(_eventLogger);
node2 = (BDBHAVirtualHostNodeImpl)_helper.recoverHaVHN(node2.getId(), node2Attributes);
- _helper.assertNodeRole(node2, "REPLICA");
-
+ _helper.assertNodeRole(node2, "REPLICA", "MASTER");
waitForNodeDetachedField(remoteNode, false);
- ArgumentCaptor<LogSubject> subjectArgument = ArgumentCaptor.forClass(LogSubject.class);
- ArgumentCaptor<LogMessage> messageArgument = ArgumentCaptor.forClass(LogMessage.class);
- verify(_eventLogger, times(2)).message(subjectArgument.capture(), messageArgument.capture());
-
- assertEquals("Unexpected subject", node1.getVirtualHostNodeLogSubject(), subjectArgument.getValue());
+ final String expectedMessage = HighAvailabilityMessages.ATTACHED(node2.getName(), groupName, "REPLICA").toString();
+ final String expectedMessage2 = HighAvailabilityMessages.ATTACHED(node2.getName(), groupName, "UNKNOWN").toString();
+ final String expectedMessage3 = HighAvailabilityMessages.ATTACHED(node2.getName(), groupName, "MASTER").toString();
+ ArgumentMatcher<LogMessage> matcher = new ArgumentMatcher<LogMessage>()
+ {
+ private String _messageErrorDescription = null;
+ private String _hierarchyErrorDescription = null;
- String expectedMessage = HighAvailabilityMessages.ATTACHED(node2.getName(), groupName, "REPLICA").toString();
- String expectedMessage2 = HighAvailabilityMessages.ATTACHED(node2.getName(), groupName, "UNKNOWN").toString();
+ @Override
+ public boolean matches(Object argument)
+ {
+ LogMessage logMessage = (LogMessage)argument;
+ String actualMessage = logMessage.toString();
+ boolean expectedMessageMatches = expectedMessage.equals(actualMessage)
+ || expectedMessage2.equals(actualMessage) || expectedMessage3.equals(actualMessage);
+ if (!expectedMessageMatches)
+ {
+ _messageErrorDescription = "Actual message does not match any expected: " + actualMessage;
+ }
+ boolean expectedHierarchyMatches = HighAvailabilityMessages.ATTACHED_LOG_HIERARCHY.equals(logMessage.getLogHierarchy());
+ if (!expectedHierarchyMatches)
+ {
+ _hierarchyErrorDescription = "Actual hierarchy does not match expected: " + logMessage.getLogHierarchy();
+ }
+ return expectedMessageMatches && expectedHierarchyMatches;
+ }
- List<LogMessage> capturedValues = messageArgument.getAllValues();
- String m = capturedValues.get(0).toString();
- assertTrue("Unexpected attached message :" + m, m.equals(expectedMessage) || m.equals(expectedMessage2));
+ @Override
+ public void describeTo(Description description)
+ {
+ if (_messageErrorDescription != null)
+ {
+ description.appendText(_messageErrorDescription);
+ }
+ if (_hierarchyErrorDescription != null)
+ {
+ description.appendText(_hierarchyErrorDescription);
+ }
+ }
+ };
+ verify(_eventLogger).message(argThat(new LogSubjectMatcher(node1.getVirtualHostNodeLogSubject())),
+ argThat(matcher));
}
private void waitForNodeDetachedField(BDBHARemoteReplicationNodeImpl remoteNode, boolean expectedDetached) throws InterruptedException {