Merge "Bug 4957: OF Role processing changes"
authormichal rehak <mirehak@cisco.com>
Wed, 2 Mar 2016 16:46:56 +0000 (16:46 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 2 Mar 2016 16:46:56 +0000 (16:46 +0000)
16 files changed:
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistratorUtils.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImplTest.java

index b0d09e14f7ca8009785214d9cb1c06e197c311f9..71cc8d60293623956b1c8bc7852822a46b00852f 100644 (file)
@@ -11,7 +11,6 @@ import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 
 /**
  * Created by kramesha on 9/12/15.
@@ -20,35 +19,10 @@ public interface RoleContext extends RoleChangeListener, RequestContextStack {
 
     void setTxLockOwned(boolean txLockOwned);
 
-    void promoteStateToWorking();
-
-    OfpRole getPropagatingRole();
-
-    void setPropagatingRole(OfpRole propagatingRole);
-
-    /** available states the {@link RoleContext} can exist in */
-    enum ROLE_CONTEXT_STATE {
-        /**
-         * before consequences of first entity ownership election are completely settled
-         * (lock acquired, data written, role propagated onto device)
-         */
-        STARTING,
-        /**
-         * state between
-         * <ul>
-         * <li>first entity ownership election settled</li>
-         * <li>and device disconnected or {@link DeviceContext#close()} invoked</li>
-         * </ul>
-         */
-        WORKING,
-        /** after {@link DeviceContext#close()} invoked */
-        TEARING_DOWN
-    }
-
     /**
      * Initialization method is responsible for a registration of
-     * {@link org.opendaylight.controller.md.sal.common.api.clustering.Entity}
-     * and listen for notification from service. {@link Future} returned object is used primary
+     * {@link org.opendaylight.controller.md.sal.common.api.clustering.Entity} and listen for notification from service.
+     * {@link Future} returned object is used primary
      * for new connection initialization phase where we have to wait for actual Role.
      * The {@link Future} has to be canceled if device is in disconnected state or when
      * {@link org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService} returns
@@ -73,7 +47,5 @@ public interface RoleContext extends RoleChangeListener, RequestContextStack {
 
     DeviceContext getDeviceContext();
 
-    ROLE_CONTEXT_STATE getState();
-
     boolean isTxLockOwned();
 }
index f7848a92639bb7d8dc28f9de79e32514e693bdc6..7925e9da81bdb3eb1ea429158ebdc84c542d5ecb 100644 (file)
@@ -22,4 +22,9 @@ public interface RpcContext extends RequestContextStack, AutoCloseable {
 
     <S extends RpcService> S lookupRpcService(Class<S> serviceClass);
     <S extends RpcService> void unregisterRpcServiceImplementation(Class<S> serviceClass);
+
+    void registerStatCompatibilityServices();
+
+    @Override
+    void close();
 }
index d5b1cf8874a88f62d61a737e846fdb4149cb7471..a7c74d618c5981d8fffe2e977cc9e8d2c675b81c 100644 (file)
@@ -176,12 +176,13 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, isStatisticsPollingOff);
         rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota);
 
-        // CM -> DM -> Role -> SM -> RPC -> DM
+        // CM -> DM -> SM -> RPC -> Role -> DM
         connectionManager.setDeviceConnectedHandler(deviceManager);
-        deviceManager.setDeviceInitializationPhaseHandler(roleManager);
-        roleManager.setDeviceInitializationPhaseHandler(statisticsManager);
+        deviceManager.setDeviceInitializationPhaseHandler(statisticsManager);
         statisticsManager.setDeviceInitializationPhaseHandler(rpcManager);
-        rpcManager.setDeviceInitializationPhaseHandler(deviceManager);
+        rpcManager.setDeviceInitializationPhaseHandler(roleManager);
+        roleManager.setDeviceInitializationPhaseHandler(deviceManager);
+
         rpcManager.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
         rpcManager.setNotificationPublishService(notificationPublishService);
 
index 70bd4532cce3e29254d2b34225474eca487ae99f..70de1190aa69736d31f1456ab2ba85dfea826cd7 100644 (file)
@@ -247,20 +247,22 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         }
         if (OfpRole.BECOMEMASTER.equals(role)) {
             if (!deviceState.deviceSynchronized()) {
-                LOG.debug("Setup Device Ctx {} for Master Role", getDeviceState().getNodeId());
+                //TODO: no necessary code for yet - it needs for initialization phase only
+                LOG.debug("Setup Empty TxManager {} for initialization phase", getDeviceState().getNodeId());
                 transactionChainManager.activateTransactionManager();
                 return Futures.immediateCheckedFuture(null);
             }
             /* Relevant for no initial Slave-to-Master scenario in cluster */
             return asyncClusterRoleChange(role);
+
         } else if (OfpRole.BECOMESLAVE.equals(role)) {
-            if (rpcContext != null) {
+            if (null != rpcContext) {
                 MdSalRegistratorUtils.registerSlaveServices(rpcContext, role);
             }
             return transactionChainManager.deactivateTransactionManager();
         } else {
             LOG.warn("Unknown OFCluster Role {} for Node {}", role, deviceState.getNodeId());
-            if (rpcContext != null) {
+            if (null != rpcContext) {
                 MdSalRegistratorUtils.unregisterServices(rpcContext);
             }
             return transactionChainManager.deactivateTransactionManager();
@@ -289,7 +291,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
                 new AsyncFunction<Optional<FlowCapableNode>, Void>() {
                     @Override
                     public ListenableFuture<Void> apply(final Optional<FlowCapableNode> input) throws Exception {
-                        if (!input.isPresent() || input.get().getTable().isEmpty()) {
+                        if (!input.isPresent() || input.get().getTable() != null || input.get().getTable().isEmpty()) {
                             /* Last master close fail scenario so we would like to activate TxManager */
                             LOG.debug("Operational DS for Device {} has to be replaced", deviceState.getNodeId());
                             getDeviceState().setDeviceSynchronized(false);
@@ -322,12 +324,18 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
                     return null;
                 }
                 LOG.debug("Get Initial Device {} information is successful", getDeviceState().getNodeId());
-                if (null != getRpcContext()) {
+                getDeviceState().setDeviceSynchronized(true);
+                transactionChainManager.activateTransactionManager();
+                //TODO: This is relevant for slave to master scenario make verify
+                if (null != rpcContext) {
                     MdSalRegistratorUtils.registerMasterServices(getRpcContext(), DeviceContextImpl.this, role);
+                    getRpcContext().registerStatCompatibilityServices();
+                } else {
+                    LOG.warn("No RpcCtx on deviceCtx: {}, cannot register services", this);
+                    // TODO : can we stay without RPCs or we need to call DeviceCtx.close ?
                 }
-                getDeviceState().setDeviceSynchronized(true);
+                initialSubmitTransaction();
                 getDeviceState().setStatisticsPollingEnabledProp(true);
-                transactionChainManager.activateTransactionManager();
                 return null;
             }
         });
@@ -556,20 +564,20 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
                 @Override
                 public void onSuccess(final Void result) {
-                    LOG.info("TxChain {} was shutdown successfull.", deviceState.getNodeId());
+                    LOG.info("TxChain {} was shutdown successfull.", getDeviceState().getNodeId());
                     tearDownClean();
                 }
 
                 @Override
                 public void onFailure(final Throwable t) {
-                    LOG.warn("Shutdown TxChain {} fail.", deviceState.getNodeId(), t);
+                    LOG.warn("Shutdown TxChain {} fail.", getDeviceState().getNodeId(), t);
                     tearDownClean();
                 }
             });
         }
     }
 
