You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2014/08/28 13:07:36 UTC

svn commit: r1621116 - in /qpid/branches/0.30: ./ qpid/ qpid/java/ qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/ qpid/java/bdbstore/...

Author: orudyy
Date: Thu Aug 28 11:07:35 2014
New Revision: 1621116

URL: http://svn.apache.org/r1621116
Log:
QPID-6048: Move permitted nodes attribute into BDB HA VH in order to be able to identify the intruder node on node start-up

svn merge -c 1620882 https://svn.apache.org/repos/asf/qpid/trunk

Modified:
    qpid/branches/0.30/   (props changed)
    qpid/branches/0.30/qpid/   (props changed)
    qpid/branches/0.30/qpid/java/   (props changed)
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHost.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHostImpl.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/edit.js
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/show.js
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/show.html
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
    qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/show.html
    qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
    qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java
    qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
    qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java
    qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java
    qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostRestTest.java
    qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupCreator.java
    qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java

Propchange: qpid/branches/0.30/
------------------------------------------------------------------------------
  Merged /qpid/trunk:r1620882

Propchange: qpid/branches/0.30/qpid/
------------------------------------------------------------------------------
  Merged /qpid/trunk/qpid:r1620882

Propchange: qpid/branches/0.30/qpid/java/
------------------------------------------------------------------------------
  Merged /qpid/trunk/qpid/java:r1620882

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java Thu Aug 28 11:07:35 2014
@@ -1220,7 +1220,7 @@ public class ReplicatedEnvironmentFacade
         }
     }
 
-    public static void connectToHelperNodeAndCheckPermittedHosts(String nodeName, String hostPort, String groupName, String helperNodeName, String helperHostPort)
+    public static Collection<String> connectToHelperNodeAndCheckPermittedHosts(String nodeName, String hostPort, String groupName, String helperNodeName, String helperHostPort)
     {
         if (LOGGER.isDebugEnabled())
         {
@@ -1264,26 +1264,8 @@ public class ReplicatedEnvironmentFacade
         {
             throw new IllegalConfigurationException(String.format("Node from '%s' is not permitted!", hostPort));
         }
-    }
 
-    private void findMasterNodeStateAndApplyPermittedNodes(Collection<NodeState> nodeStates)
-    {
-        if (ReplicatedEnvironment.State.MASTER != _environment.getState())
-        {
-            for (NodeState nodeState : nodeStates)
-            {
-                if (nodeState.getNodeState() == ReplicatedEnvironment.State.MASTER)
-                {
-                    byte[] applicationState = nodeState.getAppState();
-                    Set<String> permittedNodes = convertApplicationStateBytesToPermittedNodeList(applicationState);
-                    if (!_permittedNodes.equals(permittedNodes))
-                    {
-                        setPermittedNodes(permittedNodes);
-                    }
-                    break;
-                }
-            }
-        }
+        return permittedNodes;
     }
 
     private void registerAppStateMonitorIfPermittedNodesSpecified()
@@ -1312,16 +1294,17 @@ public class ReplicatedEnvironmentFacade
     }
 
 
-    private void onIntruder(ReplicationGroupListener replicationGroupListener, ReplicationNode replicationNode)
+    private boolean onIntruder(ReplicationGroupListener replicationGroupListener, ReplicationNode replicationNode)
     {
         if (replicationGroupListener != null)
         {
-            replicationGroupListener.onIntruderNode(replicationNode);
+            return replicationGroupListener.onIntruderNode(replicationNode);
         }
         else
         {
             LOGGER.warn(String.format("Found an intruder node '%s' from ''%s' . The node is not listed in permitted list: %s",
                     replicationNode.getName(), getHostPort(replicationNode), String.valueOf(_permittedNodes)));
+            return true;
         }
     }
 
@@ -1373,46 +1356,55 @@ public class ReplicatedEnvironmentFacade
         @Override
         public Void call()
         {
+            boolean continueMonitoring = true;
             try
             {
                 if (_state.get() == State.OPEN)
                 {
                     try
                     {
-                        detectGroupChangesAndNotify();
+                        continueMonitoring = detectGroupChangesAndNotify();
                     }
                     catch(DatabaseException e)
                     {
                         handleDatabaseException("Exception on replication group check", e);
                     }
 
-                    Map<ReplicationNode, NodeState> nodeStates = discoverNodeStates(_remoteReplicationNodes.values());
-
-                    executeDatabasePingerOnNodeChangesIfMaster(nodeStates);
+                    if (continueMonitoring)
+                    {
+                        Map<ReplicationNode, NodeState> nodeStates = discoverNodeStates(_remoteReplicationNodes.values());
 
-                    notifyGroupListenerAboutNodeStates(nodeStates);
+                        executeDatabasePingerOnNodeChangesIfMaster(nodeStates);
 
-                    findMasterNodeStateAndApplyPermittedNodes(nodeStates.values());
+                       notifyGroupListenerAboutNodeStates(nodeStates);
+                    }
                 }
             }
             finally
             {
                 State state = _state.get();
-                if (state != State.CLOSED && state != State.CLOSING)
+                if (state != State.CLOSED && state != State.CLOSING && continueMonitoring)
                 {
                     _groupChangeExecutor.schedule(this, REMOTE_NODE_MONITOR_INTERVAL, TimeUnit.MILLISECONDS);
                 }
+                else
+                {
+                    if (LOGGER.isDebugEnabled())
+                    {
+                        LOGGER.debug("Monitoring task is not scheduled:  state " + state + ", continue monitoring flag " + continueMonitoring);
+                    }
+                }
             }
             return null;
         }
 
-        private void detectGroupChangesAndNotify()
+        private boolean detectGroupChangesAndNotify()
         {
             if (LOGGER.isDebugEnabled())
             {
                 LOGGER.debug("Checking for changes in the group " + _configuration.getGroupName() + " on node " + _configuration.getName());
             }
-
+            boolean shouldContinue = true;
             String groupName = _configuration.getGroupName();
             ReplicatedEnvironment env = _environment;
             ReplicationGroupListener replicationGroupListener = _replicationGroupListener.get();
@@ -1446,7 +1438,10 @@ public class ReplicatedEnvironmentFacade
                             }
                             else
                             {
-                                onIntruder(replicationGroupListener, replicationNode);
+                                if (!onIntruder(replicationGroupListener, replicationNode))
+                                {
+                                    shouldContinue = false;
+                                }
                             }
                         }
                         else
@@ -1473,6 +1468,7 @@ public class ReplicatedEnvironmentFacade
                     }
                 }
             }
+            return shouldContinue;
         }
 
         private Map<ReplicationNode, NodeState> discoverNodeStates(Collection<ReplicationNode> electableNodes)

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicationGroupListener.java Thu Aug 28 11:07:35 2014
@@ -51,7 +51,7 @@ public interface ReplicationGroupListene
     /**
      * Invoked on intruder node detected
      */
-    void onIntruderNode(ReplicationNode node);
+    boolean onIntruderNode(ReplicationNode node);
 
     void onNoMajority();
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHost.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHost.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHost.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHost.java Thu Aug 28 11:07:35 2014
@@ -36,7 +36,6 @@ public interface BDBHAVirtualHost<X exte
     String COALESCING_SYNC = "coalescingSync";
     String DURABILITY = "durability";
     String STORE_PATH = "storePath";
-    String PERMITTED_NODES = "permittedNodes";
 
     @ManagedAttribute( defaultValue = "SYNC")
     String getLocalTransactionSynchronizationPolicy();
@@ -55,7 +54,4 @@ public interface BDBHAVirtualHost<X exte
 
     @ManagedAttribute(mandatory = true, defaultValue = "0")
     Long getStoreOverfullSize();
