Bug-5486:Device disconnected handers on disconnection get closed in no particular... 22/36522/2
authorKamal Rameshan <kramesha@cisco.com>
Thu, 10 Mar 2016 18:36:33 +0000 (10:36 -0800)
committerKamal Rameshan <kramesha@cisco.com>
Mon, 28 Mar 2016 21:24:52 +0000 (21:24 +0000)
HashSets dont gaurantee any retrieval order. Further we dont need hashing as we just iterate through it.

Some log changes.

Change-Id: Ia31ce404e44e78bd0a3483e969da06119afe75f0
Signed-off-by: Kamal Rameshan <kramesha@cisco.com>
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/listener/SystemNotificationsListenerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java

index 2cd648acf5810ed4a172747dfb2f34297f56c491..1d99f8073fddbddf78c19527150f086ac4efad7c 100644 (file)
@@ -61,7 +61,7 @@ public class SystemNotificationsListenerImpl implements SystemNotificationsListe
 
                 if (ConnectionContext.CONNECTION_STATE.WORKING.equals(connectionContext.getConnectionState())) {
                     FeaturesReply features = connectionContext.getFeatures();
-                    LOG.debug("Switch Idle state occured, node={}|auxId={}", remoteAddress, features.getAuxiliaryId());
+                    LOG.info("Switch Idle state occurred, node={}|auxId={}", remoteAddress, features.getAuxiliaryId());
                     connectionContext.changeStateToTimeouting();
                     EchoInputBuilder builder = new EchoInputBuilder();
                     builder.setVersion(features.getVersion());
index 7a6889f763f5fa0ca2e735708029e3df4fa2409e..73636efb7d329cea39596f2d52f97b793ebc1dfe 100644 (file)
@@ -20,11 +20,8 @@ import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
 import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -135,7 +132,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     private final DeviceFlowRegistry deviceFlowRegistry;
     private final DeviceGroupRegistry deviceGroupRegistry;
     private final DeviceMeterRegistry deviceMeterRegistry;
-    private final Collection<DeviceContextClosedHandler> closeHandlers = new HashSet<>();
+    private final List<DeviceContextClosedHandler> closeHandlers = new ArrayList<>(4);
     private final PacketInRateLimiter packetInLimiter;
     private final MessageSpy messageSpy;
     private final ItemLifeCycleKeeper flowLifeCycleKeeper;
@@ -244,7 +241,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         LOG.trace("onClusterRoleChange {} for node:", role, deviceState.getNodeId());
         Preconditions.checkArgument(role != null);
         if (role.equals(oldRole)) {
-            LOG.debug("Demanded role change for device {} is not change OldRole: {}, NewRole {}", deviceState.getNodeId(), oldRole, role);
+            LOG.debug("Demanded role change for device {} is not changed. OldRole: {}, NewRole {}", deviceState.getNodeId(), oldRole, role);
             return Futures.immediateFuture(null);
         }
         if (OfpRole.BECOMEMASTER.equals(role)) {
@@ -591,9 +588,9 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         LOG.info("Closing transaction chain manager without cleaning inventory operational");
         transactionChainManager.close();
 
-        final LinkedList<DeviceContextClosedHandler> reversedCloseHandlers = new LinkedList<>(closeHandlers);
-        Collections.reverse(reversedCloseHandlers);
-        for (final DeviceContextClosedHandler deviceContextClosedHandler : reversedCloseHandlers) {
+        // call closeHandlers in the reverse order
+        for (int i=(closeHandlers.size() - 1); i >=0; i--) {
+            DeviceContextClosedHandler deviceContextClosedHandler = closeHandlers.get(i);
             deviceContextClosedHandler.onDeviceContextClosed(this);
         }
         closeHandlers.clear();
index fc159499cff4c61bb2cfe325d43b82da7a297d94..01cd3ab8c331163a23a57d111094af3c7160aec2 100644 (file)
@@ -366,7 +366,7 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
 
             @Override
             public void onFailure(final Throwable t) {
-                LOG.warn("Delete Node {} fail.", deviceState.getNodeId(), t);
+                LOG.warn("Delete Node {} failed.", deviceState.getNodeId(), t);
             }
         });
         return delFuture;
index 4681d12381d620c65f2612ef87d323523b72cb44..6e516aca726b4cefd01c6e3c3181037d67294ae0 100644 (file)
@@ -59,7 +59,7 @@ public class RpcManagerImpl implements RpcManager {
         deviceContext.addDeviceContextClosedHandler(this);
 
         if (OfpRole.BECOMEMASTER.equals(ofpRole)) {
-            LOG.info("Registering Openflow RPCs services for node:{}, role:{}", nodeId, ofpRole);
+            LOG.info("Registering Openflow Master RPCs for node:{}, role:{}", nodeId, ofpRole);
             MdSalRegistrationUtils.registerMasterServices(rpcContext, deviceContext, ofpRole);
 
         } else if(OfpRole.BECOMESLAVE.equals(ofpRole)) {
index 992275175eb9cdbb86a5d6dc1e55f46c4925029e..850a101ea317abf973ee924b0dc7a0cedd892cef 100644 (file)
@@ -166,8 +166,8 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
             scheduleNextPolling(deviceContext, statisticsContext, timeCounter);
             return;
         }
-        if (OfpRole.BECOMESLAVE.equals(deviceContext.getDeviceState().getRole())) {
-            LOG.debug("Role is SLAVE so we don't want to poll any stat for device: {}", deviceContext.getDeviceState().getNodeId());
+        if (!OfpRole.BECOMEMASTER.equals(deviceContext.getDeviceState().getRole())) {
+            LOG.debug("Role is not Master so we don't want to poll any stat for device: {}", deviceContext.getDeviceState().getNodeId());
             scheduleNextPolling(deviceContext, statisticsContext, timeCounter);
             return;
         }
index 0a4bb06eb13f28659143a8c0ebc2b7d8a24fa994..70101e553cd1ddf9db4da03d187a6255fe65b8f0 100644 (file)
@@ -15,19 +15,21 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-
-import java.math.BigInteger;
-import java.net.InetSocketAddress;
-import java.util.concurrent.atomic.AtomicLong;
-
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
+import com.google.common.util.concurrent.Uninterruptibles;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -507,4 +509,53 @@ public class DeviceContextImplTest {
         Assert.assertEquals(0, deviceContext.getDeviceMeterRegistry().getAllMeterIds().size());
 
     }
+
+    @Test
+    public void testDeviceDisconnectedHandlerExecutionOrder() throws Exception {
+        DeviceState deviceState = new DeviceStateImpl(mock(FeaturesReply.class), mock(NodeId.class));
+        DeviceContext deviceContext1 = new DeviceContextImpl(connectionContext, deviceState, dataBroker, timer,
+                messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, false);
+
+        deviceState.setValid(true);
+        when(txChainManager.shuttingDown()).thenReturn(Futures.immediateFuture((Void) null));
+
+        List<Integer> executionOrderList = new ArrayList<>(4);
+
+        DeviceContextClosedHandler deviceContextClosedHandler1 = new OrderedDeviceContextClosedHandler(1, executionOrderList);
+        DeviceContextClosedHandler deviceContextClosedHandler2 = new OrderedDeviceContextClosedHandler(2, executionOrderList);
+        DeviceContextClosedHandler deviceContextClosedHandler3 = new OrderedDeviceContextClosedHandler(3, executionOrderList);
+        DeviceContextClosedHandler deviceContextClosedHandler4 = new OrderedDeviceContextClosedHandler(4, executionOrderList);
+
+        deviceContext1.addDeviceContextClosedHandler(deviceContextClosedHandler1);
+        deviceContext1.addDeviceContextClosedHandler(deviceContextClosedHandler2);
+        deviceContext1.addDeviceContextClosedHandler(deviceContextClosedHandler3);
+        deviceContext1.addDeviceContextClosedHandler(deviceContextClosedHandler4);
+
+        deviceContext1.onDeviceDisconnected(connectionContext);
+
+        Uninterruptibles.sleepUninterruptibly(2, TimeUnit.SECONDS);
+
+        assertEquals("Not all DeviceContextClosedHandler got executed", 4, executionOrderList.size());
+        assertEquals("DeviceContextClosedHandler execution is not correct", 4, executionOrderList.get(0).intValue());
+        assertEquals("DeviceContextClosedHandler execution is not correct", 3, executionOrderList.get(1).intValue());
+        assertEquals("DeviceContextClosedHandler execution is not correct", 2, executionOrderList.get(2).intValue());
+        assertEquals("DeviceContextClosedHandler execution is not correct", 1, executionOrderList.get(3).intValue());
+    }
+
+    private class OrderedDeviceContextClosedHandler implements DeviceContextClosedHandler {
+
+        private final int order;
+        private final List<Integer> executionOrderList;
+
+        public OrderedDeviceContextClosedHandler(int order, List<Integer> executionOrderList ) {
+
+            this.order = order;
+            this.executionOrderList = executionOrderList;
+        }
+
+        @Override
+        public void onDeviceContextClosed(DeviceContext deviceContext) {
+            executionOrderList.add(order);
+        }
+    }
 }