Bug 5596 Change of start up services 29/42029/14
authorJozef Bacigal <jbacigal@cisco.com>
Tue, 19 Jul 2016 07:35:06 +0000 (09:35 +0200)
committerShuva Jyoti Kar <shuva.jyoti.kar@ericsson.com>
Mon, 15 Aug 2016 05:26:07 +0000 (05:26 +0000)
Change-Id: I6bae36251f4d01e6d851f8f09a976e790665ef20
Signed-off-by: Jozef Bacigal <jbacigal@cisco.com>
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.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/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImplTest.java

index 7215fa6ab34103f6b8921dec50367570ce72e363..657a06509435ef777d1ded1370addea320aff281 100644 (file)
@@ -240,7 +240,7 @@ public class OpenFlowPluginProviderImpl implements OpenFlowPluginProvider, OpenF
         statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, isStatisticsPollingOff, conductor, convertorManager);
         conductor.setSafelyManager(statisticsManager);
 
-        rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota, conductor);
+        rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota, extensionConverterManager, conductor, convertorManager);
         conductor.setSafelyManager(rpcManager);
 
         roleManager.addRoleChangeListener((RoleChangeListener) conductor);
index 587de817a7a88b85e376994536a0cccca87cdb33..34142de5675b5d839e3641bc6cc5a0301f90fb49 100644 (file)
@@ -92,10 +92,13 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
     private final LifecycleConductor conductor;
 
     public DeviceManagerImpl(@Nonnull final DataBroker dataBroker,
-                             final long globalNotificationQuota, final boolean switchFeaturesMandatory,
-                             final long barrierInterval, final int barrierCountLimit,
-                             final LifecycleConductor lifecycleConductor, boolean isNotificationFlowRemovedOff,
-                             final ConvertorExecutor convertorExecutor) {
+                             final long globalNotificationQuota,
+                             final boolean switchFeaturesMandatory,
+                             final long barrierInterval,
+                             final int barrierCountLimit,
+                             final LifecycleConductor lifecycleConductor,
+                             boolean isNotificationFlowRemovedOff,
+                            final ConvertorExecutor convertorExecutor) {
         this.switchFeaturesMandatory = switchFeaturesMandatory;
         this.globalNotificationQuota = globalNotificationQuota;
         this.isNotificationFlowRemovedOff = isNotificationFlowRemovedOff;
index b9e8d445a08e8bfeb6a1bc47f47d7e6523e7c557..b804f3128bea20f68c02a7178e3a6d8589fdcd06 100644 (file)
@@ -27,7 +27,7 @@ class LifecycleServiceImpl implements LifecycleService {
     private final RoleContext roleContext;
     private final StatisticsContext statContext;
 
-    public LifecycleServiceImpl(
+    LifecycleServiceImpl(
             final DeviceContext deviceContext,
             final RpcContext rpcContext,
             final RoleContext roleContext,
@@ -40,17 +40,29 @@ class LifecycleServiceImpl implements LifecycleService {
 
     @Override
     public void instantiateServiceInstance() {
-        LOG.info("Starting device context cluster services for node {}", this.deviceContext.getServiceIdentifier());
         try {
+
+            LOG.info("Starting device context cluster services for node {}", getIdentifier());
             this.deviceContext.startupClusterServices();
+
+            LOG.info("Starting statistics context cluster services for node {}", getIdentifier());
+            this.statContext.startupClusterServices();
+
+            LOG.info("Starting rpc context cluster services for node {}", getIdentifier());
+            this.rpcContext.startupClusterServices();
+
+            LOG.info("Starting role context cluster services for node {}", getIdentifier());
+            this.roleContext.startupClusterServices();
+
         } catch (ExecutionException | InterruptedException e) {
             LOG.warn("Cluster service {} was unable to start.", this.getIdentifier());
         }
-        LOG.info("Starting statistics context cluster services for node {}", this.deviceContext.getServiceIdentifier());
     }
 
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
+        statContext.stopClusterServices();
+        rpcContext.stopClusterServices();
         return deviceContext.stopClusterServices();
     }
 
index 87463cc6640d00a6ac889c3de8631dc38fc9e6d6..faf903906759b9146fc89ec1a9d29091c7ae2c71 100644 (file)
@@ -8,6 +8,12 @@
 package org.opendaylight.openflowplugin.impl.role;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.TimerTask;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
@@ -17,12 +23,20 @@ import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
 import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -214,4 +228,39 @@ class RoleContextImpl implements RoleContext {
         return this.deviceInfo;
     }
 
+    public void startupClusterServices() throws ExecutionException, InterruptedException {
+        sendRoleChangeToDevice(OfpRole.BECOMEMASTER).get();
+    }
+
+    @Override
+    public ListenableFuture<Void> stopClusterServices() {
+        return Futures.immediateFuture(null);
+    }
+
+    private ListenableFuture<RpcResult<SetRoleOutput>> sendRoleChangeToDevice(final OfpRole newRole) {
+        LOG.debug("Sending new role {} to device {}", newRole, deviceInfo.getNodeId());
+        final Future<RpcResult<SetRoleOutput>> setRoleOutputFuture;
+        final Short version = deviceInfo.getVersion();
+        if (null == version) {
+            LOG.debug("Device version is null");
+            return Futures.immediateFuture(null);
+        }
+        if (version < OFConstants.OFP_VERSION_1_3) {
+            LOG.debug("Device version not support ROLE");
+            return Futures.immediateFuture(null);
+        } else {
+            final SetRoleInput setRoleInput = (new SetRoleInputBuilder()).setControllerRole(newRole)
+                    .setNode(new NodeRef(DeviceStateUtil.createNodeInstanceIdentifier(deviceInfo.getNodeId()))).build();
+            setRoleOutputFuture = getSalRoleService().setRole(setRoleInput);
+            final TimerTask timerTask = timeout -> {
+                if (!setRoleOutputFuture.isDone()) {
+                    LOG.warn("New role {} was not propagated to device {} during 10 sec", newRole, deviceInfo.getNodeId());
+                    setRoleOutputFuture.cancel(true);
+                }
+            };
+            conductor.newTimeout(timerTask, 10, TimeUnit.SECONDS);
+        }
+        return JdkFutureAdapters.listenInPoolThread(setRoleOutputFuture);
+    }
+
 }
index 1a8cb845f1452b8760ae60369c48f0bf7b4e0fe8..759f1858b9ae668d1869f4c93ba41ff622e55869 100644 (file)
@@ -10,19 +10,26 @@ package org.opendaylight.openflowplugin.impl.rpc;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterators;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Iterator;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Semaphore;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.XidSequencer;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.util.MdSalRegistrationUtils;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -44,21 +51,30 @@ class RpcContextImpl implements RpcContext {
     private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
     private CONTEXT_STATE state;
     private final DeviceInfo deviceInfo;
+    private final DeviceContext deviceContext;
+    private final ExtensionConverterProvider extensionConverterProvider;
+    private final ConvertorExecutor convertorExecutor;
 
     RpcContextImpl(final DeviceInfo deviceInfo,
                    final RpcProviderRegistry rpcProviderRegistry,
                    final XidSequencer xidSequencer,
                    final MessageSpy messageSpy,
                    final int maxRequests,
-                   final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier) {
+                   final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier,
+                   final DeviceContext deviceContext,
+                   final ExtensionConverterProvider extensionConverterProvider,
+                   final ConvertorExecutor convertorExecutor) {
         this.xidSequencer = Preconditions.checkNotNull(xidSequencer);
         this.messageSpy = Preconditions.checkNotNull(messageSpy);
         this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
         this.nodeInstanceIdentifier = nodeInstanceIdentifier;
 
         tracker = new Semaphore(maxRequests, true);
+        this.extensionConverterProvider = extensionConverterProvider;
         setState(CONTEXT_STATE.WORKING);
         this.deviceInfo = deviceInfo;
+        this.deviceContext = deviceContext;
+        this.convertorExecutor = convertorExecutor;
     }
 
     /**
@@ -180,4 +196,15 @@ class RpcContextImpl implements RpcContext {
     public DeviceInfo getDeviceInfo() {
         return this.deviceInfo;
     }
+
+    @Override
+    public void startupClusterServices() throws ExecutionException, InterruptedException {
+        MdSalRegistrationUtils.registerServices(this, deviceContext, extensionConverterProvider, convertorExecutor);
+    }
+
+    @Override
+    public ListenableFuture<Void> stopClusterServices() {
+        MdSalRegistrationUtils.unregisterServices(this);
+        return Futures.immediateFuture(null);
+    }
 }
index a09a395c2a51d4195f4958508dcc15f456467fa9..7849fc76874676aef32a7b0619f41efb2a56381b 100644 (file)
@@ -23,6 +23,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTermin
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,16 +37,21 @@ public class RpcManagerImpl implements RpcManager {
     private final int maxRequestsQuota;
     private final ConcurrentMap<DeviceInfo, RpcContext> contexts = new ConcurrentHashMap<>();
     private boolean isStatisticsRpcEnabled;
-
+    private final ExtensionConverterProvider extensionConverterProvider;
     private final LifecycleConductor conductor;
+    private final ConvertorExecutor convertorExecutor;
 
     public RpcManagerImpl(
             final RpcProviderRegistry rpcProviderRegistry,
             final int quotaValue,
-            final LifecycleConductor lifecycleConductor) {
+            ExtensionConverterProvider extensionConverterProvider,
+            final LifecycleConductor lifecycleConductor,
+            final ConvertorExecutor convertorExecutor) {
         this.rpcProviderRegistry = rpcProviderRegistry;
         maxRequestsQuota = quotaValue;
+        this.extensionConverterProvider = extensionConverterProvider;
         this.conductor = lifecycleConductor;
+        this.convertorExecutor = convertorExecutor;
     }
 
     @Override
@@ -63,7 +70,10 @@ public class RpcManagerImpl implements RpcManager {
                 deviceContext,
                 deviceContext.getMessageSpy(),
                 maxRequestsQuota,
-                deviceInfo.getNodeInstanceIdentifier());
+                deviceInfo.getNodeInstanceIdentifier(),
+                deviceContext,
+                extensionConverterProvider,
+                convertorExecutor);
 
         Verify.verify(contexts.putIfAbsent(deviceInfo, rpcContext) == null, "RpcCtx still not closed for node {}", deviceInfo.getNodeId());
 
index fccc2bfc4b1c61d705ed254abda1f90c9d7d639a..9e4f3db7d22e50a543c352dd3fb98f46bd3d3d02 100644 (file)
@@ -23,6 +23,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
@@ -405,4 +406,15 @@ class StatisticsContextImpl implements StatisticsContext {
     public DeviceInfo getDeviceInfo() {
         return this.deviceInfo;
     }
+
+    @Override
+    public void startupClusterServices() throws ExecutionException, InterruptedException {
+        this.statListForCollectingInitialization();
+        this.initialGatherDynamicData();
+    }
+
+    @Override
+    public ListenableFuture<Void> stopClusterServices() {
+        return Futures.immediateFuture(null);
+    }
 }
index a88fa53f319ee030360182b21f0feecd67640137..c871b5513395741e90392feb4ef9ca2a4332452f 100644 (file)
@@ -28,6 +28,8 @@ import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.XidSequencer;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 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;
@@ -62,6 +64,10 @@ public class RpcContextImplTest {
     private TestRpcService serviceInstance;
     @Mock
     private DeviceInfo deviceInfo;
+    @Mock
+    private ExtensionConverterProvider extensionConverterProvider;
+    @Mock
+    private ConvertorExecutor convertorExecutor;
 
     private KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
 
@@ -80,7 +86,10 @@ public class RpcContextImplTest {
                 deviceContext,
                 messageSpy,
                 MAX_REQUESTS,
-                nodeInstanceIdentifier);
+                nodeInstanceIdentifier,
+                deviceContext,
+                extensionConverterProvider,
+                convertorExecutor);
 
         when(rpcProviderRegistry.addRoutedRpcImplementation(TestRpcService.class, serviceInstance)).thenReturn(routedRpcReg);
 
@@ -94,7 +103,10 @@ public class RpcContextImplTest {
                 xidSequencer,
                 messageSpy,
                 100,
-                nodeInstanceIdentifier)) {
+                nodeInstanceIdentifier,
+                deviceContext,
+                extensionConverterProvider,
+                convertorExecutor)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNotNull(requestContext);
         }
@@ -108,7 +120,10 @@ public class RpcContextImplTest {
                 xidSequencer,
                 messageSpy,
                 0,
-                nodeInstanceIdentifier)) {
+                nodeInstanceIdentifier,
+                deviceContext,
+                extensionConverterProvider,
+                convertorExecutor)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNull(requestContext);
         }
@@ -122,7 +137,10 @@ public class RpcContextImplTest {
                 deviceContext,
                 messageSpy,
                 100,
-                nodeInstanceIdentifier)) {
+                nodeInstanceIdentifier,
+                deviceContext,
+                extensionConverterProvider,
+                convertorExecutor)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNotNull(requestContext);
             requestContext.close();
index 415d443580ff2ec95fafa459a1c29e9437be2890..0918e4e43159a52f82353b6ce19bd0f22a23603d 100644 (file)
@@ -36,6 +36,8 @@ import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor
 import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
@@ -80,6 +82,10 @@ public class RpcManagerImplTest {
     private ConcurrentMap<DeviceInfo, RpcContext> contexts;
     @Mock
     private DeviceInfo deviceInfo;
+    @Mock
+    private ExtensionConverterProvider extensionConverterProvider;
+    @Mock
+    private ConvertorExecutor convertorExecutor;
 
     @Rule
     public ExpectedException expectedException = ExpectedException.none();
@@ -91,7 +97,7 @@ public class RpcManagerImplTest {
     @Before
     public void setUp() {
         final NodeKey nodeKey = new NodeKey(nodeId);
-        rpcManager = new RpcManagerImpl(rpcProviderRegistry, QUOTA_VALUE, conductor);
+        rpcManager = new RpcManagerImpl(rpcProviderRegistry, QUOTA_VALUE, extensionConverterProvider, conductor, convertorExecutor);
         rpcManager.setDeviceInitializationPhaseHandler(deviceINitializationPhaseHandler);
 
         GetFeaturesOutput featuresOutput = new GetFeaturesOutputBuilder()