-
-    @ManagedAttribute(mandatory = true)
-    List<String> getPermittedNodes();
 }

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHostImpl.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHostImpl.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHostImpl.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAVirtualHostImpl.java Thu Aug 28 11:07:35 2014
@@ -20,7 +20,6 @@
  */
 package org.apache.qpid.server.virtualhost.berkeleydb;
 
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -55,9 +54,6 @@ public class BDBHAVirtualHostImpl extend
     @ManagedAttributeField
     private Long _storeOverfullSize;
 
-    @ManagedAttributeField(afterSet = "applyPermittedNodes")
-    private List<String> _permittedNodes;
-
     @ManagedObjectFactoryConstructor
     public BDBHAVirtualHostImpl(final Map<String, Object> attributes, VirtualHostNode<?> virtualHostNode)
     {
@@ -132,34 +128,6 @@ public class BDBHAVirtualHostImpl extend
             validateTransactionSynchronizationPolicy(policy);
         }
 
-        if(changedAttributes.contains(PERMITTED_NODES))
-        {
-            validatePermittedNodes(((BDBHAVirtualHost<?>)proxyForValidation).getPermittedNodes());
-        }
-    }
-
-    private void validatePermittedNodes(List<String> permittedNodes)
-    {
-        if (permittedNodes == null || permittedNodes.isEmpty())
-        {
-            throw new IllegalArgumentException(String.format("Attribute '%s' is mandatory and must be set", PERMITTED_NODES));
-        }
-        for (String permittedNode: permittedNodes)
-        {
-            String[] tokens = permittedNode.split(":");
-            if (tokens.length != 2)
-            {
-                throw new IllegalArgumentException(String.format("Invalid permitted node specified '%s'. ", permittedNode));
-            }
-            try
-            {
-                Integer.parseInt(tokens[1]);
-            }
-            catch(Exception e)
-            {
-                throw new IllegalArgumentException(String.format("Invalid port is specified in permitted node '%s'. ", permittedNode));
-            }
-        }
     }
 
     private void validateTransactionSynchronizationPolicy(String policy)
@@ -192,27 +160,12 @@ public class BDBHAVirtualHostImpl extend
     }
 
     @Override
-    public List<String> getPermittedNodes()
-    {
-        return _permittedNodes;
-    }
-
-    @Override
     public void onValidate()
     {
         super.onValidate();
 
-        validatePermittedNodes(this.getPermittedNodes());
         validateTransactionSynchronizationPolicy(this.getLocalTransactionSynchronizationPolicy());
         validateTransactionSynchronizationPolicy(this.getRemoteTransactionSynchronizationPolicy());
     }
 
-    protected void applyPermittedNodes()
-    {
-        ReplicatedEnvironmentFacade facade = getReplicatedEnvironmentFacade();
-        if (facade != null)
-        {
-            facade.setPermittedNodes(getPermittedNodes());
-        }
-    }
 }

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java Thu Aug 28 11:07:35 2014
@@ -20,10 +20,13 @@
  */
 package org.apache.qpid.server.virtualhostnode.berkeleydb;
 
+import java.util.List;
+
 import org.apache.qpid.server.model.DerivedAttribute;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.store.berkeleydb.HASettings;
 
+
 public interface BDBHAVirtualHostNode<X extends BDBHAVirtualHostNode<X>> extends BDBVirtualHostNode<X>, HASettings
 {
     public static final String GROUP_NAME = "groupName";
@@ -37,6 +40,7 @@ public interface BDBHAVirtualHostNode<X 
     public static final String LAST_KNOWN_REPLICATION_TRANSACTION_ID = "lastKnownReplicationTransactionId";
     public static final String JOIN_TIME = "joinTime";
     public static final String HELPER_NODE_NAME = "helperNodeName";
+    public static final String PERMITTED_NODES = "permittedNodes";
 
     @ManagedAttribute(mandatory=true)
     String getGroupName();
@@ -67,4 +71,7 @@ public interface BDBHAVirtualHostNode<X 
 
     @ManagedAttribute(persist = false)
     String getHelperNodeName();
+
+    @ManagedAttribute(persist = true)
+    List<String> getPermittedNodes();
 }

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java Thu Aug 28 11:07:35 2014
@@ -23,10 +23,12 @@ package org.apache.qpid.server.virtualho
 import java.net.InetSocketAddress;
 import java.security.PrivilegedAction;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
@@ -126,6 +128,9 @@ public class BDBHAVirtualHostNodeImpl ex
     @ManagedAttributeField
     private String _helperNodeName;
 
+    @ManagedAttributeField(afterSet = "postSetPermittedNodes")
+    private List<String> _permittedNodes;
+
     @ManagedObjectFactoryConstructor
     public BDBHAVirtualHostNodeImpl(Map<String, Object> attributes, Broker<?> broker)
     {
@@ -136,6 +141,8 @@ public class BDBHAVirtualHostNodeImpl ex
     protected void validateChange(final ConfiguredObject<?> proxyForValidation, final Set<String> changedAttributes)
     {
         super.validateChange(proxyForValidation, changedAttributes);
+        BDBHAVirtualHostNode<?> proposed = (BDBHAVirtualHostNode<?>)proxyForValidation;
+
         if (changedAttributes.contains(ROLE))
         {
             String currentRole = getRole();
@@ -143,12 +150,17 @@ public class BDBHAVirtualHostNodeImpl ex
             {
                 throw new IllegalStateException("Cannot transfer mastership when not a replica, current role is " + currentRole);
             }
-            BDBHAVirtualHostNode<?> proposed = (BDBHAVirtualHostNode<?>)proxyForValidation;
+
             if (!ReplicatedEnvironment.State.MASTER.name().equals(proposed.getRole()))
             {
                 throw new IllegalArgumentException("Changing role to other value then " + ReplicatedEnvironment.State.MASTER.name() + " is unsupported");
             }
         }
+
+        if (changedAttributes.contains(PERMITTED_NODES))
+        {
+            validatePermittedNodes(proposed.getPermittedNodes());
+        }
     }
 
     @Override
@@ -227,6 +239,12 @@ public class BDBHAVirtualHostNodeImpl ex
         return _helperNodeName;
     }
 
+    @Override
+    public List<String> getPermittedNodes()
+    {
+        return _permittedNodes;
+    }
+
     @SuppressWarnings("rawtypes")
     @Override
     public Collection<? extends RemoteReplicationNode> getRemoteReplicationNodes()
@@ -268,7 +286,8 @@ public class BDBHAVirtualHostNodeImpl ex
         {
             try
             {
-                ReplicatedEnvironmentFacade.connectToHelperNodeAndCheckPermittedHosts(getName(), getAddress(), getGroupName(), getHelperNodeName(), getHelperAddress());
+                Collection<String> permittedNodes = ReplicatedEnvironmentFacade.connectToHelperNodeAndCheckPermittedHosts(getName(), getAddress(), getGroupName(), getHelperNodeName(), getHelperAddress());
+                setAttribute(PERMITTED_NODES, null, new ArrayList<String>(permittedNodes));
             }
             catch(IllegalConfigurationException e)
             {
@@ -314,6 +333,7 @@ public class BDBHAVirtualHostNodeImpl ex
         {
             environmentFacade.setStateChangeListener(new EnvironmentStateChangeListener());
             environmentFacade.setReplicationGroupListener(new RemoteNodesDiscoverer());
+            environmentFacade.setPermittedNodes(_permittedNodes);
         }
     }
 
@@ -416,6 +436,14 @@ public class BDBHAVirtualHostNodeImpl ex
         _virtualHostNodePrincipalName = MessageFormat.format(VIRTUAL_HOST_PRINCIPAL_NAME_FORMAT, getGroupName(), getName());
     }
 