-    synchronized void tearDownClean() {
+    protected void tearDownClean() {
         LOG.info("Closing transaction chain manager without cleaning inventory operational");
         Preconditions.checkState(!deviceState.isValid());
         transactionChainManager.close();
index ca2567b091ef905af56b7cfb2f38984ec5261b5d..a614509d8f769a67c7dbe03fe3541edef6a108f1 100644 (file)
@@ -7,18 +7,17 @@
  */
 package org.opendaylight.openflowplugin.impl.device;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import io.netty.util.HashedWheelTimer;
 import java.util.Collections;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
-import io.netty.util.HashedWheelTimer;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
@@ -150,8 +149,8 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         final DeviceContext deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker,
                 hashedWheelTimer, messageIntelligenceAgency, outboundQueueProvider, translatorLibrary, switchFeaturesMandatory);
 
+        Verify.verify(deviceContexts.putIfAbsent(connectionContext.getNodeId(), deviceContext) == null, "DeviceCtx still not closed.");
         deviceContext.addDeviceContextClosedHandler(this);
-        Verify.verify(deviceContexts.putIfAbsent(connectionContext.getNodeId(), deviceContext) == null);
 
         ((ExtensionConverterProviderKeeper) deviceContext).setExtensionConverterProvider(extensionConverterProvider);
         deviceContext.setNotificationService(notificationService);
index b178f66b5607a8ec1a983a52e3f764a165b94cbc..23a7485982ac99742f20ba184c1dce0e4f184255 100644 (file)
@@ -99,7 +99,7 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable
      * transactions. Call this method for MASTER role only.
      */
     public void activateTransactionManager() {
-        LOG.trace("activateTransactionManager for node {} transaction submit is set to {}", deviceState.getNodeId());
+        LOG.trace("activateTransactionManager for node {} transaction submit is set to {}", deviceState.getNodeId(), this.submitIsEnabled);
         synchronized (txLock) {
             if (TransactionChainManagerStatus.SLEEPING.equals(transactionChainManagerStatus)) {
                 LOG.debug("Transaction Factory create {}", deviceState.getNodeId());
index c125f030371e136ebf1a6aeb64eacde187f1fcee..78eb72402d30a2b08a8489be9f0e2d0e0290e9b9 100644 (file)
@@ -14,6 +14,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.JdkFutureAdapters;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -63,9 +64,7 @@ public class RoleContextImpl implements RoleContext {
 
     private final Semaphore mainCandidateGuard = new Semaphore(1, true);
     private final Semaphore txCandidateGuard = new Semaphore(1, true);
-    private volatile ROLE_CONTEXT_STATE state;
     private volatile boolean txLockOwned;
-    private volatile OfpRole propagatingRole;
 
     public RoleContextImpl(final DeviceContext deviceContext, final EntityOwnershipService entityOwnershipService,
                            final Entity entity, final Entity txEnitity) {
@@ -79,11 +78,32 @@ public class RoleContextImpl implements RoleContext {
 
     @Override
     public void initialization() throws CandidateAlreadyRegisteredException {
-        state = ROLE_CONTEXT_STATE.STARTING;
-        LOG.debug("Initialization requestOpenflowEntityOwnership for entity {}", entity);
-        entityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity);
-        LOG.debug("RoleContextImpl : Candidate registered with ownership service for device :{}",
-                deviceContext.getPrimaryConnectionContext().getNodeId().getValue());
+        LOG.debug("Initialization RoleContext for Node {}", deviceContext.getDeviceState().getNodeId());
+        final AsyncFunction<RpcResult<SetRoleOutput>, Void> initFunction = new AsyncFunction<RpcResult<SetRoleOutput>, Void>() {
+            @Override
+            public ListenableFuture<Void> apply(final RpcResult<SetRoleOutput> input) throws Exception {
+                LOG.debug("Initialization request OpenflowEntityOwnership for entity {}", entity);
+                getDeviceState().setRole(OfpRole.BECOMESLAVE);
+                entityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity);
+                LOG.debug("RoleContextImpl : Candidate registered with ownership service for device :{}", deviceContext
+                        .getPrimaryConnectionContext().getNodeId().getValue());
+                return Futures.immediateFuture(null);
+            }
+        };
+        final ListenableFuture<Void> roleChange = sendRoleChangeToDevice(OfpRole.BECOMESLAVE, initFunction);
+        Futures.addCallback(roleChange, new FutureCallback<Void>() {
+
+            @Override
+            public void onSuccess(final Void result) {
+                LOG.debug("Initial RoleContext for Node {} is successful", deviceContext.getDeviceState().getNodeId());
+            }
+
+            @Override
+            public void onFailure(final Throwable t) {
+                LOG.warn("Initial RoleContext for Node {} fail", deviceContext.getDeviceState().getNodeId(), t);
+                deviceContext.close();
+            }
+        });
     }
 
     @Override
@@ -103,38 +123,16 @@ public class RoleContextImpl implements RoleContext {
         LOG.debug("Role change received from ownership listener from {} to {} for device:{}", oldRole, newRole,
                 deviceContext.getPrimaryConnectionContext().getNodeId());
 
-
-        final AsyncFunction<RpcResult<SetRoleOutput>, Void> roleChangeRpcFunction = new AsyncFunction<RpcResult<SetRoleOutput>, Void>() {
+        final AsyncFunction<RpcResult<SetRoleOutput>, Void> roleChangeFunction = new AsyncFunction<RpcResult<SetRoleOutput>, Void>() {
             @Override
             public ListenableFuture<Void> apply(final RpcResult<SetRoleOutput> setRoleOutputRpcResult) throws Exception {
-                LOG.debug("Rolechange {} successful made on switch :{}", newRole, deviceContext.getDeviceState().getNodeId());
-                final ListenableFuture<Void> nextStepFuture;
-                switch (state) {
-                case STARTING:
-                    if (OfpRole.BECOMESLAVE.equals(newRole)) {
-                        getDeviceState().setRole(newRole);
-                        nextStepFuture = Futures.immediateFuture(null);
-                    } else if (OfpRole.BECOMEMASTER.equals(newRole)) {
-                        nextStepFuture = deviceContext.onClusterRoleChange(oldRole, newRole);
-                    } else {
-                        nextStepFuture = Futures.immediateFuture(null);
-                    }
-
-                    break;
-                case WORKING:
-                    nextStepFuture = deviceContext.onClusterRoleChange(oldRole, newRole);
-                    break;
-                //case TEARING_DOWN:
-                default:
-                    nextStepFuture = Futures.immediateFuture(null);
-                    break;
-                }
-
-                return nextStepFuture;
+                LOG.debug("Role change {} successful made on switch :{}", newRole, deviceContext.getDeviceState()
+                        .getNodeId());
+                getDeviceState().setRole(newRole);
+                return deviceContext.onClusterRoleChange(oldRole, newRole);
             }
         };
-
-        return sendRoleChangeToDevice(newRole, roleChangeRpcFunction);
+        return sendRoleChangeToDevice(newRole, roleChangeFunction);
     }
 
     @Override
@@ -151,7 +149,6 @@ public class RoleContextImpl implements RoleContext {
             LOG.debug("Closing EntityOwnershipCandidateRegistration for {}", entity);
             entityOwnershipCandidateRegistration.close();
         }
-        promoteStateToTearingDown();
     }
 
     @Override
@@ -213,11 +210,6 @@ public class RoleContextImpl implements RoleContext {
         return txCandidateGuard;
     }
 
-    @Override
-    public ROLE_CONTEXT_STATE getState() {
-        return state;
-    }
-
     @Override
     public boolean isTxLockOwned() {
         return txLockOwned;
@@ -228,25 +220,6 @@ public class RoleContextImpl implements RoleContext {
         this.txLockOwned = txLockOwned;
     }
 
-    private void promoteStateToTearingDown() {
-        state = ROLE_CONTEXT_STATE.TEARING_DOWN;
-    }
-
-    @Override
-    public void promoteStateToWorking() {
-        state = ROLE_CONTEXT_STATE.WORKING;
-    }
-
-    @Override
-    public OfpRole getPropagatingRole() {
-        return propagatingRole;
-    }
-
-    @Override
-    public void setPropagatingRole(final OfpRole propagatingRole) {
-        this.propagatingRole = propagatingRole;
-    }
-
     private ListenableFuture<Void> sendRoleChangeToDevice(final OfpRole newRole, final AsyncFunction<RpcResult<SetRoleOutput>, Void> function) {
         LOG.debug("Send new Role {} to Device {}", newRole, deviceContext.getDeviceState().getNodeId());
         final Future<RpcResult<SetRoleOutput>> setRoleOutputFuture;
index 3ed9c45390a94cdd79a508e318b0421ebe6906af..57683dafd14379cea00b34980a09412c6b2210d4 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
-import com.google.common.util.concurrent.AsyncFunction;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -40,7 +39,6 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitia
 import org.opendaylight.openflowplugin.api.openflow.role.RoleChangeListener;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
-import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.slf4j.Logger;
@@ -81,17 +79,18 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
     @Override
     public void onDeviceContextLevelUp(@CheckForNull final DeviceContext deviceContext) throws Exception {
         LOG.debug("RoleManager called for device:{}", deviceContext.getPrimaryConnectionContext().getNodeId());
-
         final RoleContext roleContext = new RoleContextImpl(deviceContext, entityOwnershipService,
                 makeEntity(deviceContext.getDeviceState().getNodeId()),
                 makeTxEntity(deviceContext.getDeviceState().getNodeId()));
+
+        Verify.verify(contexts.putIfAbsent(roleContext.getEntity(), roleContext) == null, "RoleCtx for master Node {} is still not closed.", deviceContext.getDeviceState().getNodeId());
+        Verify.verify(!txContexts.containsKey(roleContext.getTxEntity()),
+                "RoleCtx for master Node {} is still not closed. TxEntity was not unregistered yet.", deviceContext.getDeviceState().getNodeId());
+
         // if the device context gets closed (mostly on connection close), we would need to cleanup
         deviceContext.addDeviceContextClosedHandler(this);
-        final RoleContext previousContext = contexts.putIfAbsent(roleContext.getEntity(), roleContext);
-        Verify.verify(previousContext == null,
-                "RoleCtx for master Node {} is still not close.", deviceContext.getDeviceState().getNodeId());
-
         roleContext.initialization();
+        deviceInitializationPhaseHandler.onDeviceContextLevelUp(deviceContext);
     }
 
     void getRoleContextLevelUp(final DeviceContext deviceContext) {
@@ -150,7 +149,6 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
                     if (!txContexts.containsKey(roleContext.getTxEntity())) {
                         try {
                             txContexts.putIfAbsent(roleContext.getTxEntity(), roleContext);
-                            roleContext.setPropagatingRole(OfpRole.BECOMEMASTER);
                             roleContext.setupTxCandidate();
                             // we'd like to wait for registration response
                             return;
@@ -218,56 +216,32 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
         final DeviceContext deviceContext = roleContext.getDeviceContext();
         final NodeId nodeId = roleContext.getDeviceState().getNodeId();
 
-        if (!roleContext.getDeviceState().isValid()
-                && RoleContext.ROLE_CONTEXT_STATE.WORKING.equals(roleContext.getState())) {
-            LOG.debug("Node {} ownership changed during closing process", roleContext.getDeviceState().getNodeId());
-            roleContext.close();
-            txCandidateGuard.release();
-            return;
-        }
-
         if (!ownershipChange.wasOwner() && ownershipChange.isOwner()) {
             // SLAVE -> MASTER - acquired transition lock
             LOG.debug("Acquired tx-lock for entity {}", ownershipChange.getEntity());
             roleContext.setTxLockOwned(true);
             final OfpRole role = roleContext.getDeviceState().getRole();
-            Verify.verify(OfpRole.BECOMEMASTER.equals(roleContext.getPropagatingRole()),
+            /* SLAVE to MASTER scenario has wait for TxEntity LEADER before sending ROLE to Device */
+            Verify.verify(OfpRole.BECOMESLAVE.equals(role),
                     "Acquired tx-lock but current role = {}", role);
 
-            switch (roleContext.getState()) {
-                case STARTING:
-                    processingClosure = roleContext.onRoleChanged(OfpRole.BECOMESLAVE, OfpRole.BECOMEMASTER);
-                    // activate stats - accomplished automatically by chaging role in deviceState
-                    // collect initial dynamic data from device
-                    processingClosure = Futures.transform(processingClosure, new AsyncFunction<Void, Void>() {
-                        @Nullable
-                        @Override
-                        public ListenableFuture<Void> apply(@Nullable final Void aVoid) {
-                            deviceContext.getDeviceState().setRole(OfpRole.BECOMEMASTER);
-                            return DeviceInitializationUtils.initializeNodeInformation(
-                                    deviceContext, switchFeaturesMandatory);
-                        }
-                    });
-                    break;
-                case WORKING:
-                    // activate txChainManager, activate rpcs
-                    processingClosure = roleContext.onRoleChanged(OfpRole.BECOMESLAVE, OfpRole.BECOMEMASTER);
-                    // activate stats - accomplished automatically by chaging role in deviceState
-                    processingClosure = Futures.transform(processingClosure, new Function<Void, Void>() {
-                        @Nullable
-                        @Override
-                        public Void apply(@Nullable final Void aVoid) {
-                            deviceContext.getDeviceState().setRole(OfpRole.BECOMEMASTER);
-                            return null;
-                        }
-                    });
-                    break;
-                //case TEARING_DOWN:
-                default:
-                    //TODO: reconsider if there is really nothing to do when tearing down
-                    processingClosure = Futures.immediateFuture(null);
-                    break;
+            // activate txChainManager, activate rpcs
+            if (roleContext.getDeviceState().isValid()) {
+                processingClosure = roleContext.onRoleChanged(OfpRole.BECOMESLAVE, OfpRole.BECOMEMASTER);
+            } else {
+                // We are not able to send anything to device, but we need to handle closing state clearly
+                roleContext.close();
+                processingClosure = Futures.immediateFuture(null);
             }
+            // activate stats - accomplished automatically by changing role in deviceState
+            processingClosure = Futures.transform(processingClosure, new Function<Void, Void>() {
+                @Nullable
+                @Override
+                public Void apply(@Nullable final Void aVoid) {
+                    deviceContext.getDeviceState().setRole(OfpRole.BECOMEMASTER);
+                    return null;
+                }
+            });
         } else if (ownershipChange.wasOwner() && !ownershipChange.isOwner()) {
             // MASTER -> SLAVE - released tx-lock
             LOG.debug("Released tx-lock for entity {}", ownershipChange.getEntity());
@@ -286,29 +260,14 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
                     @Override
                     public void onSuccess(@Nullable final Void aVoid) {
                         // propagating role must be BECOMEMASTER in order to run this processing
-                        // removing it will disable redundand processing of BECOMEMASTER
-                        roleContext.setPropagatingRole(null);
-
+                        // removing it will disable redundant processing of BECOMEMASTER
                         txCandidateGuard.release();
-                        switch (roleContext.getState()) {
-                            case STARTING:
-                                LOG.debug("init steps protected by tx-lock for node {} are done.", nodeId);
-                                roleContext.promoteStateToWorking();
-                                getRoleContextLevelUp(deviceContext);
-                                break;
-                            case WORKING:
-                                LOG.debug("normal steps protected by tx-lock for node {} are done.", nodeId);
-                                break;
-                            case TEARING_DOWN:
-                                LOG.debug("teardown steps protected by tx-lock for node {} are done.", nodeId);
-                                break;
-                        }
                     }
 
                     @Override
                     public void onFailure(final Throwable throwable) {
-                        LOG.warn("Unexpected error for Node {}, state={}, txLock={} -> terminating device context",
-                                nodeId, roleContext.getState(), roleContext.isTxLockOwned(), throwable);
+                        LOG.warn("Unexpected error for Node {}, txLock={} -> terminating device context", nodeId,
+                                roleContext.isTxLockOwned(), throwable);
                         txCandidateGuard.release();
                         deviceContext.close();
                     }
@@ -336,8 +295,6 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
                     LOG.debug("Node {} is marked as LEADER", nodeId);
                     Verify.verify(txContexts.putIfAbsent(roleContext.getTxEntity(), roleContext) == null,
                             "RoleCtx for TxEntity {} master Node {} is still not closed.", roleContext.getTxEntity(), nodeId);
-                    roleContext.setPropagatingRole(OfpRole.BECOMEMASTER);
-
                     // try to register tx-candidate via ownership service
                     roleContext.setupTxCandidate();
                 } catch (final CandidateAlreadyRegisteredException e) {
@@ -346,7 +303,6 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
                     // withdraw context from map in order to have it as before
                     txContexts.remove(roleContext.getTxEntity(), roleContext);
                     // no more propagating any role - there is no txCandidate lock approaching
-                    roleContext.setPropagatingRole(null);
                     roleContext.getDeviceContext().close();
                 }
                 return null;
@@ -372,21 +328,12 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
             if (ownershipChange.wasOwner() && !ownershipChange.isOwner() && ownershipChange.hasOwner()) {
                 // MASTER -> SLAVE
                 rolePropagationFx = roleContext.onRoleChanged(oldRole, newRole);
-                if (RoleContext.ROLE_CONTEXT_STATE.WORKING.equals(roleContext.getState())) {
-                    txProcessCallback = makeTxEntitySuspendCallback(roleContext);
-                } else {
-                    txProcessCallback = null;
-                }
+                txProcessCallback = makeTxEntitySuspendCallback(roleContext);
             } else if (!ownershipChange.wasOwner() && ownershipChange.isOwner() && ownershipChange.hasOwner()) {
                 // SLAVE -> MASTER
                 txProcessCallback = makeTxEntitySetupCallback(roleContext);
-            } else if (!ownershipChange.wasOwner() && !ownershipChange.isOwner() && ownershipChange.hasOwner()) {
-                if (RoleContext.ROLE_CONTEXT_STATE.STARTING.equals(roleContext.getState())) {
-                    rolePropagationFx = roleContext.onRoleChanged(oldRole, newRole);
-                }
-                txProcessCallback = null;
             } else {
-                LOG.trace("Main candidate role change case not covered: {} -> {} .. NOOP", oldRole, newRole);
+                LOG.debug("Main candidate role change case not covered: {} -> {} .. NOOP", oldRole, newRole);
                 txProcessCallback = null;
             }
 
@@ -400,14 +347,13 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener {
                 public void onSuccess(@Nullable final Void aVoid) {
                     LOG.debug("Role of main candidate successfully propagated: {}, {} -> {}",
                             ownershipChange.getEntity(), oldRole, newRole);
-                    roleContext.setPropagatingRole(newRole);
                     mainCandidateGuard.release();
                 }
 
                 @Override
                 public void onFailure(final Throwable throwable) {
                     LOG.warn("Main candidate role propagation FAILED for entity: {}, {} -> {}",
-                            ownershipChange.getEntity(), oldRole, newRole);
+                            ownershipChange.getEntity(), oldRole, newRole, throwable);
                     mainCandidateGuard.release();
                     roleContext.getDeviceContext().close();
                 }
index b450077582f1238fc11ac25b8d23bdf75a1f1b1e..6299cacf6607d130053a8c6b4db488d36b14632d 100644 (file)
@@ -10,15 +10,16 @@ package org.opendaylight.openflowplugin.impl.rpc;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Semaphore;
-
+import java.util.concurrent.atomic.AtomicLong;
 import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.util.MdSalRegistratorUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.slf4j.Logger;
@@ -33,11 +34,17 @@ public class RpcContextImpl implements RpcContext {
 
     // TODO: add private Sal salBroker
     private final ConcurrentMap<Class<?>, RoutedRpcRegistration<?>> rpcRegistrations = new ConcurrentHashMap<>();
+    private final boolean isStatisticsRpcEnabled;
+    private final NotificationPublishService notificationPublishService;
 
-    public RpcContextImpl(final MessageSpy messageSpy, final RpcProviderRegistry rpcProviderRegistry, final DeviceContext deviceContext, final int maxRequests) {
-        this.messageSpy = messageSpy;
-        this.rpcProviderRegistry = rpcProviderRegistry;
+    public RpcContextImpl(final MessageSpy messageSpy, final RpcProviderRegistry rpcProviderRegistry, final DeviceContext deviceContext,
+ final int maxRequests, final boolean isStatisticsRpcEnabled,
+            final NotificationPublishService notificationPublishService) {
         this.deviceContext = Preconditions.checkNotNull(deviceContext);
+        this.messageSpy = Preconditions.checkNotNull(messageSpy);
+        this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
+        this.isStatisticsRpcEnabled = isStatisticsRpcEnabled;
+        this.notificationPublishService = notificationPublishService;
         tracker = new Semaphore(maxRequests, true);
     }
 
@@ -48,30 +55,26 @@ public class RpcContextImpl implements RpcContext {
     @Override
     public <S extends RpcService> void registerRpcServiceImplementation(final Class<S> serviceClass,
                                                                         final S serviceInstance) {
+        LOG.trace("Try to register service {} for device {}.", serviceClass, deviceContext.getDeviceState().getNodeInstanceIdentifier());
         if (! rpcRegistrations.containsKey(serviceClass)) {
             final RoutedRpcRegistration<S> routedRpcReg = rpcProviderRegistry.addRoutedRpcImplementation(serviceClass, serviceInstance);
             routedRpcReg.registerPath(NodeContext.class, deviceContext.getDeviceState().getNodeInstanceIdentifier());
             rpcRegistrations.put(serviceClass, routedRpcReg);
+            LOG.debug("Registration of service {} for device {}.", serviceClass, deviceContext.getDeviceState().getNodeInstanceIdentifier());
         }
-        LOG.debug("Registration of service {} for device {}.", serviceClass, deviceContext.getDeviceState().getNodeInstanceIdentifier());
+    }
 
-        if (serviceInstance instanceof ItemLifeCycleSource) {
-            // TODO: collect registration for selective unregistering in case of tearing down only one rpc
-            deviceContext.getItemLifeCycleSourceRegistry().registerLifeCycleSource((ItemLifeCycleSource) serviceInstance);
+    public void registerStatCompatibilityServices() {
+        if (isStatisticsRpcEnabled) {
+            MdSalRegistratorUtils.registerStatCompatibilityServices(RpcContextImpl.this, deviceContext,
+                    notificationPublishService, new AtomicLong());
         }
     }
 
     @Override
-    public <S extends RpcService> S lookupRpcService(Class<S> serviceClass) {
-        S service = null;
-        for (RoutedRpcRegistration<?> rpcRegistration : rpcRegistrations.values()) {
-            final RpcService rpcService = rpcRegistration.getInstance();
-            if (serviceClass.isInstance(rpcService)) {
-                service = (S) rpcService;
-                break;
-            }
-        }
-        return service;
+    public <S extends RpcService> S lookupRpcService(final Class<S> serviceClass) {
+        final RpcService rpcService = rpcRegistrations.get(serviceClass).getInstance();
+        return (S) rpcService;
     }
     /**
      * Unregisters all services.
@@ -86,6 +89,7 @@ public class RpcContextImpl implements RpcContext {
             LOG.debug("Closing RPC Registration of service {} for device {}.", rpcRegistration.getServiceType(),
                     deviceContext.getDeviceState().getNodeInstanceIdentifier());
         }
+        rpcRegistrations.clear();
     }
 
     @Override
@@ -97,11 +101,6 @@ public class RpcContextImpl implements RpcContext {
             LOG.info("Acquired semaphore for {}, available permits:{} ", deviceContext.getDeviceState().getNodeId(), tracker.availablePermits());
         }
 
-        final Long xid = deviceContext.reservedXidForDeviceMessage();
-        if (xid == null) {
-            LOG.error("Xid cannot be reserved for new RequestContext, node:{}", deviceContext.getDeviceState().getNodeId());
-        }
-
         return new AbstractRequestContext<T>(deviceContext.reservedXidForDeviceMessage()) {
             @Override
             public void close() {
@@ -115,11 +114,12 @@ public class RpcContextImpl implements RpcContext {
 
     @Override
     public <S extends RpcService> void unregisterRpcServiceImplementation(final Class<S> serviceClass) {
-        LOG.debug("Unregistration serviceClass {} for Node {}", serviceClass, deviceContext.getDeviceState().getNodeId());
+        LOG.trace("Try to unregister serviceClass {} for Node {}", serviceClass, deviceContext.getDeviceState().getNodeId());
         final RoutedRpcRegistration<?> rpcRegistration = rpcRegistrations.remove(serviceClass);
         if (rpcRegistration != null) {
             rpcRegistration.unregisterPath(NodeContext.class, deviceContext.getDeviceState().getNodeInstanceIdentifier());
             rpcRegistration.close();
+            LOG.debug("Unregistration serviceClass {} for Node {}", serviceClass, deviceContext.getDeviceState().getNodeId());
         }
     }
 }
index 67d08bb0a72c3d0fa2dc9e71d3e5eddf6e2dcd30..f95d5ff809878e0136f20b207ff04be397fd34ae 100644 (file)
@@ -7,9 +7,9 @@
  */
 package org.opendaylight.openflowplugin.impl.rpc;
 
+import com.google.common.base.Verify;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
+import java.util.concurrent.ConcurrentMap;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -28,7 +28,7 @@ public class RpcManagerImpl implements RpcManager {
     private final RpcProviderRegistry rpcProviderRegistry;
     private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
     private final int maxRequestsQuota;
-    private final ConcurrentHashMap<DeviceContext, RpcContext> contexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceContext, RpcContext> contexts = new ConcurrentHashMap<>();
     private boolean isStatisticsRpcEnabled;
     private NotificationPublishService notificationPublishService;
 
@@ -49,23 +49,18 @@ public class RpcManagerImpl implements RpcManager {
         final OfpRole ofpRole = deviceContext.getDeviceState().getRole();
 
         LOG.debug("Node:{}, deviceContext.getDeviceState().getRole():{}", nodeId, ofpRole);
+        final RpcContext rpcContext = new RpcContextImpl(deviceContext.getMessageSpy(), rpcProviderRegistry,
+                deviceContext, maxRequestsQuota, isStatisticsRpcEnabled, notificationPublishService);
 
-        RpcContext rpcContext = contexts.get(deviceContext);
-        if (rpcContext == null) {
-            rpcContext = new RpcContextImpl(deviceContext.getMessageSpy(), rpcProviderRegistry, deviceContext, maxRequestsQuota);
-            contexts.put(deviceContext, rpcContext);
-        }
-
+        Verify.verify(contexts.putIfAbsent(deviceContext, rpcContext) == null, "RpcCtx still not closed for node {}", nodeId);
         deviceContext.addDeviceContextClosedHandler(this);
 
+        //FIXME : propagate isStatisticsRpcEnabled to DeviceContext
+
         if (OfpRole.BECOMEMASTER.equals(ofpRole)) {
             LOG.info("Registering Openflow RPCs for node:{}, role:{}", nodeId, ofpRole);
             MdSalRegistratorUtils.registerMasterServices(rpcContext, deviceContext, ofpRole);
 
-            if (isStatisticsRpcEnabled) {
-                MdSalRegistratorUtils.registerStatCompatibilityServices(rpcContext, deviceContext,
-                        notificationPublishService, new AtomicLong());
-            }
         } else if(OfpRole.BECOMESLAVE.equals(ofpRole)) {
             // if slave, we need to de-register rpcs if any have been registered, in case of master to slave
             LOG.info("Unregistering RPC registration (if any) for slave role for node:{}", deviceContext.getDeviceState().getNodeId());
@@ -82,7 +77,10 @@ public class RpcManagerImpl implements RpcManager {
 
     @Override
     public void close() throws Exception {
-
+        for(final RpcContext ctx : contexts.values()) {
+            ctx.close();
+        }
+        contexts.clear();
     }
 
 
@@ -90,13 +88,8 @@ public class RpcManagerImpl implements RpcManager {
     public void onDeviceContextClosed(final DeviceContext deviceContext) {
         final RpcContext removedContext = contexts.remove(deviceContext);
         if (removedContext != null) {
-            try {
-                LOG.info("Unregistering rpcs for device context closure");
-                removedContext.close();
-            } catch (final Exception e) {
-                LOG.error("Exception while unregistering rpcs onDeviceContextClosed handler for node:{}. But continuing.",
-                        deviceContext.getDeviceState().getNodeId(), e);
-            }
+            LOG.info("Unregistering rpcs for device context closure");
+            removedContext.close();
         }
     }
     @Override
index 46ecf390ce3ca11c6ab8b71babc0f19bc80c79c4..65c7057ceeb0e18337850277527cd80abe8bc036 100644 (file)
@@ -72,7 +72,7 @@ public class StatisticsContextImpl implements StatisticsContext {
         statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService(this, deviceContext);
         itemLifeCycleListener = new ItemLifecycleListenerImpl(deviceContext);
         statListForCollectingInitialization();
-        deviceContext.setStatisticsContext(StatisticsContextImpl.this);
+        this.deviceContext.setStatisticsContext(StatisticsContextImpl.this);
     }
 
     @Override
@@ -267,16 +267,16 @@ public class StatisticsContextImpl implements StatisticsContext {
                     statisticsGatheringService, deviceContext, /*MultipartType.OFPMPMETER*/ multipartType) : emptyFuture;
         }
 
-        @VisibleForTesting
-        protected void setStatisticsGatheringService ( final StatisticsGatheringService statisticsGatheringService){
-            this.statisticsGatheringService = statisticsGatheringService;
-        }
+    @VisibleForTesting
+    protected void setStatisticsGatheringService(final StatisticsGatheringService statisticsGatheringService) {
+        this.statisticsGatheringService = statisticsGatheringService;
+    }
 
-        @VisibleForTesting
-        protected void setStatisticsGatheringOnTheFlyService ( final StatisticsGatheringOnTheFlyService
-        statisticsGatheringOnTheFlyService){
-            this.statisticsGatheringOnTheFlyService = statisticsGatheringOnTheFlyService;
-        }
+    @VisibleForTesting
+    protected void setStatisticsGatheringOnTheFlyService(final StatisticsGatheringOnTheFlyService
+                                                             statisticsGatheringOnTheFlyService) {
+        this.statisticsGatheringOnTheFlyService = statisticsGatheringOnTheFlyService;
+    }
 
         @Override
         public ItemLifecycleListener getItemLifeCycleListener () {
index 210ffe7274be270f5e3f70fc175d8d1c297788a5..bc2b4a33de60b1a8ac48b40ce21ecd618f6ac8aa 100644 (file)
@@ -20,12 +20,20 @@ import java.util.concurrent.TimeoutException;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timeout;
 import io.netty.util.TimerTask;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.CheckForNull;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
@@ -58,7 +66,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
 
     private HashedWheelTimer hashedWheelTimer;
 
-    private final ConcurrentHashMap<DeviceContext, StatisticsContext> contexts = new ConcurrentHashMap<>();
+    private final ConcurrentMap<DeviceContext, StatisticsContext> contexts = new ConcurrentHashMap<>();
 
     private static final long basicTimerDelay = 3000;
     private static long currentTimerDelay = basicTimerDelay;
@@ -89,6 +97,8 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
             hashedWheelTimer = deviceContext.getTimer();
         }
         final StatisticsContext statisticsContext = new StatisticsContextImpl(deviceContext, shuttingDownStatisticsPolling);
+
+        Verify.verify(contexts.putIfAbsent(deviceContext, statisticsContext) == null, "StatisticsCtx still not closed for Node {}",deviceContext.getDeviceState().getNodeId());
         deviceContext.addDeviceContextClosedHandler(this);
 
         if (shuttingDownStatisticsPolling) {
@@ -102,7 +112,6 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
             }
             scheduleNextPolling(deviceContext, statisticsContext, new TimeCounter());
         }
-        contexts.put(deviceContext, statisticsContext);
         deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext);
         deviceContext.getDeviceState().setDeviceSynchronized(true);
     }
index aee32aea5784269831b51cb1ea7e1b1fbb991c7e..7bf986bf20ffed68a8dad7466baabb417b0f217d 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.openflowplugin.impl.util;
 
-import java.util.concurrent.atomic.AtomicLong;
-
 import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.reflect.TypeToken;
@@ -105,7 +103,7 @@ public class MdSalRegistratorUtils {
         Preconditions.checkArgument(rpcContext != null);
         Preconditions.checkArgument(newRole != null);
         Verify.verify(OfpRole.BECOMESLAVE.equals(newRole), "Service call with bad Role {} we expect role BECOMESLAVE", newRole);
-
+        
         unregisterServices(rpcContext);
     }
 
index 9779f941327d5a57832a663dca39772081fe78a1..83f40861c66063b1cd72e7707594b12f199915c5 100644 (file)
@@ -21,7 +21,6 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
 import org.mockito.Matchers;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
@@ -106,7 +105,7 @@ public class RoleContextImplTest {
         when(deviceContext.getPrimaryConnectionContext().getFeatures()).thenReturn(featuresReply);
         when(deviceContext.getPrimaryConnectionContext().getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
         when(deviceContext.onClusterRoleChange(Matchers.<OfpRole>any(), Matchers.<OfpRole>any()))
-                .thenReturn(Futures.immediateFuture((Void) null));
+            .thenReturn(Futures.immediateFuture((Void) null));
 
         roleContext = new RoleContextImpl(deviceContext, entityOwnershipService, entity, txEntity);
         roleContext.initialization();
@@ -145,7 +144,7 @@ public class RoleContextImplTest {
         final ListenableFuture<Void> onRoleChanged = roleContext.onRoleChanged(oldRole, newRole);
         onRoleChanged.get(5, TimeUnit.SECONDS);
 
-        verify(deviceContext, Mockito.never()).onClusterRoleChange(oldRole, newRole);
+        verify(deviceContext).onClusterRoleChange(oldRole, newRole);
     }
 
     @Test
@@ -177,7 +176,6 @@ public class RoleContextImplTest {
                 .thenReturn(future);
 
         roleContext.setSalRoleService(salRoleService);
-        roleContext.promoteStateToWorking();
 
         final ListenableFuture<Void> onRoleChanged = roleContext.onRoleChanged(oldRole, newRole);
         onRoleChanged.get(5, TimeUnit.SECONDS);
index ee20b1e649e8ed054faf52e02119320c342d8092..cee4e6691611de54905c00e4426bc5a460852ddb 100644 (file)
@@ -15,6 +15,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
@@ -42,12 +43,14 @@ public class RpcContextImplTest {
     private DeviceContext deviceContext;
     @Mock
     private MessageSpy messageSpy;
+    @Mock
+    private NotificationPublishService notificationPublishService;
 
     private KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
 
     @Before
     public void setup() {
-        NodeId nodeId = new NodeId("openflow:1");
+        final NodeId nodeId = new NodeId("openflow:1");
         nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId));
 
         when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
@@ -61,16 +64,18 @@ public class RpcContextImplTest {
 
     @Test
     public void testStoreOrFail() throws Exception {
-        try (final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, deviceContext, 100)) {
-            RequestContext<?> requestContext = rpcContext.createRequestContext();
+        try (final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, deviceContext,
+                100, false, notificationPublishService)) {
+            final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNotNull(requestContext);
         }
     }
 
     @Test
     public void testStoreOrFailThatFails() throws Exception {
-        try (final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, deviceContext, 0)) {
-            RequestContext<?> requestContext = rpcContext.createRequestContext();
+        try (final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, deviceContext, 0,
+                false, notificationPublishService)) {
+            final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNull(requestContext);
         }
     }
index 9bd6caa8ab41e1a8b1eb7194c66a458198e02fc5..8f474c86e3b0712f47c42745e39bb0605ef16123 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -55,6 +56,8 @@ public class RpcManagerImplTest {
     private DeviceState deviceState;
     @Mock
     private ItemLifeCycleRegistry itemLifeCycleRegistry;
+    @Mock
+    private MessageSpy messageSpy;
 
     private KeyedInstanceIdentifier<Node, NodeKey> nodePath;
 
@@ -72,6 +75,7 @@ public class RpcManagerImplTest {
         Mockito.when(deviceContext.getDeviceState().getRole()).thenReturn(OfpRole.BECOMEMASTER);
         Mockito.when(deviceContext.getItemLifeCycleSourceRegistry()).thenReturn(itemLifeCycleRegistry);
         Mockito.when(deviceState.getNodeInstanceIdentifier()).thenReturn(nodePath);
+        Mockito.when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
     }
 
     @Test