summaryrefslogtreecommitdiff
path: root/qpid/java
diff options
context:
space:
mode:
authorAndrew MacBean <macbean@apache.org>2014-07-14 10:26:17 +0000
committerAndrew MacBean <macbean@apache.org>2014-07-14 10:26:17 +0000
commit422327a1b3effa916465ad033530b702de3c97e0 (patch)
treeda11e8d60a02793ef8d9400d23587d8553b63655 /qpid/java
parent60d0130f832efaf2935a9b6d485b6ff4b4ad1bd8 (diff)
downloadqpid-python-422327a1b3effa916465ad033530b702de3c97e0.tar.gz
QPID-5891: [Java Broker] Add BDB HA operational logging functionality
Work completed by Alex Rudyy <orudyy@apache.org> and me. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1610379 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java18
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java2
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java2
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java133
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java327
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/NoopConfigurationChangeListener.java53
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java5
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java309
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java264
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java502
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties35
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/VirtualHostNodeLogSubject.java33
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java9
14 files changed, 1385 insertions, 309 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 f8b9636c5d..332658692c 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
@@ -306,7 +306,18 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
@Override
public DatabaseException handleDatabaseException(String contextMessage, final DatabaseException dbe)
{
- boolean restart = (dbe instanceof InsufficientReplicasException || dbe instanceof InsufficientAcksException || dbe instanceof RestartRequiredException);
+ boolean noMajority = dbe instanceof InsufficientReplicasException || dbe instanceof InsufficientAcksException;
+
+ if (noMajority)
+ {
+ ReplicationGroupListener listener = _replicationGroupListener.get();
+ if (listener != null)
+ {
+ listener.onNoMajority();
+ }
+ }
+
+ boolean restart = (noMajority || dbe instanceof RestartRequiredException);
if (restart)
{
tryToRestartEnvironment(dbe);
@@ -951,7 +962,6 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
{
connectToHelperNodeAndCheckPermittedHosts(helperNodeName, helperHostPort, hostPort);
}
-
Map<String, String> replicationEnvironmentParameters = new HashMap<>(ReplicatedEnvironmentFacade.REPCONFIG_DEFAULTS);
replicationEnvironmentParameters.putAll(_configuration.getReplicationParameters());
@@ -1107,10 +1117,6 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
}
_realMessageStoreDurability = new Durability(localTransactionSynchronizationPolicy, remoteTransactionSynchronizationPolicy, replicaAcknowledgmentPolicy);
}
- else
- {
- throw new IllegalStateException("Message store durability is already set to " + _messageStoreDurability.get());
- }
}
public void setPermittedNodes(Collection<String> permittedNodes)
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java
index 7f9f0fcf64..7367f5cda7 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java
@@ -53,4 +53,6 @@ public interface ReplicationGroupListener
*/
void onIntruderNode(ReplicationNode node);
+ void onNoMajority();
+
}
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java
index ad12dc2447..b76e4d8d5c 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java
@@ -56,7 +56,7 @@ public interface BDBHAVirtualHostNode<X extends BDBHAVirtualHostNode<X>> extends
@ManagedAttribute(defaultValue = "0")
int getQuorumOverride();
- @ManagedAttribute(persist = false)
+ @ManagedAttribute(persist = false, defaultValue = "UNKNOWN")
String getRole();
@DerivedAttribute
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 0bbbff0f98..6f64c0bade 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
@@ -47,6 +47,7 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.updater.Task;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
+import org.apache.qpid.server.logging.messages.HighAvailabilityMessages;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.BrokerModel;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -247,6 +248,13 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
return (BDBConfigurationStore) super.getConfigurationStore();
}
+ @Override
+ public void onCreate()
+ {
+ super.onCreate();
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ADDED(getName(), getGroupName()));
+ }
+
protected ReplicatedEnvironmentFacade getReplicatedEnvironmentFacade()
{
return _environmentFacade.get();
@@ -268,6 +276,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
getConfigurationStore().openConfigurationStore(this);
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ATTACHED(getName(), getGroupName(), getRole()));
+
getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.CREATED());
getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.STORE_LOCATION(getStorePath()));
@@ -279,7 +289,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
if (_environmentFacade.compareAndSet(null, environmentFacade))
{
- environmentFacade.setStateChangeListener(new BDBHAMessageStoreStateChangeListener());
+ environmentFacade.setStateChangeListener(new EnvironmentStateChangeListener());
environmentFacade.setReplicationGroupListener(new RemoteNodesDiscoverer());
}
}
@@ -294,13 +304,30 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
finally
{
stopEnvironment();
+
+ //Perhaps, having STOPPED operational logging could be sufficient. However, on START we still will be seeing 2 logs: ATTACHED and STARTED
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DETACHED(getName(), getGroupName()));
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.STOPPED(getName(), getGroupName()));
+ }
+ }
+
+ @StateTransition( currentState = { State.UNINITIALIZED, State.STOPPED, State.ERRORED }, desiredState = State.ACTIVE )
+ protected void doActivate()
+ {
+ try
+ {
+ super.doActivate();
+ }
+ finally
+ {
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.STARTED(getName(), getGroupName()));
}
}
private void stopEnvironment()
{
ReplicatedEnvironmentFacade environmentFacade = getReplicatedEnvironmentFacade();
- if (_environmentFacade.compareAndSet(environmentFacade, null))
+ if (environmentFacade != null && _environmentFacade.compareAndSet(environmentFacade, null))
{
environmentFacade.close();
}
@@ -311,6 +338,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
{
Set<InetSocketAddress> helpers = getRemoteNodeAddresses();
super.doDelete();
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DELETED(getName(), getGroupName()));
if (getState() == State.DELETED && !helpers.isEmpty())
{
try
@@ -362,11 +390,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
}
finally
{
- ReplicatedEnvironmentFacade environmentFacade = getReplicatedEnvironmentFacade();
- if (environmentFacade != null && _environmentFacade.compareAndSet(environmentFacade, null))
- {
- environmentFacade.close();
- }
+ stopEnvironment();
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DETACHED(getName(), getGroupName()));
}
}
@@ -463,7 +488,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
}
}
- private class BDBHAMessageStoreStateChangeListener implements StateChangeListener
+ private class EnvironmentStateChangeListener implements StateChangeListener
{
@Override
public void stateChange(StateChangeEvent stateChangeEvent) throws RuntimeException
@@ -475,25 +500,33 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
LOGGER.info("Received BDB event indicating transition to state " + state);
}
- switch (state)
- {
- case MASTER:
- onMaster();
- break;
- case REPLICA:
- onReplica();
- break;
- case DETACHED:
- onDetached();
- break;
- case UNKNOWN:
- break;
- default:
- LOGGER.error("Unexpected state change: " + state);
- throw new IllegalStateException("Unexpected state change: " + state);
+ try
+ {
+ switch (state)
+ {
+ case MASTER:
+ onMaster();
+ break;
+ case REPLICA:
+ onReplica();
+ break;
+ case DETACHED:
+ onDetached();
+ break;
+ case UNKNOWN:
+ break;
+ default:
+ LOGGER.error("Unexpected state change: " + state);
+ }
+ }
+ finally
+ {
+ _lastReplicatedEnvironmentState.set(state);
+ String previousRole = _role;
+ attributeSet(ROLE, _role, state.name());
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ROLE_CHANGED(getName(),
+ getGroupName(), previousRole, state.name()));
}
- _lastReplicatedEnvironmentState.set(state);
- attributeSet(ROLE, _role, state.name());
}
}
@@ -507,10 +540,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
try
{
environmentFacade.setPriority(_priority).get(MUTATE_JE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Node priority changed. " + this);
- }
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.PRIORITY_CHANGED(getName(),
+ getGroupName(), String.valueOf(_priority)));
}
catch (TimeoutException e)
{
@@ -537,10 +568,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
try
{
environmentFacade.setDesignatedPrimary(_designatedPrimary).get(MUTATE_JE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Designated primary changed. " + this);
- }
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DESIGNATED_PRIMARY_CHANGED(getName(),
+ getGroupName(), String.valueOf(_designatedPrimary)));
}
catch (TimeoutException e)
{
@@ -567,10 +596,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
try
{
environmentFacade.setElectableGroupSizeOverride(_quorumOverride).get(MUTATE_JE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Quorum override changed. " + this);
- }
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.QUORUM_OVERRIDE_CHANGED(getName(),
+ getGroupName(), String.valueOf(_quorumOverride)));
}
catch (TimeoutException e)
{
@@ -597,10 +624,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
try
{
environmentFacade.transferMasterToSelfAsynchronously().get(MUTATE_JE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- if (LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Requested master transfer to self. " + this);
- }
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.TRANSFER_MASTER(getName(), getName(), getGroupName()));
}
catch (TimeoutException e)
{
@@ -642,6 +666,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
BDBHARemoteReplicationNodeImpl remoteNode = new BDBHARemoteReplicationNodeImpl(BDBHAVirtualHostNodeImpl.this, nodeToAttributes(node), getReplicatedEnvironmentFacade());
remoteNode.create();
childAdded(remoteNode);
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ADDED(remoteNode.getName(), getGroupName()));
}
@Override
@@ -662,6 +687,8 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
{
BDBHARemoteReplicationNodeImpl remoteNode = new BDBHARemoteReplicationNodeImpl(BDBHAVirtualHostNodeImpl.this, nodeToAttributes(node), getReplicatedEnvironmentFacade());
remoteNode.open();
+
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ATTACHED(remoteNode.getName(), getGroupName(), String.valueOf(remoteNode.getState())));
}
@Override
@@ -684,6 +711,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
if (remoteNode != null)
{
remoteNode.deleted();
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DELETED(remoteNode.getName(), getGroupName()));
}
}
@@ -693,6 +721,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
BDBHARemoteReplicationNodeImpl remoteNode = getChildByName(BDBHARemoteReplicationNodeImpl.class, node.getName());
if (remoteNode != null)
{
+ String currentRole = remoteNode.getRole();
if (nodeState == null)
{
remoteNode.setRole(ReplicatedEnvironment.State.UNKNOWN.name());
@@ -703,17 +732,25 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
remoteNode.setLastTransactionId(nodeState.getCurrentTxnEndVLSN());
remoteNode.setRole(nodeState.getNodeState().name());
}
+
+ String newRole = remoteNode.getRole();
+ if (!newRole.equals(currentRole))
+ {
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.ROLE_CHANGED(remoteNode.getName(),
+ getGroupName(), currentRole, newRole));
+ }
}
}
@Override
public void onIntruderNode(ReplicationNode node)
{
+ String hostAndPort = node.getHostName() + ":" + node.getPort();
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.INTRUDER_DETECTED(node.getName(), hostAndPort, getGroupName()));
+
boolean inManagementMode = getParent(Broker.class).isManagementMode();
if (inManagementMode)
{
- LOGGER.warn(String.format("Intruder replication node '%s' from '%s' is detected. Ignoring intruder in management mode",
- node.getName(), node.getHostName() + ":" + node.getPort() ));
BDBHARemoteReplicationNodeImpl remoteNode = getChildByName(BDBHARemoteReplicationNodeImpl.class, node.getName());
if (remoteNode == null)
{
@@ -723,7 +760,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
else
{
LOGGER.error(String.format("Intruder node '%s' from '%s' is detected. Stopping down virtual host node '%s'",
- node.getName(), node.getHostName() + ":" + node.getPort(), BDBHAVirtualHostNodeImpl.this.toString() ));
+ node.getName(), hostAndPort, BDBHAVirtualHostNodeImpl.this.toString() ));
getTaskExecutor().submit(new Task<Void>()
{
@@ -750,6 +787,12 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu
}
}
+ @Override
+ public void onNoMajority()
+ {
+ getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.MAJORITY_LOST(getName(), getGroupName()));
+ }
+
private Map<String, Object> nodeToAttributes(ReplicationNode replicationNode)
{
Map<String, Object> attributes = new HashMap<String, Object>();
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
index d830d488db..0d631ae52b 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
@@ -24,14 +24,10 @@ import static org.mockito.Mockito.when;
import java.io.File;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -41,54 +37,30 @@ import com.sleepycat.je.rep.ReplicatedEnvironment;
import com.sleepycat.je.rep.ReplicationConfig;
import org.apache.qpid.server.configuration.IllegalConfigurationException;
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
-import org.apache.qpid.server.configuration.updater.TaskExecutorImpl;
-import org.apache.qpid.server.logging.LogMessage;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.logging.MessageLogger;
-import org.apache.qpid.server.logging.messages.VirtualHostMessages;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.BrokerModel;
import org.apache.qpid.server.model.ConfigurationChangeListener;
import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.ConfiguredObjectFactory;
import org.apache.qpid.server.model.RemoteReplicationNode;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.model.VirtualHostNode;
import org.apache.qpid.server.store.DurableConfigurationStore;
-import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHost;
import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl;
import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNode;
import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNodeImpl;
import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode;
+import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeTestHelper;
import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeImpl;
import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.util.FileUtils;
public class BDBHAVirtualHostNodeTest extends QpidTestCase
{
-
- private Broker<?> _broker;
- private File _bdbStorePath;
- private TaskExecutor _taskExecutor;
- private final ConfiguredObjectFactory _objectFactory = BrokerModel.getInstance().getObjectFactory();
- private final Set<BDBHAVirtualHostNode<?>> _nodes = new HashSet<>();
-
+ private BDBHAVirtualHostNodeTestHelper _helper;
@Override
protected void setUp() throws Exception
{
super.setUp();
- _broker = BrokerTestHelper.createBrokerMock();
-
- _taskExecutor = new TaskExecutorImpl();
- _taskExecutor.start();
- when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
-
- _bdbStorePath = new File(TMP_FOLDER, getTestName() + "." + System.currentTimeMillis());
- _bdbStorePath.deleteOnExit();
+ _helper = new BDBHAVirtualHostNodeTestHelper(getTestName());
}
@Override
@@ -96,42 +68,17 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
{
try
{
- Exception firstException = null;
- for (VirtualHostNode<?> node : _nodes)
- {
- try
- {
- node.delete();
- }
- catch(Exception e)
- {
- if (firstException != null)
- {
- firstException = e;
- }
- }
- if (firstException != null)
- {
- throw firstException;
- }
- }
+ _helper.tearDown();
}
finally
{
- if (_taskExecutor != null)
- {
- _taskExecutor.stopImmediately();
- }
- if (_bdbStorePath != null)
- {
- FileUtils.delete(_bdbStorePath, true);
- }
super.tearDown();
}
}
public void testCreateAndActivateVirtualHostNode() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
String repStreamTimeout = "2 h";
String nodeName = "node";
String groupName = "group";
@@ -146,11 +93,11 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
attributes.put(BDBHAVirtualHostNode.ADDRESS, nodeHostPort);
attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperHostPort);
- attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath);
+ attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath);
attributes.put(BDBHAVirtualHostNode.CONTEXT,
Collections.singletonMap(ReplicationConfig.REP_STREAM_TIMEOUT, repStreamTimeout));
- BDBHAVirtualHostNode<?> node = createHaVHN(attributes);
+ BDBHAVirtualHostNode<?> node = _helper.createHaVHN(attributes);
final CountDownLatch virtualHostAddedLatch = new CountDownLatch(1);
node.addChangeListener(new NoopConfigurationChangeListener()
@@ -167,7 +114,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
});
node.start();
- assertNodeRole(node, "MASTER", "REPLICA");
+ _helper.assertNodeRole(node, "MASTER", "REPLICA");
assertEquals("Unexpected node state", State.ACTIVE, node.getState());
DurableConfigurationStore store = node.getConfigurationStore();
@@ -201,7 +148,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node.delete();
assertEquals("Unexpected state returned after delete", State.DELETED, node.getState());
assertEquals("Unexpected state", State.DELETED, node.getState());
- assertFalse("Store still exists " + _bdbStorePath, _bdbStorePath.exists());
+ assertFalse("Store still exists " + messageStorePath, new File(messageStorePath).exists());
}
public void testMutableAttributes() throws Exception
@@ -216,9 +163,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
attributes.put(BDBHAVirtualHostNode.GROUP_NAME, "group");
attributes.put(BDBHAVirtualHostNode.ADDRESS, address);
attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, address);
- attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath);
+ attributes.put(BDBHAVirtualHostNode.STORE_PATH, _helper.getMessageStorePath());
- BDBHAVirtualHostNode<?> node = createAndStartHaVHN(attributes);
+ BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(attributes);
BDBConfigurationStore bdbConfigurationStore = (BDBConfigurationStore) node.getConfigurationStore();
ReplicatedEnvironment environment = (ReplicatedEnvironment) bdbConfigurationStore.getEnvironmentFacade().getEnvironment();
@@ -241,6 +188,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
public void testTransferMasterToSelf() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
@@ -252,8 +200,8 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
- createAndStartHaVHN(node1Attributes);
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
+ _helper.createAndStartHaVHN(node1Attributes);
int node2PortNumber = getNextAvailable(node1PortNumber+1);
@@ -264,8 +212,8 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
- createAndStartHaVHN(node2Attributes);
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
+ _helper.createAndStartHaVHN(node2Attributes);
int node3PortNumber = getNextAvailable(node2PortNumber+1);
Map<String, Object> node3Attributes = new HashMap<String, Object>();
@@ -275,14 +223,14 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node3Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber);
node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3");
- createAndStartHaVHN(node3Attributes);
+ node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "3");
+ _helper.createAndStartHaVHN(node3Attributes);
- BDBHAVirtualHostNode<?> replica = awaitAndFindNodeInRole("REPLICA");
+ BDBHAVirtualHostNode<?> replica = _helper.awaitAndFindNodeInRole("REPLICA");
replica.setAttribute(BDBHAVirtualHostNode.ROLE, "REPLICA", "MASTER");
- assertNodeRole(replica, "MASTER");
+ _helper.assertNodeRole(replica, "MASTER");
}
public void testTransferMasterToRemoteReplica() throws Exception
@@ -290,6 +238,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
+ String messageStorePath = _helper.getMessageStorePath();
Map<String, Object> node1Attributes = new HashMap<String, Object>();
node1Attributes.put(BDBHAVirtualHostNode.ID, UUID.randomUUID());
@@ -298,9 +247,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node1 = createAndStartHaVHN(node1Attributes);
+ BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes);
final AtomicReference<RemoteReplicationNode<?>> lastSeenReplica = new AtomicReference<>();
final CountDownLatch remoteNodeLatch = new CountDownLatch(2);
@@ -326,9 +275,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
- BDBHAVirtualHostNode<?> node2 = createAndStartHaVHN(node2Attributes);
+ BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes);
int node3PortNumber = getNextAvailable(node2PortNumber+1);
Map<String, Object> node3Attributes = new HashMap<String, Object>();
@@ -338,18 +287,18 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node3Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber);
node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3");
- BDBHAVirtualHostNode<?> node3 = createAndStartHaVHN(node3Attributes);
+ node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "3");
+ BDBHAVirtualHostNode<?> node3 = _helper.createAndStartHaVHN(node3Attributes);
assertTrue("Replication nodes have not been seen during 5s", remoteNodeLatch.await(5, TimeUnit.SECONDS));
BDBHARemoteReplicationNodeImpl replicaRemoteNode = (BDBHARemoteReplicationNodeImpl)lastSeenReplica.get();
- awaitForAttributeChange(replicaRemoteNode, BDBHARemoteReplicationNodeImpl.ROLE, "REPLICA");
+ _helper.awaitForAttributeChange(replicaRemoteNode, BDBHARemoteReplicationNodeImpl.ROLE, "REPLICA");
replicaRemoteNode.setAttributes(Collections.<String,Object>singletonMap(BDBHARemoteReplicationNode.ROLE, "MASTER"));
BDBHAVirtualHostNode<?> replica = replicaRemoteNode.getName().equals(node2.getName())? node2 : node3;
- assertNodeRole(replica, "MASTER");
+ _helper.assertNodeRole(replica, "MASTER");
}
public void testMutatingRoleWhenNotReplica_IsDisallowed() throws Exception
@@ -357,6 +306,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
int nodePortNumber = findFreePort();
String helperAddress = "localhost:" + nodePortNumber;
String groupName = "group";
+ String messageStorePath = _helper.getMessageStorePath();
Map<String, Object> node1Attributes = new HashMap<String, Object>();
node1Attributes.put(BDBHAVirtualHostNode.ID, UUID.randomUUID());
@@ -365,10 +315,10 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node = createAndStartHaVHN(node1Attributes);
- assertNodeRole(node, "MASTER");
+ BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(node1Attributes);
+ _helper.assertNodeRole(node, "MASTER");
try
{
@@ -384,6 +334,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
public void testRemoveReplicaNode() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
@@ -395,8 +346,8 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
- createAndStartHaVHN(node1Attributes);
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
+ _helper.createAndStartHaVHN(node1Attributes);
int node2PortNumber = getNextAvailable(node1PortNumber+1);
@@ -407,8 +358,8 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
- createAndStartHaVHN(node2Attributes);
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
+ _helper.createAndStartHaVHN(node2Attributes);
int node3PortNumber = getNextAvailable(node2PortNumber+1);
Map<String, Object> node3Attributes = new HashMap<String, Object>();
@@ -418,20 +369,20 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node3Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber);
node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3");
- createAndStartHaVHN(node3Attributes);
+ node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "3");
+ _helper.createAndStartHaVHN(node3Attributes);
- BDBHAVirtualHostNode<?> master = awaitAndFindNodeInRole("MASTER");
- awaitRemoteNodes(master, 2);
+ BDBHAVirtualHostNode<?> master = _helper.awaitAndFindNodeInRole("MASTER");
+ _helper.awaitRemoteNodes(master, 2);
- BDBHAVirtualHostNode<?> replica = awaitAndFindNodeInRole("REPLICA");
+ BDBHAVirtualHostNode<?> replica = _helper.awaitAndFindNodeInRole("REPLICA");
- assertNotNull("Remote node " + replica.getName() + " is not found", findRemoteNode( master, replica.getName()));
+ assertNotNull("Remote node " + replica.getName() + " is not found", _helper.findRemoteNode(master, replica.getName()));
replica.delete();
- awaitRemoteNodes(master, 1);
+ _helper.awaitRemoteNodes(master, 1);
- assertNull("Remote node " + replica.getName() + " is not found", findRemoteNode( master, replica.getName()));
+ assertNull("Remote node " + replica.getName() + " is not found", _helper.findRemoteNode(master, replica.getName()));
}
@@ -448,8 +399,8 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
nodeAttributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
nodeAttributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
nodeAttributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- nodeAttributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node = createHaVHN(nodeAttributes);
+ nodeAttributes.put(BDBHAVirtualHostNode.STORE_PATH, _helper.getMessageStorePath() + File.separator + "1");
+ BDBHAVirtualHostNode<?> node = _helper.createHaVHN(nodeAttributes);
final CountDownLatch virtualHostAddedLatch = new CountDownLatch(1);
node.addChangeListener(new NoopConfigurationChangeListener()
@@ -466,14 +417,14 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
});
node.start();
- assertNodeRole(node, "MASTER", "REPLICA");
+ _helper.assertNodeRole(node, "MASTER", "REPLICA");
assertEquals("Unexpected node state", State.ACTIVE, node.getState());
assertTrue("Virtual host child has not been added", virtualHostAddedLatch.await(30, TimeUnit.SECONDS));
BDBHAVirtualHostImpl virtualHost = (BDBHAVirtualHostImpl)node.getVirtualHost();
assertNotNull("Virtual host is not created", virtualHost);
- awaitForAttributeChange(virtualHost, BDBHAVirtualHostImpl.COALESCING_SYNC, true);
+ _helper.awaitForAttributeChange(virtualHost, BDBHAVirtualHostImpl.COALESCING_SYNC, true);
assertEquals("Unexpected local transaction synchronization policy", "SYNC", virtualHost.getLocalTransactionSynchronizationPolicy());
assertEquals("Unexpected remote transaction synchronization policy", "NO_SYNC", virtualHost.getRemoteTransactionSynchronizationPolicy());
@@ -514,6 +465,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
public void testIntruderProtection() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
@@ -525,9 +477,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node1 = createAndStartHaVHN(node1Attributes);
+ BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes);
BDBHAVirtualHost<?> host = (BDBHAVirtualHost<?>)node1.getVirtualHost();
List<String> permittedNodes = new ArrayList<String>();
@@ -543,11 +495,11 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
node2Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, "node1");
node2Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
- BDBHAVirtualHostNode<?> node2 = createAndStartHaVHN(node2Attributes);
+ BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes);
int node3PortNumber = getNextAvailable(node2PortNumber+1);
Map<String, Object> node3Attributes = new HashMap<String, Object>();
@@ -557,13 +509,13 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node3Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber);
node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3");
+ node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "3");
node3Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, "node1");
node3Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
try
{
- createHaVHN(node3Attributes);
+ _helper.createHaVHN(node3Attributes);
fail("The VHN should not be permitted to join the group");
}
catch(IllegalConfigurationException e)
@@ -588,13 +540,14 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
};
node1.addChangeListener(listener);
- createHaVHN(node3Attributes);
+ _helper.createHaVHN(node3Attributes);
assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS));
}
public void testIntruderProtectionInManagementMode() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
@@ -606,9 +559,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node1 = createAndStartHaVHN(node1Attributes);
+ BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes);
int node2PortNumber = getNextAvailable(node1PortNumber+1);
Map<String, Object> node2Attributes = new HashMap<String, Object>();
@@ -618,11 +571,11 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
node2Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, "node1");
node2Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0);
- BDBHAVirtualHostNode<?> node2 = createAndStartHaVHN(node2Attributes);
+ BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes);
final CountDownLatch stopLatch = new CountDownLatch(1);
ConfigurationChangeListener listener = new NoopConfigurationChangeListener()
@@ -646,17 +599,18 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS));
- when(_broker.isManagementMode()).thenReturn(true);
+ when(_helper.getBroker().isManagementMode()).thenReturn(true);
node1.start();
- awaitRemoteNodes(node1, 1);
+ _helper.awaitRemoteNodes(node1, 1);
- BDBHARemoteReplicationNode<?> remote = findRemoteNode(node1, node2.getName());
+ BDBHARemoteReplicationNode<?> remote = _helper.findRemoteNode(node1, node2.getName());
remote.delete();
}
public void testIntruderConnectedBeforePermittedNodesAreSet() throws Exception
{
+ String messageStorePath = _helper.getMessageStorePath();
int node1PortNumber = findFreePort();
String helperAddress = "localhost:" + node1PortNumber;
String groupName = "group";
@@ -668,9 +622,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress);
node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1");
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "1");
- BDBHAVirtualHostNode<?> node1 = createAndStartHaVHN(node1Attributes);
+ BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes);
int node2PortNumber = getNextAvailable(node1PortNumber+1);
Map<String, Object> node2Attributes = new HashMap<String, Object>();
@@ -680,10 +634,10 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
node2Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber);
node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
- node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2");
+ node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, messageStorePath + File.separator + "2");
node2Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, "node1");
- createAndStartHaVHN(node2Attributes);
+ _helper.createAndStartHaVHN(node2Attributes);
final CountDownLatch stopLatch = new CountDownLatch(1);
ConfigurationChangeListener listener = new NoopConfigurationChangeListener()
@@ -707,145 +661,6 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase
assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(20, TimeUnit.SECONDS));
}
- private BDBHARemoteReplicationNode<?> findRemoteNode(BDBHAVirtualHostNode<?> node, String name)
- {
- for (RemoteReplicationNode<?> remoteNode : node.getRemoteReplicationNodes())
- {
- if (remoteNode.getName().equals(name))
- {
- return (BDBHARemoteReplicationNode<?>)remoteNode;
- }
- }
- return null;
- }
-
- private void awaitRemoteNodes(BDBHAVirtualHostNode<?> node, int expectedNodeNumber) throws InterruptedException
- {
- int counter = 0;
-
- @SuppressWarnings("rawtypes")
- Collection<? extends RemoteReplicationNode> remoteNodes = null;
- do
- {
- remoteNodes = node.getRemoteReplicationNodes();
- if (counter > 0)
- {
- Thread.sleep(100);
- }
- counter++;
- }
- while(remoteNodes.size() != expectedNodeNumber && counter<100);
- assertEquals("Unexpected node number", expectedNodeNumber, node.getRemoteReplicationNodes().size());
- }
-
- private void awaitForAttributeChange(ConfiguredObject<?> object, String name, Object expectedValue) throws InterruptedException
- {
- int awaitCounter = 0;
- while(!object.equals(object.getAttribute(name)) && awaitCounter < 50)
- {
- Thread.sleep(100);
- awaitCounter++;
- }
- assertEquals("Unexpected attribute " + name + " on " + object, expectedValue, object.getAttribute(name) );
- }
-
- private BDBHAVirtualHostNode<?> awaitAndFindNodeInRole(String role) throws InterruptedException
- {
- BDBHAVirtualHostNode<?> replica = null;
- int findReplicaCount = 0;
- while(replica == null)
- {
- replica = findNodeInRole(role);
- if (replica == null)
- {
- Thread.sleep(100);
- }
- if (findReplicaCount > 50)
- {
- fail("Could not find a node in replica role");
- }
- findReplicaCount++;
- }
- return replica;
- }
-
- private BDBHAVirtualHostNode<?> findNodeInRole(String role)
- {
- for (BDBHAVirtualHostNode<?> node : _nodes)
- {
- if (role.equals(node.getRole()))
- {
- return node;
- }
- }
- return null;
- }
-
- private BDBHAVirtualHostNode<?> createHaVHN(Map<String, Object> attributes)
- {
- @SuppressWarnings("unchecked")
- BDBHAVirtualHostNode<?> node = (BDBHAVirtualHostNode<?>) _objectFactory.create(VirtualHostNode.class, attributes, _broker);
- _nodes.add(node);
- return node;
- }
-
- private void assertNodeRole(BDBHAVirtualHostNode<?> node, String... roleName) throws InterruptedException
- {
- int iterationCounter = 0;
- boolean inRole =false;
- do
- {
- for (String role : roleName)
- {
- if (role.equals(node.getRole()))
- {
- inRole = true;
- break;
- }
- }
- if (!inRole)
- {
- Thread.sleep(100);
- }
- iterationCounter++;
- }
- while(!inRole && iterationCounter<50);
- assertTrue("Node " + node.getName() + " did not transit into role " + Arrays.toString(roleName), inRole);
- }
-
- private BDBHAVirtualHostNode<?> createAndStartHaVHN(Map<String, Object> attributes) throws InterruptedException
- {
- BDBHAVirtualHostNode<?> node = createHaVHN(attributes);
- node.start();
- assertNodeRole(node, "MASTER", "REPLICA");
- assertEquals("Unexpected node state", State.ACTIVE, node.getState());
- return node;
- }
-
- class NoopConfigurationChangeListener implements ConfigurationChangeListener
- {
-
- @Override
- public void stateChanged(ConfiguredObject<?> object, State oldState, State newState)
- {
- }
-
- @Override
- public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child)
- {
- }
-
- @Override
- public void childRemoved(ConfiguredObject<?> object, ConfiguredObject<?> child)
- {
- }
-
- @Override
- public void attributeSet(ConfiguredObject<?> object, String attributeName, Object oldAttributeValue,
- Object newAttributeValue)
- {
- }
- }
}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/NoopConfigurationChangeListener.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/NoopConfigurationChangeListener.java
new file mode 100644
index 0000000000..b185a31c3b
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/NoopConfigurationChangeListener.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.store.berkeleydb;
+
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+
+public class NoopConfigurationChangeListener implements ConfigurationChangeListener
+{
+
+ public NoopConfigurationChangeListener() {
+ }
+
+ @Override
+ public void stateChanged(ConfiguredObject<?> object, State oldState, State newState)
+ {
+ }
+
+ @Override
+ public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child)
+ {
+ }
+
+ @Override
+ public void childRemoved(ConfiguredObject<?> object, ConfiguredObject<?> child)
+ {
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject<?> object, String attributeName, Object oldAttributeValue,
+ Object newAttributeValue)
+ {
+ }
+}
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 6c03e59d72..355ebcb981 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
@@ -862,5 +862,10 @@ public class ReplicatedEnvironmentFacadeTest extends QpidTestCase
LOGGER.warn("Intruder node " + node);
}
+ @Override
+ public void onNoMajority()
+ {
+ }
+
}
}
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
new file mode 100644
index 0000000000..4d2c07901c
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
@@ -0,0 +1,309 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.virtualhostnode.berkeleydb;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.qpid.server.logging.EventLogger;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.logging.messages.HighAvailabilityMessages;
+import org.apache.qpid.server.model.SystemContext;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.mockito.ArgumentMatcher;
+
+/**
+ * Class to test that specific VHN operations result in the expected Operational Log message(s) being performed.
+ */
+public class BDBHAVirtualHostNodeOperationalLoggingTest extends QpidTestCase
+{
+ private BDBHAVirtualHostNodeTestHelper _helper;
+ private EventLogger _eventLogger;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _helper = new BDBHAVirtualHostNodeTestHelper(getTestName());
+ _eventLogger = mock(EventLogger.class);
+ SystemContext<?> context = (SystemContext<?>) _helper.getBroker().getParent(SystemContext.class);
+ when(context.getEventLogger()).thenReturn(_eventLogger);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ _helper.tearDown();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testCreate() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+
+ _helper.assertNodeRole(node1, "MASTER");
+
+ String expectedMessage = HighAvailabilityMessages.ADDED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.ADDED_LOG_HIERARCHY)));
+
+ expectedMessage = HighAvailabilityMessages.ATTACHED(node1.getName(), node1.getGroupName(), "UNKNOWN").toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.ATTACHED_LOG_HIERARCHY)));
+
+
+ expectedMessage = HighAvailabilityMessages.STARTED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.STARTED_LOG_HIERARCHY)));
+
+ expectedMessage = HighAvailabilityMessages.ROLE_CHANGED(node1.getName(), node1.getGroupName(), "UNKNOWN", "MASTER").toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.ROLE_CHANGED_LOG_HIERARCHY)));
+ }
+
+ public void testStop() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+ reset(_eventLogger);
+
+ node1.stop();
+
+ String expectedMessage = HighAvailabilityMessages.DETACHED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DETACHED_LOG_HIERARCHY)));
+
+ expectedMessage = HighAvailabilityMessages.STOPPED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.STOPPED_LOG_HIERARCHY)));
+ }
+
+ public void testClose() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ node1.close();
+
+ String expectedMessage = HighAvailabilityMessages.DETACHED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DETACHED_LOG_HIERARCHY)));
+ }
+
+ public void testDelete() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ node1.delete();
+
+ String expectedMessage = HighAvailabilityMessages.DETACHED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DETACHED_LOG_HIERARCHY)));
+
+ expectedMessage = HighAvailabilityMessages.DELETED(node1.getName(), node1.getGroupName()).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DELETED_LOG_HIERARCHY)));
+ }
+
+ public void testSetPriority() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PRIORITY, 10));
+
+ String expectedMessage = HighAvailabilityMessages.PRIORITY_CHANGED(node1.getName(), node1.getGroupName(), "10").toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.PRIORITY_CHANGED_LOG_HIERARCHY)));
+ }
+
+ public void testSetQuorumOverride() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.QUORUM_OVERRIDE, 1));
+
+ String expectedMessage = HighAvailabilityMessages.QUORUM_OVERRIDE_CHANGED(node1.getName(), node1.getGroupName(), "1").toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.QUORUM_OVERRIDE_CHANGED_LOG_HIERARCHY)));
+ }
+
+ public void testSetDesignatedPrimary() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.DESIGNATED_PRIMARY, true));
+
+ String expectedMessage = HighAvailabilityMessages.DESIGNATED_PRIMARY_CHANGED(node1.getName(), node1.getGroupName(), "true").toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DESIGNATED_PRIMARY_CHANGED_LOG_HIERARCHY)));
+ }
+
+ public void testRemoteNodeAdded() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ reset(_eventLogger);
+
+ resetEventLogger();
+
+ int node2PortNumber = getNextAvailable(node1PortNumber + 1);
+ Map<String, Object> node2Attributes = _helper.createNodeAttributes("node2", groupName, "localhost:" + node2PortNumber, helperAddress);
+ BDBHAVirtualHostNodeImpl node2 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node2Attributes);
+ _helper.awaitRemoteNodes(node1, 1);
+
+ String expectedMessage = HighAvailabilityMessages.ADDED(node2.getName(), groupName).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.ADDED_LOG_HIERARCHY)));
+ }
+
+ public void testRemoteNodeRemoved() throws Exception
+ {
+ int node1PortNumber = findFreePort();
+ String helperAddress = "localhost:" + node1PortNumber;
+ String groupName = "group";
+ String nodeName = "node1";
+
+ Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress);
+ node1Attributes.put(BDBHAVirtualHostNode.DESIGNATED_PRIMARY, true);
+ BDBHAVirtualHostNodeImpl node1 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node1Attributes);
+ _helper.assertNodeRole(node1, "MASTER");
+
+ resetEventLogger();
+
+ int node2PortNumber = getNextAvailable(node1PortNumber + 1);
+ Map<String, Object> node2Attributes = _helper.createNodeAttributes("node2", groupName, "localhost:" + node2PortNumber, helperAddress);
+ BDBHAVirtualHostNodeImpl node2 = (BDBHAVirtualHostNodeImpl)_helper.createHaVHN(node2Attributes);
+ _helper.awaitRemoteNodes(node1, 1);
+
+ reset(_eventLogger);
+
+ node2.delete();
+ _helper.awaitRemoteNodes(node1, 0);
+
+ String expectedMessage = HighAvailabilityMessages.DELETED(node2.getName(), groupName).toString();
+ verify(_eventLogger).message(eq(node1.getVirtualHostNodeLogSubject()),
+ argThat(new LogMessageMatcher(expectedMessage, HighAvailabilityMessages.DELETED_LOG_HIERARCHY)));
+ }
+
+ private EventLogger resetEventLogger()
+ {
+ EventLogger eventLogger = mock(EventLogger.class);
+ SystemContext<?> context = (SystemContext<?>) _helper.getBroker().getParent(SystemContext.class);
+ when(context.getEventLogger()).thenReturn(eventLogger);
+ return eventLogger;
+ }
+
+ class LogMessageMatcher extends ArgumentMatcher<LogMessage>
+ {
+
+ private String _expectedMessage;
+ private String _expectedHierarchy;
+
+ public LogMessageMatcher(String expectedMessage, String expectedHierarchy)
+ {
+ _expectedMessage = expectedMessage;
+ _expectedHierarchy = expectedHierarchy;
+ }
+
+ @Override
+ public boolean matches(Object argument)
+ {
+ LogMessage logMessage = (LogMessage)argument;
+ return _expectedMessage.equals( logMessage.toString()) && _expectedHierarchy.equals(logMessage.getLogHierarchy());
+ }
+ }
+}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java
new file mode 100644
index 0000000000..0fd06645bc
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java
@@ -0,0 +1,264 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.virtualhostnode.berkeleydb;
+
+import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import com.sleepycat.je.rep.ReplicationConfig;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutorImpl;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObjectFactory;
+import org.apache.qpid.server.model.RemoteReplicationNode;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.util.FileUtils;
+
+/**
+ * Helper class to make the tests of BDB HA Virtual Host Nodes simpler and more concise.
+ */
+public class BDBHAVirtualHostNodeTestHelper
+{
+ private final String _testName;
+ private Broker<?> _broker;
+ private File _bdbStorePath;
+ private TaskExecutor _taskExecutor;
+ private final ConfiguredObjectFactory _objectFactory = BrokerModel.getInstance().getObjectFactory();
+ private final Set<BDBHAVirtualHostNode<?>> _nodes = new HashSet<>();
+
+ public BDBHAVirtualHostNodeTestHelper(String testName) throws Exception
+ {
+ _testName = testName;
+ _broker = BrokerTestHelper.createBrokerMock();
+
+ _taskExecutor = new TaskExecutorImpl();
+ _taskExecutor.start();
+ when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
+
+ _bdbStorePath = new File(QpidTestCase.TMP_FOLDER, _testName + "." + System.currentTimeMillis());
+ _bdbStorePath.deleteOnExit();
+ }
+
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ Exception firstException = null;
+ for (VirtualHostNode<?> node : _nodes)
+ {
+ try
+ {
+ node.delete();
+ }
+ catch(Exception e)
+ {
+ if (firstException != null)
+ {
+ firstException = e;
+ }
+ }
+ if (firstException != null)
+ {
+ throw firstException;
+ }
+ }
+ }
+ finally
+ {
+ if (_taskExecutor != null)
+ {
+ _taskExecutor.stopImmediately();
+ }
+ if (_bdbStorePath != null)
+ {
+ FileUtils.delete(_bdbStorePath, true);
+ }
+ }
+ }
+
+ public BDBHARemoteReplicationNode<?> findRemoteNode(BDBHAVirtualHostNode<?> node, String name)
+ {
+ for (RemoteReplicationNode<?> remoteNode : node.getRemoteReplicationNodes())
+ {
+ if (remoteNode.getName().equals(name))
+ {
+ return (BDBHARemoteReplicationNode<?>)remoteNode;
+ }
+ }
+ return null;
+ }
+
+ public void awaitRemoteNodes(BDBHAVirtualHostNode<?> node, int expectedNodeNumber) throws InterruptedException
+ {
+ int counter = 0;
+
+ @SuppressWarnings("rawtypes")
+ Collection<? extends RemoteReplicationNode> remoteNodes = null;
+ do
+ {
+ remoteNodes = node.getRemoteReplicationNodes();
+ if (counter > 0)
+ {
+ Thread.sleep(100);
+ }
+ counter++;
+ }
+ // TODO: 30 seconds is quite a lot to wait, we need to reduce this limit
+ while(remoteNodes.size() != expectedNodeNumber && counter<100);
+ assertEquals("Unexpected node number", expectedNodeNumber, node.getRemoteReplicationNodes().size());
+ }
+
+ public void awaitForAttributeChange(ConfiguredObject<?> object, String name, Object expectedValue) throws InterruptedException
+ {
+ int awaitCounter = 0;
+ while(!object.equals(object.getAttribute(name)) && awaitCounter < 50)
+ {
+ Thread.sleep(100);
+ awaitCounter++;
+ }
+ assertEquals("Unexpected attribute " + name + " on " + object, expectedValue, object.getAttribute(name) );
+ }
+
+ public BDBHAVirtualHostNode<?> awaitAndFindNodeInRole(String role) throws InterruptedException
+ {
+ BDBHAVirtualHostNode<?> replica = null;
+ int findReplicaCount = 0;
+ while(replica == null)
+ {
+ replica = findNodeInRole(role);
+ if (replica == null)
+ {
+ Thread.sleep(100);
+ }
+ if (findReplicaCount > 50)
+ {
+ fail("Could not find a node in replica role");
+ }
+ findReplicaCount++;
+ }
+ return replica;
+ }
+
+ public BDBHAVirtualHostNode<?> findNodeInRole(String role)
+ {
+ for (BDBHAVirtualHostNode<?> node : _nodes)
+ {
+ if (role.equals(node.getRole()))
+ {
+ return node;
+ }
+ }
+ return null;
+ }
+
+ public BDBHAVirtualHostNode<?> createHaVHN(Map<String, Object> attributes)
+ {
+ @SuppressWarnings("unchecked")
+ BDBHAVirtualHostNode<?> node = (BDBHAVirtualHostNode<?>) _objectFactory.create(VirtualHostNode.class, attributes, _broker);
+ _nodes.add(node);
+ return node;
+ }
+
+ public void assertNodeRole(BDBHAVirtualHostNode<?> node, String... roleName) throws InterruptedException
+ {
+ int iterationCounter = 0;
+ boolean inRole =false;
+ do
+ {
+ for (String role : roleName)
+ {
+ if (role.equals(node.getRole()))
+ {
+ inRole = true;
+ break;
+ }
+ }
+ if (!inRole)
+ {
+ Thread.sleep(50);
+ }
+ iterationCounter++;
+ }
+ while(!inRole && iterationCounter<100);
+ assertTrue("Node " + node.getName() + " did not transit into role " + Arrays.toString(roleName), inRole);
+ }
+
+ public BDBHAVirtualHostNode<?> createAndStartHaVHN(Map<String, Object> attributes) throws InterruptedException
+ {
+ BDBHAVirtualHostNode<?> node = createHaVHN(attributes);
+ return startNodeAndWait(node);
+ }
+
+ public BDBHAVirtualHostNode<?> startNodeAndWait(BDBHAVirtualHostNode<?> node) throws InterruptedException
+ {
+ node.start();
+ assertNodeRole(node, "MASTER", "REPLICA");
+ assertEquals("Unexpected node state", State.ACTIVE, node.getState());
+ return node;
+ }
+
+ public String getMessageStorePath()
+ {
+ return _bdbStorePath.getAbsolutePath();
+ }
+
+ public Broker getBroker()
+ {
+ return _broker;
+ }
+
+ Map<String, Object> createNodeAttributes(String nodeName, String groupName, String address, String helperAddress)
+ {
+ Map<String, Object> node1Attributes = new HashMap<String, Object>();
+ node1Attributes.put(BDBHAVirtualHostNode.ID, UUID.randomUUID());
+ node1Attributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA");
+ node1Attributes.put(BDBHAVirtualHostNode.NAME, nodeName);
+ node1Attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName);
+ node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, address);
+ node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
+ node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, getMessageStorePath() + File.separator + nodeName);
+
+ Map<String, String> repConfig = new HashMap<String, String>();
+ repConfig.put(ReplicationConfig.REPLICA_ACK_TIMEOUT, "2 s");
+ repConfig.put(ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT, "2 s");
+
+ node1Attributes.put(BDBHAVirtualHostNode.CONTEXT, repConfig);
+
+ return node1Attributes;
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java
new file mode 100644
index 0000000000..9e497efcd2
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailabilityMessages.java
@@ -0,0 +1,502 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging.messages;
+
+import static org.apache.qpid.server.logging.AbstractMessageLogger.DEFAULT_LOG_HIERARCHY_PREFIX;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.logging.LogMessage;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * DO NOT EDIT DIRECTLY, THIS FILE WAS GENERATED.
+ *
+ * Generated using GenerateLogMessages and LogMessages.vm
+ * This file is based on the content of HighAvailability_logmessages.properties
+ *
+ * To regenerate, edit the templates/properties and run the build with -Dgenerate=true
+ */
+public class HighAvailabilityMessages
+{
+ private static ResourceBundle _messages;
+ private static Locale _currentLocale = BrokerProperties.getLocale();
+
+ public static final String HIGHAVAILABILITY_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability";
+ public static final String STOPPED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.stopped";
+ public static final String INTRUDER_DETECTED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.intruder_detected";
+ public static final String STARTED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.started";
+ public static final String TRANSFER_MASTER_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.transfer_master";
+ public static final String QUORUM_OVERRIDE_CHANGED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.quorum_override_changed";
+ public static final String DETACHED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.detached";
+ public static final String MAJORITY_LOST_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.majority_lost";
+ public static final String PRIORITY_CHANGED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.priority_changed";
+ public static final String ATTACHED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.attached";
+ public static final String ADDED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.added";
+ public static final String DELETED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.deleted";
+ public static final String ROLE_CHANGED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.role_changed";
+ public static final String DESIGNATED_PRIMARY_CHANGED_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "highavailability.designated_primary_changed";
+
+ static
+ {
+ Logger.getLogger(HIGHAVAILABILITY_LOG_HIERARCHY);
+ Logger.getLogger(STOPPED_LOG_HIERARCHY);
+ Logger.getLogger(INTRUDER_DETECTED_LOG_HIERARCHY);
+ Logger.getLogger(STARTED_LOG_HIERARCHY);
+ Logger.getLogger(TRANSFER_MASTER_LOG_HIERARCHY);
+ Logger.getLogger(QUORUM_OVERRIDE_CHANGED_LOG_HIERARCHY);
+ Logger.getLogger(DETACHED_LOG_HIERARCHY);
+ Logger.getLogger(MAJORITY_LOST_LOG_HIERARCHY);
+ Logger.getLogger(PRIORITY_CHANGED_LOG_HIERARCHY);
+ Logger.getLogger(ATTACHED_LOG_HIERARCHY);
+ Logger.getLogger(ADDED_LOG_HIERARCHY);
+ Logger.getLogger(DELETED_LOG_HIERARCHY);
+ Logger.getLogger(ROLE_CHANGED_LOG_HIERARCHY);
+ Logger.getLogger(DESIGNATED_PRIMARY_CHANGED_LOG_HIERARCHY);
+
+ _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.HighAvailability_logmessages", _currentLocale);
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1012 : The node ''{0}'' from the replication group ''{1}'' is stopped.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage STOPPED(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("STOPPED");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return STOPPED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1007: Intruder node ''{0}'' from ''{1}'' is detected in replication group ''{2}''</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage INTRUDER_DETECTED(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("INTRUDER_DETECTED");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return INTRUDER_DETECTED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1013 : The node ''{0}'' from the replication group ''{1}'' is started.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage STARTED(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("STARTED");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return STARTED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1014 : Transfer master to ''{0}'' is requested on node ''{1}'' from the replication group ''{2}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage TRANSFER_MASTER(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("TRANSFER_MASTER");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return TRANSFER_MASTER_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1009 : The quorum override attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage QUORUM_OVERRIDE_CHANGED(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("QUORUM_OVERRIDE_CHANGED");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return QUORUM_OVERRIDE_CHANGED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1003 : The node ''{0}'' detached from the replication group ''{1}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage DETACHED(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("DETACHED");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return DETACHED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1006 : A majority of nodes from replication group ''{0}'' is not available for node ''{1}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage MAJORITY_LOST(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("MAJORITY_LOST");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return MAJORITY_LOST_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1008 : The priority attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage PRIORITY_CHANGED(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("PRIORITY_CHANGED");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return PRIORITY_CHANGED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1004 : The node ''{0}'' attached to the replication group ''{1}'' with role ''{2}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage ATTACHED(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("ATTACHED");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return ATTACHED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1001 : A new node ''{0}'' is added into a replication group ''{1}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage ADDED(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("ADDED");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return ADDED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1002 : An existing node ''{0}'' is removed from the replication group ''{1}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage DELETED(String param1, String param2)
+ {
+ String rawMessage = _messages.getString("DELETED");
+
+ final Object[] messageArguments = {param1, param2};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return DELETED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1005 : The role of the node ''{0}'' from the replication group ''{1}'' has changed from ''{2}'' to ''{3}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage ROLE_CHANGED(String param1, String param2, String param3, String param4)
+ {
+ String rawMessage = _messages.getString("ROLE_CHANGED");
+
+ final Object[] messageArguments = {param1, param2, param3, param4};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return ROLE_CHANGED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+ /**
+ * Log a HighAvailability message of the Format:
+ * <pre>HA-1010 : The designated primary attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.</pre>
+ * Optional values are contained in [square brackets] and are numbered
+ * sequentially in the method call.
+ *
+ */
+ public static LogMessage DESIGNATED_PRIMARY_CHANGED(String param1, String param2, String param3)
+ {
+ String rawMessage = _messages.getString("DESIGNATED_PRIMARY_CHANGED");
+
+ final Object[] messageArguments = {param1, param2, param3};
+ // Create a new MessageFormat to ensure thread safety.
+ // Sharing a MessageFormat and using applyPattern is not thread safe
+ MessageFormat formatter = new MessageFormat(rawMessage, _currentLocale);
+
+ final String message = formatter.format(messageArguments);
+
+ return new LogMessage()
+ {
+ public String toString()
+ {
+ return message;
+ }
+
+ public String getLogHierarchy()
+ {
+ return DESIGNATED_PRIMARY_CHANGED_LOG_HIERARCHY;
+ }
+ };
+ }
+
+
+ private HighAvailabilityMessages()
+ {
+ }
+
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties
new file mode 100644
index 0000000000..94df7cc38b
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/messages/HighAvailability_logmessages.properties
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# HA logging message i18n strings.
+ADDED=HA-1001 : A new node ''{0}'' is added into a replication group ''{1}''.
+DELETED=HA-1002 : An existing node ''{0}'' is removed from the replication group ''{1}''.
+DETACHED=HA-1003 : The node ''{0}'' detached from the replication group ''{1}''.
+ATTACHED=HA-1004 : The node ''{0}'' attached to the replication group ''{1}'' with role ''{2}''.
+ROLE_CHANGED=HA-1005 : The role of the node ''{0}'' from the replication group ''{1}'' has changed from ''{2}'' to ''{3}''.
+MAJORITY_LOST=HA-1006 : A majority of nodes from replication group ''{0}'' is not available for node ''{1}''.
+INTRUDER_DETECTED=HA-1007: Intruder node ''{0}'' from ''{1}'' is detected in replication group ''{2}''
+PRIORITY_CHANGED=HA-1008 : The priority attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.
+QUORUM_OVERRIDE_CHANGED=HA-1009 : The quorum override attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.
+DESIGNATED_PRIMARY_CHANGED=HA-1010 : The designated primary attribute of node ''{0}'' from the replication group ''{1}'' is set to ''{2}''.
+STOPPED=HA-1011 : The node ''{0}'' from the replication group ''{1}'' is stopped.
+STARTED=HA-1012 : The node ''{0}'' from the replication group ''{1}'' is started.
+TRANSFER_MASTER=HA-1013 : Transfer master to ''{0}'' is requested on node ''{1}'' from the replication group ''{2}''.
+
+
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
index 7611ee1a88..edb78369ae 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
@@ -115,4 +115,6 @@ public class LogSubjectFormat
* 1 - queue name
*/
public static final String QUEUE_FORMAT = "vh(/{0})/qu({1})";
+
+ public static final String VIRTUAL_HOST_NODE_FORMAT = "vhn(/{0}))";
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/VirtualHostNodeLogSubject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/VirtualHostNodeLogSubject.java
new file mode 100644
index 0000000000..fad9a91841
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/logging/subjects/VirtualHostNodeLogSubject.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.logging.subjects;
+
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.VIRTUAL_HOST_NODE_FORMAT;
+
+import org.apache.qpid.server.model.VirtualHostNode;
+
+public class VirtualHostNodeLogSubject extends AbstractLogSubject
+{
+ public VirtualHostNodeLogSubject(String nodeName)
+ {
+ setLogStringWithFormat(VIRTUAL_HOST_NODE_FORMAT, nodeName);
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
index b21fcd704f..c9220b7b74 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
@@ -24,6 +24,7 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.logging.EventLogger;
import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
+import org.apache.qpid.server.logging.subjects.VirtualHostNodeLogSubject;
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -51,6 +52,7 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
private final Broker<?> _broker;
private final AtomicReference<State> _state = new AtomicReference<State>(State.UNINITIALIZED);
private final EventLogger _eventLogger;
+ private final VirtualHostNodeLogSubject _virtualHostNodeLogSubject;
private DurableConfigurationStore _durableConfigurationStore;
@@ -63,6 +65,7 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
_broker = parent;
SystemContext<?> systemContext = _broker.getParent(SystemContext.class);
_eventLogger = systemContext.getEventLogger();
+ _virtualHostNodeLogSubject = new VirtualHostNodeLogSubject(getName());
}
@@ -89,7 +92,7 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
@StateTransition( currentState = {State.UNINITIALIZED, State.STOPPED, State.ERRORED }, desiredState = State.ACTIVE )
- private void doActivate()
+ protected void doActivate()
{
try
{
@@ -243,4 +246,8 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
protected abstract void activate();
+ public VirtualHostNodeLogSubject getVirtualHostNodeLogSubject()
+ {
+ return _virtualHostNodeLogSubject;
+ }
}