+    @Override
+    public  void onOpen()
+    {
+        super.onOpen();
+
+        validatePermittedNodes(_permittedNodes);
+    }
+
     private void onMaster()
     {
         try
@@ -719,6 +747,40 @@ public class BDBHAVirtualHostNodeImpl ex
                                               hostAttributes, vhostRecord.getParents());
     }
 
+    protected void postSetPermittedNodes()
+    {
+        ReplicatedEnvironmentFacade replicatedEnvironmentFacade = getReplicatedEnvironmentFacade();
+        if (replicatedEnvironmentFacade != null)
+        {
+            replicatedEnvironmentFacade.setPermittedNodes(_permittedNodes);
+        }
+    }
+
+    private void validatePermittedNodes(List<String> permittedNodes)
+    {
+        if (permittedNodes == null || permittedNodes.isEmpty())
+        {
+            throw new IllegalArgumentException(String.format("Attribute '%s' is mandatory and must be set", PERMITTED_NODES));
+        }
+        for (String permittedNode: permittedNodes)
+        {
+            String[] tokens = permittedNode.split(":");
+            if (tokens.length != 2)
+            {
+                throw new IllegalArgumentException(String.format("Invalid permitted node specified '%s'. ", permittedNode));
+            }
+            try
+            {
+                Integer.parseInt(tokens[1]);
+            }
+            catch(Exception e)
+            {
+                throw new IllegalArgumentException(String.format("Invalid port is specified in permitted node '%s'. ", permittedNode));
+            }
+        }
+
+    }
+
     private class RemoteNodesDiscoverer implements ReplicationGroupListener
     {
         @Override
@@ -827,6 +889,23 @@ public class BDBHAVirtualHostNodeImpl ex
                         getEventLogger().message(getGroupLogSubject(), HighAvailabilityMessages.JOINED(remoteNode.getName(), remoteNode.getAddress()));
                         remoteNode.setDetached(false);
                     }
+                    if (ReplicatedEnvironment.State.MASTER.name().equals(remoteNode.getRole()))
+                    {
+                        byte[] applicationState = nodeState.getAppState();
+                        Set<String> permittedNodes = ReplicatedEnvironmentFacade.convertApplicationStateBytesToPermittedNodeList(applicationState);
+                        if (!_permittedNodes.equals(permittedNodes))
+                        {
+                            if (_permittedNodes.contains(remoteNode.getAddress()))
+                            {
+                                setAttribute(PERMITTED_NODES, _permittedNodes, new ArrayList<String>(permittedNodes));
+                            }
+                            else
+                            {
+                                LOGGER.warn("Cannot change permitted nodes from Master as existing master node '" + remoteNode.getName()
+                                        + "' (" + remoteNode.getAddress() + ") is not in list of trusted nodes " + _permittedNodes);
+                            }
+                        }
+                    }
                 }
 
                 String newRole = remoteNode.getRole();
@@ -838,20 +917,20 @@ public class BDBHAVirtualHostNodeImpl ex
         }
 
         @Override
-        public void onIntruderNode(final ReplicationNode node)
+        public boolean onIntruderNode(final ReplicationNode node)
         {
-            Subject.doAs(SecurityManager.getSystemTaskSubject(_virtualHostNodePrincipalName), new PrivilegedAction<Void>()
+            return Subject.doAs(SecurityManager.getSystemTaskSubject(_virtualHostNodePrincipalName), new PrivilegedAction<Boolean>()
             {
                 @Override
-                public Void run()
+                public Boolean run()
                 {
-                    processIntruderNode(node);
-                    return null;
+                    return processIntruderNode(node);
+
                 }
             });
         }
 
-        private void processIntruderNode(ReplicationNode node)
+        private boolean processIntruderNode(ReplicationNode node)
         {
             String hostAndPort = node.getHostName() + ":" + node.getPort();
             getEventLogger().message(getGroupLogSubject(), HighAvailabilityMessages.INTRUDER_DETECTED(node.getName(), hostAndPort));
@@ -864,11 +943,12 @@ public class BDBHAVirtualHostNodeImpl ex
                 {
                     addRemoteReplicationNode(node);
                 }
+                return true;
             }
             else
             {
-                LOGGER.error(String.format("Intruder node '%s' from '%s' is detected. Stopping down virtual host node '%s'",
-                        node.getName(), hostAndPort, BDBHAVirtualHostNodeImpl.this.toString() ));
+                LOGGER.error(String.format("Intruder node '%s' from '%s' detected. Shutting down virtual host node '%s' based on permitted nodes '%s'",
+                        node.getName(), hostAndPort, BDBHAVirtualHostNodeImpl.this.getName(), String.valueOf(BDBHAVirtualHostNodeImpl.this.getPermittedNodes()) ));
 
                 getTaskExecutor().submit(new Task<Void>()
                 {
@@ -876,13 +956,16 @@ public class BDBHAVirtualHostNodeImpl ex
                     public Void execute()
                     {
                         State state = getState();
-
                         if (state == State.ACTIVE)
                         {
                             try
                             {
                                 stopAndSetStateTo(State.ERRORED);
                             }
+                            catch(Exception e)
+                            {
+                                LOGGER.error("Unexpected exception on closing the node when intruder is detected ", e);
+                            }
                             finally
                             {
                                 closeEnvironment();
@@ -892,6 +975,7 @@ public class BDBHAVirtualHostNodeImpl ex
                         return null;
                     }
                 });
+                return false;
             }
         }
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/edit.js Thu Aug 28 11:07:35 2014
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-define(["qpid/common/util", "qpid/common/metadata", "dijit/registry", "dojo/_base/window", "dojo/domReady!"],
+define(["qpid/common/util", "qpid/common/metadata", "dijit/registry", "dojo/domReady!"],
    function (util, metadata, registry, win)
    {
        var fieldNames = ["storeUnderfullSize", "storeOverfullSize",
@@ -28,120 +28,6 @@ define(["qpid/common/util", "qpid/common
 
               registry.byId("editVirtualHost.storeUnderfullSize").set("regExpGen", util.numericOrContextVarRegexp);
               registry.byId("editVirtualHost.storeOverfullSize").set("regExpGen", util.numericOrContextVarRegexp);
-
-              var that = this;
-              this.permittedNodes = registry.byId("editVirtualHost.permittedNodes");
-              this.permittedNodesList = registry.byId("editVirtualHost.permittedNodesList");
-              this.permittedNodesList.on("change", function(value){that._changePermittedNodeList(value);});
-
-              // permitted node text field
-              this.permittedNode = registry.byId("editVirtualHost.permittedNode");
-              this.permittedNode.on("change", function(value){that._changePermittedNode(value);});
-
-              // add and remove buttons & click handlers
-              this.permittedNodeAddButton = registry.byId("editVirtualHost.permittedNodeAdd");
-              this.permittedNodeAddButton.set("disabled", true);
-              this.permittedNodeRemoveButton = registry.byId("editVirtualHost.permittedNodeRemove");
-              this.permittedNodeRemoveButton.set("disabled", true);
-              this.permittedNodeAddButton.on("click", function(e){that._clickAddPermittedNodeButton(e);});
-              this.permittedNodeRemoveButton.on("click", function(e){that._clickRemovePermittedNodeButton(e);});
-
-              var permittedNodes = data.data.permittedNodes;
-              for(var i=0; i<permittedNodes.length;i++)
-              {
-                 var host = permittedNodes[i];
-                 var newOption = this._addOption(host);
-                 // add new option to list
-                 this.permittedNodesList.containerNode.appendChild(newOption);
-              }
-           },
-           _clickAddPermittedNodeButton: function(e)
-           {
-             // check the text box is valid and not empty
-             if(this.permittedNode.isValid() &&
-                   this.permittedNode.value &&
-                   this.permittedNode.value != "")
-             {
-               // read value to add from text box
-               var newAddress = this.permittedNode.value;
-
-               // clear UI value
-               this.permittedNode.set("value", "");
-               this.permittedNodeAddButton.set("disabled", true);
-
-               //check entry not already present in list
-               var alreadyPresent = false;
-               var children = this.permittedNodesList.containerNode.children;
-               var i;
-               for (i = 0; i < children.length; i++)
-                 {
-                   var child = children.item(i);
-                   if (child.value == newAddress)
-                   {
-                     alreadyPresent = true;
-                     break;
-                   }
-                 }
-
-                 if (!alreadyPresent)
-                 {
-                   var newOption = this._addOption(newAddress);
-
-                   // add new option to list
-                   this.permittedNodesList.containerNode.appendChild(newOption);
-                   this._updatePermittedNodes();
-                 }
-             }
-           },
-           _clickRemovePermittedNodeButton: function(e)
-           {
-             var selectedValues = this.permittedNodesList.get("value");
-             var v;
-             for (v in selectedValues)
-             {
-               var children = this.permittedNodesList.containerNode.children;
-               var i;
-               for (i = 0; i < children.length; i++)
-               {
-                 var child = children.item(i);
-                 if (child.value == selectedValues[v])
-                 {
-                   this.permittedNodesList.containerNode.removeChild(child);
-                 }
-               }
-             }
-             this._updatePermittedNodes();
-             this.permittedNodeRemoveButton.set("disabled", true);
-           },
-           _addOption: function(newAddress)
-           {
-              // construct new option for list
-              var newOption = win.doc.createElement('option');
-              newOption.innerHTML = newAddress;
-              newOption.value = newAddress;
-              return newOption;
-           },
-           _changePermittedNodeList: function(value)
-           {
-               var hasSelection = this.permittedNodesList.get("value").length > 0;
-               this.permittedNodeRemoveButton.set("disabled", !hasSelection);
-           },
-           _changePermittedNode: function(value)
-           {
-               var fieldIsEmpty = (this.permittedNode.get("value") == "");
-               this.permittedNodeAddButton.set("disabled", fieldIsEmpty);
-               return true;
-           },
-           _updatePermittedNodes: function()
-           {
-              var values = [];
-              var children = this.permittedNodesList.containerNode.children;
-              for (var i = 0; i < children.length; i++)
-              {
-                 var child = children.item(i);
-                 values.push(children.item(i).value);
-              }
-              this.permittedNodes.set("value", values);
            }
        };
    }

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhost/bdb_ha/show.js Thu Aug 28 11:07:35 2014
@@ -28,7 +28,7 @@ define(["qpid/common/util", "dojo/query"
     function BDB(data)
     {
         util.buildUI(data.containerNode, data.parent, "virtualhost/bdb_ha/show.html", fields, this);
-        this["permittedNodes"]= query(".permittedNodes", data.containerNode)[0];
+
         this[localTransactionSynchronizationPolicy]= query("." + localTransactionSynchronizationPolicy, data.containerNode)[0];
         this[remoteTransactionSynchronizationPolicy]= query("."+ remoteTransactionSynchronizationPolicy, data.containerNode)[0];
     }
@@ -37,16 +37,6 @@ define(["qpid/common/util", "dojo/query"
     {
         util.updateUI(data, fields, this);
 
-        var permittedNodesMarkup = "";
-        if (data.permittedNodes)
-        {
-            for(var i=0;i<data.permittedNodes.length;i++)
-            {
-                permittedNodesMarkup+="<div>" + data.permittedNodes[i] + "</div>";
-            }
-        }
-        this["permittedNodes"].innerHTML = permittedNodesMarkup ;
-
         var localSyncPolicy =  data[localTransactionSynchronizationPolicy] ? data[localTransactionSynchronizationPolicy].toLowerCase() : "";
         var remoteSyncPolicy =  data[remoteTransactionSynchronizationPolicy] ? data[remoteTransactionSynchronizationPolicy].toLowerCase() : "";
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js Thu Aug 28 11:07:35 2014
@@ -67,7 +67,7 @@ define(["dojo/_base/xhr",
           this.addVirtualHostNodePermittedNodeRemoveButton.on("click", function(e){that._clickRemovePermittedNodeButton(e);});
 
           // This will contain the serialised form that will go to the server
-          this.addVirtualHostNodeVirtualhostBlueprint = registry.byId("addVirtualHostNode.virtualhostBlueprint");
+          this.addVirtualHostNodePermittedNodes = registry.byId("addVirtualHostNode.permittedNodes");
 
           registry.byId("addVirtualHostNode.groupName").set("regExpGen", util.nameOrContextVarRegexp);
         },
@@ -90,7 +90,7 @@ define(["dojo/_base/xhr",
             }
           }
 
-          this.addVirtualHostNodeVirtualhostBlueprint.set("value",json.stringify({"permittedNodes" : permittedNodes}));
+          this.addVirtualHostNodePermittedNodes.set("value", permittedNodes);
         },
         _changePermittedNodeList: function(value)
         {

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/edit.js
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/edit.js?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/edit.js (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/edit.js Thu Aug 28 11:07:35 2014
@@ -22,8 +22,9 @@ define(["qpid/common/util",
         "dijit/registry",
         "dojo/store/Memory",
         "dojo/data/ObjectStore",
+         "dojo/_base/window",
         "dojo/domReady!"],
-   function (util, registry, Memory, ObjectStore)
+   function (util, registry, Memory, ObjectStore, win)
    {
        var fields = [ "storePath", "name", "groupName", "address",
                       "designatedPrimary", "priority",  "quorumOverride"];
@@ -58,6 +59,120 @@ define(["qpid/common/util",
               }
               var store = new Memory({data :overrideData, idProperty: "id" });
               registry.byId("editVirtualHostNode.quorumOverride").set("store", new ObjectStore({objectStore: store}));
+
+              var that = this;
+              this.permittedNodes = registry.byId("editVirtualHostNode.permittedNodes");
+              this.permittedNodesList = registry.byId("editVirtualHostNode.permittedNodesList");
+              this.permittedNodesList.on("change", function(value){that._changePermittedNodeList(value);});
+
+              // permitted node text field
+              this.permittedNode = registry.byId("editVirtualHostNode.permittedNode");
+              this.permittedNode.on("change", function(value){that._changePermittedNode(value);});
+
+              // add and remove buttons & click handlers
+              this.permittedNodeAddButton = registry.byId("editVirtualHostNode.permittedNodeAdd");
+              this.permittedNodeAddButton.set("disabled", true);
+              this.permittedNodeRemoveButton = registry.byId("editVirtualHostNode.permittedNodeRemove");
+              this.permittedNodeRemoveButton.set("disabled", true);
+              this.permittedNodeAddButton.on("click", function(e){that._clickAddPermittedNodeButton(e);});
+              this.permittedNodeRemoveButton.on("click", function(e){that._clickRemovePermittedNodeButton(e);});
+
+              var permittedNodes = data.data.permittedNodes;
+              for(var i=0; i<permittedNodes.length;i++)
+              {
+                var host = permittedNodes[i];
+                var newOption = this._addOption(host);
+                // add new option to list
+                this.permittedNodesList.containerNode.appendChild(newOption);
+              }
+           },
+           _clickAddPermittedNodeButton: function(e)
+           {
+             // check the text box is valid and not empty
+             if(this.permittedNode.isValid() &&
+                   this.permittedNode.value &&
+                   this.permittedNode.value != "")
+             {
+               // read value to add from text box
+               var newAddress = this.permittedNode.value;
+
+               // clear UI value
+               this.permittedNode.set("value", "");
+               this.permittedNodeAddButton.set("disabled", true);
+
+               //check entry not already present in list
+               var alreadyPresent = false;
+               var children = this.permittedNodesList.containerNode.children;
+               var i;
+               for (i = 0; i < children.length; i++)
+                 {
+                   var child = children.item(i);
+                   if (child.value == newAddress)
+                   {
+                     alreadyPresent = true;
+                     break;
+                   }
+                 }
+
+                 if (!alreadyPresent)
+                 {
+                   var newOption = this._addOption(newAddress);
+
+                   // add new option to list
+                   this.permittedNodesList.containerNode.appendChild(newOption);
+                   this._updatePermittedNodes();
+                 }
+             }
+           },
+           _clickRemovePermittedNodeButton: function(e)
+           {
+             var selectedValues = this.permittedNodesList.get("value");
+             var v;
+             for (v in selectedValues)
+             {
+               var children = this.permittedNodesList.containerNode.children;
+               var i;
+               for (i = 0; i < children.length; i++)
+               {
+                 var child = children.item(i);
+                 if (child.value == selectedValues[v])
+                 {
+                   this.permittedNodesList.containerNode.removeChild(child);
+                 }
+               }
+             }
+             this._updatePermittedNodes();
+             this.permittedNodeRemoveButton.set("disabled", true);
+           },
+           _addOption: function(newAddress)
+           {
+              // construct new option for list
+              var newOption = win.doc.createElement('option');
+              newOption.innerHTML = newAddress;
+              newOption.value = newAddress;
+              return newOption;
+           },
+           _changePermittedNodeList: function(value)
+           {
+               var hasSelection = this.permittedNodesList.get("value").length > 0;
+               this.permittedNodeRemoveButton.set("disabled", !hasSelection);
+           },
+           _changePermittedNode: function(value)
+           {
+               var fieldIsEmpty = (this.permittedNode.get("value") == "");
+               this.permittedNodeAddButton.set("disabled", fieldIsEmpty);
+               return true;
+           },
+           _updatePermittedNodes: function()
+           {
+              var values = [];
+              var children = this.permittedNodesList.containerNode.children;
+              for (var i = 0; i < children.length; i++)
+              {
+                 var child = children.item(i);
+                 values.push(children.item(i).value);
+              }
+              this.permittedNodes.set("value", values);
            }
        };
    }

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/show.js
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/show.js?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/show.js (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/show.js Thu Aug 28 11:07:35 2014
@@ -90,7 +90,7 @@ define(["dojo/_base/xhr",
       this.designatedPrimaryContainer = findNode("designatedPrimaryContainer", containerNode);
       this.priorityContainer = findNode("priorityContainer", containerNode);
       this.quorumOverrideContainer = findNode("quorumOverrideContainer", containerNode);
-
+      this.permittedNodes = query(".permittedNodes", containerNode)[0];
       this.membersGridPanel = registry.byNode(query(".membersGridPanel", containerNode)[0]);
       this.membersGrid = new UpdatableStore([],
           findNode("groupMembers", containerNode),
@@ -158,6 +158,18 @@ define(["dojo/_base/xhr",
     BDBHA.prototype.update=function(data)
     {
       this.parent.editNodeButton.set("disabled", false);
+
+
+      var permittedNodesMarkup = "";
+      if (data.permittedNodes)
+      {
+        for(var i=0;i<data.permittedNodes.length;i++)
+        {
+            permittedNodesMarkup+="<div>" + data.permittedNodes[i] + "</div>";
+        }
+      }
+      this.permittedNodes.innerHTML = permittedNodesMarkup ;
+
       this.data = data;
       for(var i = 0; i < nodeFields.length; i++)
       {

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/edit.html Thu Aug 28 11:07:35 2014
@@ -45,45 +45,6 @@
         </div>
     </div>
 
-     <div class="formBox clear">
-        <fieldset>
-            <legend>Permitted group nodes</legend>
-            <div class="clear">
-                <div class="formLabel-labelCell tableContainer-labelCell">Permitted addresses*:</div>
-                <div class="formLabel-controlCell tableContainer-valueCell addPermittedNodeList">
-                    <select type="text" id="editVirtualHost.permittedNodesList"
-                            data-dojo-type="dijit/form/MultiSelect"
-                            data-dojo-props="
-                                      multiple: true,
-                                      name: 'permittedNodeList',
-                                      readOnly : 'true',
-                                      excluded: true,
-                                      title: 'Enter permitted nodes'">
-                    </select> <!-- must use closing tag rather than shorthand - dojo bug? -->
-                    <input type="hidden" id="editVirtualHost.permittedNodes"
-                           data-dojo-type="dijit/form/ValidationTextBox"
-                           name="permittedNodes"/>
-                </div>
-                <button data-dojo-type="dijit/form/Button" id="editVirtualHost.permittedNodeRemove" data-dojo-props="label: '-'" ></button>
-            </div>
-
-            <div class="clear"></div>
-            <div class="clear">
-                <div class="formLabel-labelCell tableContainer-labelCell">Address:</div>
-                <div class="formLabel-controlCell tableContainer-valueCell">
-                    <input type="text" id="editVirtualHost.permittedNode"
-                           data-dojo-type="dijit/form/ValidationTextBox"
-                           data-dojo-props="
-                                      name: 'permittedNode',
-                                      placeHolder: 'host:port',
-                                      intermediateChanges: true,
-                                      title: 'Enter address of node to be permitted into the group',
-                                      promptMessage: 'Address of node to be permitted into the group'" />
-                </div>
-                <button data-dojo-type="dijit/form/Button" id="editVirtualHost.permittedNodeAdd" data-dojo-props="label: '+'"></button>
-            </div>
-        </fieldset>
-    </div>
 
     <div class="clear"></div>
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/show.html
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/show.html?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/show.html (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhost/bdb_ha/show.html Thu Aug 28 11:07:35 2014
@@ -26,10 +26,6 @@
       <div class="formLabel-labelCell">Store underfull size:</div>
       <div><span class="storeUnderfullSize"></span> bytes</div>
   </div>
-  <div class="clear">
-      <div class="formLabel-labelCell">Permitted nodes:</div>
-      <div class="permittedNodes multiLineValue"></div>
-  </div>
   <div class="clear"></div>
   <br/>
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/add/newgroup/add.html Thu Aug 28 11:07:35 2014
@@ -91,10 +91,10 @@
         </fieldset>
     </div>
 
-    <input type="hidden" id="addVirtualHostNode.virtualhostBlueprint"
+    <input type="hidden" id="addVirtualHostNode.permittedNodes"
            data-dojo-type="dijit/form/ValidationTextBox"
-           data-dojo-props="name: 'virtualhostBlueprint'"
-           contextvar="true"/>
+           data-dojo-props="name: 'permittedNodes'"
+           />
 
     <input type="hidden" id="addVirtualHostNode.helperAddress"
            data-dojo-type="dijit/form/ValidationTextBox"

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/edit.html Thu Aug 28 11:07:35 2014
@@ -53,6 +53,47 @@
 
         </div>
     </div>
+
+    <div class="formBox clear">
+        <fieldset>
+            <legend>Permitted group nodes</legend>
+            <div class="clear">
+                <div class="formLabel-labelCell tableContainer-labelCell">Permitted addresses*:</div>
+                <div class="formLabel-controlCell tableContainer-valueCell addPermittedNodeList">
+                    <select type="text" id="editVirtualHostNode.permittedNodesList"
+                            data-dojo-type="dijit/form/MultiSelect"
+                            data-dojo-props="
+                                      multiple: true,
+                                      name: 'permittedNodeList',
+                                      readOnly : 'true',
+                                      excluded: true,
+                                      title: 'Enter permitted nodes'">
+                    </select> <!-- must use closing tag rather than shorthand - dojo bug? -->
+                    <input type="hidden" id="editVirtualHostNode.permittedNodes"
+                           data-dojo-type="dijit/form/ValidationTextBox"
+                           name="permittedNodes"/>
+                </div>
+                <button data-dojo-type="dijit/form/Button" id="editVirtualHostNode.permittedNodeRemove" data-dojo-props="label: '-'" ></button>
+            </div>
+
+            <div class="clear"></div>
+            <div class="clear">
+                <div class="formLabel-labelCell tableContainer-labelCell">Address:</div>
+                <div class="formLabel-controlCell tableContainer-valueCell">
+                    <input type="text" id="editVirtualHostNode.permittedNode"
+                           data-dojo-type="dijit/form/ValidationTextBox"
+                           data-dojo-props="
+                                      name: 'permittedNode',
+                                      placeHolder: 'host:port',
+                                      intermediateChanges: true,
+                                      title: 'Enter address of node to be permitted into the group',
+                                      promptMessage: 'Address of node to be permitted into the group'" />
+                </div>
+                <button data-dojo-type="dijit/form/Button" id="editVirtualHostNode.permittedNodeAdd" data-dojo-props="label: '+'"></button>
+            </div>
+        </fieldset>
+    </div>
+
     <div class="clear">
         <div class="formLabel-labelCell tableContainer-labelCell">Allow this node to operate solo: </div>
         <div class="formLabel-controlCell tableContainer-valueCell">

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/show.html
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/show.html?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/show.html (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/main/java/resources/virtualhostnode/bdb_ha/show.html Thu Aug 28 11:07:35 2014
@@ -35,6 +35,10 @@
       <div class="formLabel-labelCell">Address:</div>
       <div class="address">N/A</div>
   </div>
+  <div class="clear">
+    <div class="formLabel-labelCell">Permitted nodes:</div>
+    <div class="permittedNodes multiLineValue"></div>
+  </div>
   <div class="clear designatedPrimaryContainer">
     <div class="formLabel-labelCell">Allow this node to operate solo:</div>
     <div class="designatedPrimary">N/A</div>
@@ -49,6 +53,7 @@
           <span class="quorumOverride" >N/A</span>
       </div>
   </div>
+  <br/>
   <div class="clear"></div>
   <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Group nodes'" class="membersGridPanel">
       <div class="groupMembers"></div>

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java Thu Aug 28 11:07:35 2014
@@ -401,11 +401,9 @@ public class BDBHAVirtualHostNodeTest ex
         };
         node1.addChangeListener(listener);
 
-        BDBHAVirtualHost<?> host = (BDBHAVirtualHost<?>)node1.getVirtualHost();
-
         List<String> permittedNodes = new ArrayList<String>();
         permittedNodes.add(helperAddress);
-        host.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHost.PERMITTED_NODES, permittedNodes));
+        node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes));
 
         assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS));
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeTest.java Thu Aug 28 11:07:35 2014
@@ -32,7 +32,6 @@ import java.util.concurrent.atomic.Atomi
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.store.berkeleydb.EnvironmentFacade;
 import org.apache.qpid.test.utils.QpidTestCase;
 import org.apache.qpid.test.utils.TestFileUtils;
@@ -694,9 +693,10 @@ public class ReplicatedEnvironmentFacade
         ReplicationGroupListener listener = new NoopReplicationGroupListener()
         {
             @Override
-            public void onIntruderNode(ReplicationNode node)
+            public boolean onIntruderNode(ReplicationNode node)
             {
                 intruderLatch.countDown();
+                return true;
             }
         };
         ReplicatedEnvironmentFacade firstNode = createMaster(listener);
@@ -713,42 +713,6 @@ public class ReplicatedEnvironmentFacade
         assertTrue("Intruder node was not detected", intruderLatch.await(10, TimeUnit.SECONDS));
     }
 
-    public void testIntruderNodeDetectionOnMasterAndReplicaNodes() throws Exception
-    {
-        final CountDownLatch intruderLatch = new CountDownLatch(2);
-        ReplicationGroupListener listener = new NoopReplicationGroupListener()
-        {
-            @Override
-            public void onIntruderNode(ReplicationNode node)
-            {
-                intruderLatch.countDown();
-            }
-        };
-
-        ReplicatedEnvironmentFacade firstNode = createMaster(listener);
-        int replica1Port = getNextAvailable(TEST_NODE_PORT + 1);
-        String node2NodeHostPort = "localhost:" + replica1Port;
-        String nodeName2 = TEST_NODE_NAME + "_1";
-        ReplicatedEnvironmentFacade secondNode = createReplica(nodeName2, node2NodeHostPort, listener);
-
-        Set<String> permittedNodes = new HashSet<String>();
-        permittedNodes.add("localhost:" + TEST_NODE_PORT);
-        permittedNodes.add(nodeName2);
-        firstNode.setPermittedNodes(permittedNodes);
-
-        int counter = 0;
-        while(secondNode.getPermittedNodes().isEmpty() && counter < 100)
-        {
-            counter++;
-            Thread.sleep(50);
-        }
-        assertEquals("Permitted nodes are not set on a replica", permittedNodes, secondNode.getPermittedNodes());
-
-        int intruderPort = getNextAvailable(replica1Port+ 1);
-        createIntruder("intruder", "localhost:" + intruderPort);
-        assertTrue("Intruder node was not detected", intruderLatch.await(10, TimeUnit.SECONDS));
-    }
-
     private void createIntruder(String nodeName, String node1NodeHostPort)
     {
         File environmentPathFile = new File(_storePath, nodeName);
@@ -872,9 +836,10 @@ public class ReplicatedEnvironmentFacade
         }
 
         @Override
-        public void onIntruderNode(ReplicationNode node)
+        public boolean onIntruderNode(ReplicationNode node)
         {
             LOGGER.warn("Intruder node " + node);
+            return true;
         }
 
         @Override

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java Thu Aug 28 11:07:35 2014
@@ -300,6 +300,7 @@ public class BDBHAVirtualHostNodeOperati
 
         reset(_eventLogger);
 
+        node2Attributes.put(BDBHAVirtualHostNode.PERMITTED_NODES, node1Attributes.get(BDBHAVirtualHostNode.PERMITTED_NODES));
         node2 = (BDBHAVirtualHostNodeImpl)_helper.recoverHaVHN(node2.getId(), node2Attributes);
         _helper.assertNodeRole(node2, "REPLICA", "MASTER");
         waitForNodeDetachedField(remoteNode, false);

Modified: qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java Thu Aug 28 11:07:35 2014
@@ -54,7 +54,6 @@ import org.apache.qpid.server.model.Virt
 import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
 import org.apache.qpid.server.store.UnresolvedConfiguredObject;
 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.AbstractVirtualHostNode;
 import org.apache.qpid.test.utils.QpidTestCase;
@@ -240,7 +239,8 @@ public class BDBHAVirtualHostNodeTestHel
             iterationCounter++;
         }
         while(!inRole && iterationCounter<100);
-        assertTrue("Node " + node.getName() + " did not transit into role " + Arrays.toString(roleName), inRole);
+        assertTrue("Node " + node.getName() + " did not transit into role " + Arrays.toString(roleName)
+                + " Node role is " + node.getRole(), inRole);
     }
 
     public BDBHAVirtualHostNode<?> createAndStartHaVHN(Map<String, Object> attributes)  throws InterruptedException
@@ -280,6 +280,10 @@ public class BDBHAVirtualHostNodeTestHel
         node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress);
         node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, getMessageStorePath() + File.separator + nodeName);
         node1Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, helperNodeNode);
+        if (address.equals(helperAddress))
+        {
+            node1Attributes.put(BDBHAVirtualHostNode.PERMITTED_NODES, getPermittedNodes(ports));
+        }
 
         Map<String, String> context = new HashMap<String, String>();
         context.put(ReplicationConfig.REPLICA_ACK_TIMEOUT, "2 s");
@@ -287,7 +291,7 @@ public class BDBHAVirtualHostNodeTestHel
 
         if (ports != null)
         {
-            String bluePrint = getBlueprint(ports);
+            String bluePrint = getBlueprint();
             node1Attributes.put(AbstractVirtualHostNode.VIRTUALHOST_INITIAL_CONFIGURATION, bluePrint);
         }
 
@@ -296,16 +300,10 @@ public class BDBHAVirtualHostNodeTestHel
         return node1Attributes;
     }
 
-    public static String getBlueprint(int... ports) throws Exception
+    public static String getBlueprint() throws Exception
     {
-        List<String> permittedNodes = new ArrayList<String>();
-        for (int port:ports)
-        {
-            permittedNodes.add("localhost:" + port);
-        }
         Map<String,Object> bluePrint = new HashMap<>();
         bluePrint.put(VirtualHost.TYPE, BDBHAVirtualHostImpl.VIRTUAL_HOST_TYPE);
-        bluePrint.put(BDBHAVirtualHost.PERMITTED_NODES, permittedNodes);
 
         StringWriter writer = new StringWriter();
         ObjectMapper mapper = new ObjectMapper();
@@ -314,6 +312,16 @@ public class BDBHAVirtualHostNodeTestHel
         return writer.toString();
     }
 
+    public static List<String> getPermittedNodes(int[] ports)
+    {
+        List<String> permittedNodes = new ArrayList<String>();
+        for (int port:ports)
+        {
+            permittedNodes.add("localhost:" + port);
+        }
+        return permittedNodes;
+    }
+
     public void awaitForVirtualhost(final VirtualHostNode<?> node, final int wait)
     {
         long endTime = System.currentTimeMillis() + wait;

Modified: qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java Thu Aug 28 11:07:35 2014
@@ -226,7 +226,7 @@ public class BDBHAVirtualHostNodeRestTes
         assertEquals("Unexpected number of remote nodes on " + NODE2, 1, data.size());
     }
 
-    public void testIntruderBDBHAVHNNotAllowedNoConnect() throws Exception
+    public void testIntruderBDBHAVHNNotAllowedToConnect() throws Exception
     {
         createHANode(NODE1, _node1HaPort, _node1HaPort);
         assertNode(NODE1, _node1HaPort, _node1HaPort, NODE1);
@@ -304,6 +304,7 @@ public class BDBHAVirtualHostNodeRestTes
                 intruder.close();
             }
         }
+
         waitForAttributeChanged(_baseNodeRestUrl + NODE1, VirtualHostNode.STATE, State.ERRORED.name());
         waitForAttributeChanged(_baseNodeRestUrl + NODE3, VirtualHostNode.STATE, State.ERRORED.name());
     }
@@ -329,7 +330,11 @@ public class BDBHAVirtualHostNodeRestTes
         nodeData.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, NODE1);
         Map<String,String> context = new HashMap<>();
         nodeData.put(BDBHAVirtualHostNode.CONTEXT, context);
-        String bluePrint = GroupCreator.getBlueprint("localhost", _node1HaPort, _node2HaPort, _node3HaPort);
+        if (nodePort == helperPort)
+        {
+            nodeData.put(BDBHAVirtualHostNode.PERMITTED_NODES, GroupCreator.getPermittedNodes("localhost", _node1HaPort, _node2HaPort, _node3HaPort));
+        }
+        String bluePrint = GroupCreator.getBlueprint();
         context.put(AbstractVirtualHostNode.VIRTUALHOST_BLUEPRINT_CONTEXT_VAR, bluePrint);
         return nodeData;
     }

Modified: qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostRestTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostRestTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostRestTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostRestTest.java Thu Aug 28 11:07:35 2014
@@ -27,6 +27,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletResponse;
@@ -49,6 +50,8 @@ public class BDBHAVirtualHostRestTest ex
     private Object _nodeName;
     private String _virtualhostUrl;
     private String _bluePrint;
+    private List<String> _permittedNodes;
+    private String _address;
 
     @Override
     public void setUp() throws Exception
@@ -59,8 +62,9 @@ public class BDBHAVirtualHostRestTest ex
         _storeBaseDir = new File(TMP_FOLDER, "store-" + _hostName + "-" + System.currentTimeMillis());
         _nodeHaPort = getNextAvailable(getRestTestHelper().getHttpPort() + 1);
         _virtualhostUrl = "virtualhost/" + _nodeName + "/" + _hostName;
-        _bluePrint = GroupCreator.getBlueprint("localhost", _nodeHaPort);
-
+        _bluePrint = GroupCreator.getBlueprint();
+        _permittedNodes = GroupCreator.getPermittedNodes("localhost", _nodeHaPort);
+        _address = "localhost:" + _nodeHaPort;
         super.setUp();
     }
 
@@ -93,9 +97,11 @@ public class BDBHAVirtualHostRestTest ex
         nodeAttributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA");
         nodeAttributes.put(BDBHAVirtualHostNode.STORE_PATH, _storeBaseDir.getPath() + File.separator + _nodeName);
         nodeAttributes.put(BDBHAVirtualHostNode.GROUP_NAME, _hostName);
-        nodeAttributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + _nodeHaPort);
+        nodeAttributes.put(BDBHAVirtualHostNode.ADDRESS, _address);
         nodeAttributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, "localhost:" + _nodeHaPort);
         nodeAttributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, _nodeName);
+
+        nodeAttributes.put(BDBHAVirtualHostNode.PERMITTED_NODES, _permittedNodes);
         Map<String, String> context = new HashMap<String,String>();
         context.put(AbstractVirtualHostNode.VIRTUALHOST_BLUEPRINT_CONTEXT_VAR, _bluePrint);
 

Modified: qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupCreator.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupCreator.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupCreator.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/GroupCreator.java Thu Aug 28 11:07:35 2014
@@ -52,7 +52,6 @@ import org.apache.qpid.server.model.Plug
 import org.apache.qpid.server.model.Port;
 import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.model.VirtualHostNode;
-import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHost;
 import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl;
 import org.apache.qpid.server.virtualhostnode.AbstractVirtualHostNode;
 import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNode;
@@ -118,7 +117,8 @@ public class GroupCreator
             brokerPort = _testcase.getNextAvailable(bdbPort + 1);
         }
 
-        String bluePrintJson =  getBlueprint(_ipAddressOfBroker, bdbPorts);
+        String bluePrintJson =  getBlueprint();
+        List<String> permittedNodes = getPermittedNodes(_ipAddressOfBroker, bdbPorts);
 
         String helperName = null;
         for (Map.Entry<Integer,Integer> entry: _brokerPortToBdbPortMap.entrySet())
@@ -145,6 +145,7 @@ public class GroupCreator
             virtualHostNodeAttributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, getHelperHostPort());
             virtualHostNodeAttributes.put(BDBHAVirtualHostNode.TYPE, BDBHAVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE);
             virtualHostNodeAttributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, helperName);
+            virtualHostNodeAttributes.put(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes);
 
             Map<String, String> context = new HashMap<>();
             context.put(ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT, "2 s");
@@ -365,11 +366,6 @@ public class GroupCreator
         return _ipAddressOfBroker + ":" + _bdbHelperPort;
     }
 
-    public void setHelperHostPort(int bdbHelperPort)
-    {
-        _bdbHelperPort = bdbHelperPort;
-    }
-
     public int getBrokerPortNumberOfPrimary()
     {
         if (_numberOfNodes != 2)
@@ -406,21 +402,6 @@ public class GroupCreator
         }
     }
 
-    public void modifyClusterNodeBdbAddress(int brokerPortNumberToBeMoved, int newBdbPort)
-    {
-        TestBrokerConfiguration config = _testcase.getBrokerConfiguration(brokerPortNumberToBeMoved);
-        String nodeName = getNodeNameForNodeAt(_brokerPortToBdbPortMap.get(brokerPortNumberToBeMoved));
-
-        Map<String, Object> objectAttributes = config.getObjectAttributes(VirtualHostNode.class, nodeName);
-
-        String oldBdbHostPort = (String)objectAttributes.get(BDBHAVirtualHostNode.ADDRESS);
-        String[] oldHostAndPort = StringUtils.split(oldBdbHostPort, ":");
-        String oldHost = oldHostAndPort[0];
-        String newBdbHostPort = oldHost + ":" + newBdbPort;
-        config.setObjectAttribute(VirtualHostNode.class, nodeName, BDBHAVirtualHostNode.ADDRESS, newBdbHostPort);
-        config.setSaved(false);
-    }
-
     public String getNodeNameForBrokerPort(final int brokerPort)
     {
         return getNodeNameForNodeAt(_brokerPortToBdbPortMap.get(brokerPort));
@@ -491,20 +472,25 @@ public class GroupCreator
 
     public void awaitNodeToAttainRole(int localNodePort, int remoteNodePort, String desiredRole) throws Exception
     {
+        awaitNodeToAttainAttributeValue(localNodePort, remoteNodePort, BDBHARemoteReplicationNode.ROLE, desiredRole);
+    }
+
+    public void awaitNodeToAttainAttributeValue(int localNodePort, int remoteNodePort, String attributeName, String desiredValue) throws Exception
+    {
         final long startTime = System.currentTimeMillis();
         Map<String, Object> data = Collections.emptyMap();
 
-        while(!desiredRole.equals(data.get(BDBHARemoteReplicationNode.ROLE)) && (System.currentTimeMillis() - startTime) < 30000)
+        while(!desiredValue.equals(data.get(attributeName)) && (System.currentTimeMillis() - startTime) < 30000)
         {
-            LOGGER.debug("Awaiting node '" + getNodeNameForBrokerPort(remoteNodePort) + "' to transit into " + desiredRole + " role");
+            LOGGER.debug("Awaiting node '" + getNodeNameForBrokerPort(remoteNodePort) + "' to transit into " + desiredValue + " role");
             data = getNodeAttributes(localNodePort, remoteNodePort);
-            if (!desiredRole.equals(data.get(BDBHARemoteReplicationNode.ROLE)))
+            if (!desiredValue.equals(data.get(attributeName)))
             {
                 Thread.sleep(1000);
             }
         }
-        LOGGER.debug("Node '" + getNodeNameForBrokerPort(remoteNodePort) + "' role is " + data.get(BDBHARemoteReplicationNode.ROLE));
-        Assert.assertEquals("Node is in unexpected role", desiredRole, data.get(BDBHARemoteReplicationNode.ROLE));
+        LOGGER.debug("Node '" + getNodeNameForBrokerPort(remoteNodePort) + "' attribute  '" + attributeName + "' is " + data.get(attributeName));
+        Assert.assertEquals("Unexpected " + attributeName + " at " + localNodePort, desiredValue, data.get(attributeName));
     }
 
     public RestTestHelper createRestTestHelper(int brokerPort)
@@ -515,16 +501,10 @@ public class GroupCreator
         return helper;
     }
 
-    public static String getBlueprint(String hostName, int... ports) throws Exception
+    public static String getBlueprint() throws Exception
     {
-        List<String> permittedNodes = new ArrayList<String>();
-        for (int port:ports)
-        {
-            permittedNodes.add(hostName + ":" + port);
-        }
         Map<String,Object> bluePrint = new HashMap<>();
         bluePrint.put(VirtualHost.TYPE, BDBHAVirtualHostImpl.VIRTUAL_HOST_TYPE);
-        bluePrint.put(BDBHAVirtualHost.PERMITTED_NODES, permittedNodes);
 
         StringWriter writer = new StringWriter();
         ObjectMapper mapper = new ObjectMapper();
@@ -532,4 +512,14 @@ public class GroupCreator
         mapper.writeValue(writer, bluePrint);
         return writer.toString();
     }
+
+    public static List<String> getPermittedNodes(String hostName, int... ports)
+    {
+        List<String> permittedNodes = new ArrayList<String>();
+        for (int port: ports)
+        {
+            permittedNodes.add(hostName + ":" + port);
+        }
+        return permittedNodes;
+    }
 }

Modified: qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java?rev=1621116&r1=1621115&r2=1621116&view=diff
==============================================================================
--- qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java (original)
+++ qpid/branches/0.30/qpid/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java Thu Aug 28 11:07:35 2014
@@ -33,10 +33,15 @@ import javax.jms.Message;
 import javax.jms.MessageConsumer;
 import javax.jms.Session;
 
+import com.sleepycat.je.Durability;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.rep.ReplicatedEnvironment;
+import com.sleepycat.je.rep.ReplicationConfig;
 import org.apache.log4j.Logger;
 import org.apache.qpid.client.AMQConnection;
 import org.apache.qpid.jms.ConnectionListener;
 import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
 import org.apache.qpid.test.utils.TestUtils;
@@ -320,6 +325,47 @@ public class MultiNodeTest extends QpidB
         assertProducingConsuming(connection);
     }
 
+    public void testClusterCannotStartWithIntruder() throws Exception
+    {
+        int intruderPort = getNextAvailable(Collections.max(_groupCreator.getBdbPortNumbers()) + 1);
+        String nodeName = "intruder";
+        String nodeHostPort = _groupCreator.getIpAddressOfBrokerHost() + ":" + intruderPort;
+        File environmentPathFile = new File(System.getProperty("QPID_WORK"), intruderPort + "");
+        environmentPathFile.mkdirs();
+        ReplicationConfig replicationConfig = new ReplicationConfig(_groupCreator.getGroupName(), nodeName, nodeHostPort);
+        replicationConfig.setHelperHosts(_groupCreator.getHelperHostPort());
+        EnvironmentConfig envConfig = new EnvironmentConfig();
+        envConfig.setAllowCreate(true);
+        envConfig.setTransactional(true);
+        envConfig.setDurability(new Durability(Durability.SyncPolicy.SYNC, Durability.SyncPolicy.WRITE_NO_SYNC, Durability.ReplicaAckPolicy.SIMPLE_MAJORITY));
+
+        ReplicatedEnvironment intruder = null;
+        try
+        {
+            intruder = new ReplicatedEnvironment(environmentPathFile, replicationConfig, envConfig);
+        }
+        finally
+        {
+            if (intruder != null)
+            {
+                intruder.close();
+            }
+        }
+
+        for (int port: _groupCreator.getBrokerPortNumbersForNodes())
+        {
+            _groupCreator.awaitNodeToAttainAttributeValue(port, port, BDBHAVirtualHostNode.STATE, State.ERRORED.name());
+        }
+
+        _groupCreator.stopCluster();
+        _groupCreator.startCluster();
+
+        for (int port: _groupCreator.getBrokerPortNumbersForNodes())
+        {
+            _groupCreator.awaitNodeToAttainAttributeValue(port, port, BDBHAVirtualHostNode.STATE, State.ERRORED.name());
+        }
+    }
+
     private final class FailoverAwaitingListener implements ConnectionListener
     {
         private final CountDownLatch _failoverCompletionLatch = new CountDownLatch(1);



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