Bug 5596 Created lifecycle service 68/41968/12
authorJozef Bacigal <jbacigal@cisco.com>
Mon, 18 Jul 2016 13:46:41 +0000 (15:46 +0200)
committerShuva Jyoti Kar <shuva.jyoti.kar@ericsson.com>
Sat, 13 Aug 2016 13:20:08 +0000 (13:20 +0000)
- created general API for cluster services
- changed OFPContext and OFPManager API

Change-Id: I6506a1dcc328e98aca21446d46b8dd09445a4b61
Signed-off-by: Jozef Bacigal <jbacigal@cisco.com>
26 files changed:
openflowplugin-api/pom.xml
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java [new file with mode: 0644]
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java
openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionContextImpl.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/lifecycle/LifecycleServiceImpl.java [new file with mode: 0644]
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/MdSalRegistrationUtils.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java [new file with mode: 0644]
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java
openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java

index 99ccd9023710b66b3382f6d489f1d508dadce923..fc41f6eb9db4daa7d2d58b5370a1a965d036f59c 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-singleton-common-api</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
index 9e8227e5b5845b4e8b6350016ae9aaec9a6bd75b..7bd11c9be76fe8463c413cee753c61c70b67396f 100644 (file)
@@ -7,6 +7,13 @@
  */
 package org.opendaylight.openflowplugin.api.openflow;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RejectedExecutionException;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+
 /**
  * General API for all OFP Context
  */
@@ -17,23 +24,45 @@ public interface OFPContext {
     }
 
     /**
-     * distinguished device context states
+     * Context state
      */
     enum CONTEXT_STATE {
-        /**
-         * initial phase
-         */
+        /* Initialization phase, context not yet fully initialized */
         INITIALIZATION,
-        /**
-         * standard phase
-         */
+        /* Standard working phase everything is fine */
         WORKING,
-        /**
-         * termination phase
-         */
+        /* Termination phase context is being shutting down */
         TERMINATION
     }
 
+    /**
+     * @return actual context state
+     */
     CONTEXT_STATE getState();
 
+    /**
+     * Starting cluster services for context becoming master
+     */
+    default void startupClusterServices() throws ExecutionException, InterruptedException {
+        throw new InterruptedException("Cannot start abstract service, check implementation of cluster services");
+    }
+
+    /**
+     * About to stop services in cluster not master anymore or going down
+     * @return Future most of services need time to be closed
+     */
+    default ListenableFuture<Void> stopClusterServices(){
+        return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services"));
+    }
+
+    /**
+     * @return cluster singleton service identifier
+     */
+    ServiceGroupIdentifier getServiceIdentifier();
+
+    /**
+     * @return device info
+     */
+    DeviceInfo getDeviceInfo();
+
 }
index c5baf45cf6dade2d5cfdbc072af403f4efb421ee..f0d0f0086f67c016bf6361e60cca2c3eac104ea7 100644 (file)
@@ -37,11 +37,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
  * a request to the switch will fail immediately, with proper error indication.
  * </p>
  */
-public interface DeviceContext extends AutoCloseable,
+public interface DeviceContext extends
+        OFPContext,
+        AutoCloseable,
         DeviceReplyProcessor,
         TxFacade,
         XidSequencer,
-        OFPContext,
         DeviceRegistry{
 
     /**
@@ -51,15 +52,13 @@ public interface DeviceContext extends AutoCloseable,
 
     /**
      * Method add auxiliary connection contexts to this context representing single device connection.
-     *
-     * @param connectionContext
+     * @param connectionContext new connection context
      */
     void addAuxiliaryConnectionContext(ConnectionContext connectionContext);
 
     /**
      * Method removes auxiliary connection context from this context representing single device connection.
-     *
-     * @param connectionContext
+     * @param connectionContext connection which need to be removed
      */
     void removeAuxiliaryConnectionContext(ConnectionContext connectionContext);
 
@@ -70,8 +69,6 @@ public interface DeviceContext extends AutoCloseable,
      */
     DeviceState getDeviceState();
 
-    DeviceInfo getDeviceInfo();
-
     /**
      * Method has to close TxManager ASAP we are notified about Closed Connection
      * @return sync. future for Slave and MD-SAL completition for Master
@@ -79,16 +76,12 @@ public interface DeviceContext extends AutoCloseable,
     ListenableFuture<Void> shuttingDownDataStoreTransactions();
 
     /**
-     * Method provides current devices connection context.
-     *
-     * @return
+     * @return current devices connection context
      */
     ConnectionContext getPrimaryConnectionContext();
 
     /**
-     * Method provides current devices auxiliary connection contexts.
-     *
-     * @return
+     * @return current devices auxiliary connection contexts
      */
     ConnectionContext getAuxiliaryConnectiobContexts(BigInteger cookie);
 
@@ -133,5 +126,8 @@ public interface DeviceContext extends AutoCloseable,
 
     @Override
     void close();
+
+    void setSwitchFeaturesMandatory(boolean switchFeaturesMandatory);
+
 }
 
index 75b0f13266ba99dc5bf189875a93c577794459b2..9272c919b223b312d63f5766b89a15b338240d2c 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.openflowplugin.api.openflow.device;
 
 import java.math.BigInteger;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 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;
@@ -39,4 +40,9 @@ public interface DeviceInfo {
      */
     BigInteger getDatapathId();
 
+    /**
+     * @return clustering service identifier
+     */
+    ServiceGroupIdentifier getServiceIdentifier();
+
 }
diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java
new file mode 100644 (file)
index 0000000..72f84dd
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.api.openflow.lifecycle;
+
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+
+/**
+ * Service for starting or stopping all services in plugin in cluster
+ */
+public interface LifecycleService extends ClusterSingletonService {
+}
index ea3d2435993e031b1842666b9e17f73e888ab82b..263bc51bc34efb9b1c016cabd751ad708dcf31a1 100644 (file)
@@ -10,8 +10,10 @@ package org.opendaylight.openflowplugin.api.openflow.role;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
 import org.opendaylight.openflowplugin.api.openflow.OFPContext;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
 
 /**
@@ -64,12 +66,6 @@ public interface RoleContext extends  RequestContextStack, AutoCloseable, OFPCon
      */
     Entity getTxEntity();
 
-    /**
-     * Actual nodeId
-     * @return
-     */
-    DeviceInfo getDeviceInfo();
-
     /**
      * Returns true if main entity is registered
      * @return
index bc851df3b64418560240a4003d06ccb90a541377..c1f73ed0e6b83159e847ea449338ad289a67f997 100644 (file)
@@ -8,16 +8,21 @@
 package org.opendaylight.openflowplugin.api.openflow.role;
 
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.RoleChangeListener;
 
 /**
- * Created by kramesha on 8/31/15.
+ * Manager for role change on device
  */
-public interface RoleManager extends DeviceLifecycleSupervisor, DeviceInitializationPhaseHandler, AutoCloseable,
-        DeviceTerminationPhaseHandler, OFPManager {
+public interface RoleManager extends
+        DeviceLifecycleSupervisor,
+        DeviceInitializationPhaseHandler,
+        AutoCloseable,
+        DeviceTerminationPhaseHandler,
+        OFPManager {
     String ENTITY_TYPE = "openflow";
     String TX_ENTITY_TYPE = "ofTransaction";
 
index 0339f8435edc07a7bcb7110c1c9a32690c6a9128..d191527081a47de4551773dedb6da9be8454abd6 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.openflowplugin.api.openflow.rpc;
 
 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceLifecycleSupervisor;
 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
index 22e975231a5edc7a410878546c6602819c3c4ac7..d681cfde8fe36601b14b516127793cc83ef667c4 100644 (file)
@@ -12,6 +12,8 @@ import com.google.common.util.concurrent.ListenableFuture;
 import io.netty.util.Timeout;
 import java.util.Optional;
 import org.opendaylight.openflowplugin.api.openflow.OFPContext;
+import org.opendaylight.openflowplugin.api.openflow.OFPManager;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
 
index d81d47a80dd1e8286ed80e423222972824621e0e..aebb3fe3d3221034a1291f9f1c7688aedf0d6657 100644 (file)
@@ -17,6 +17,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
@@ -249,6 +250,7 @@ public class ConnectionContextImpl implements ConnectionContext {
         final private KeyedInstanceIdentifier<Node, NodeKey> nodeII;
         final private Short version;
         final private BigInteger datapathId;
+        final private ServiceGroupIdentifier serviceGroupIdentifier;
 
         DeviceInfoImpl(
                 final NodeId nodeId,
@@ -259,6 +261,7 @@ public class ConnectionContextImpl implements ConnectionContext {
             this.nodeII = nodeII;
             this.version = version;
             this.datapathId = datapathId;
+            this.serviceGroupIdentifier = ServiceGroupIdentifier.create(this.nodeId.getValue());
         }
 
         @Override
@@ -281,6 +284,11 @@ public class ConnectionContextImpl implements ConnectionContext {
             return datapathId;
         }
 
+        @Override
+        public ServiceGroupIdentifier getServiceIdentifier() {
+            return this.serviceGroupIdentifier;
+        }
+
         @Override
         public boolean equals(Object o) {
             if (this == o) {
index fd2e77c773382ab73d5d155261e4637868f7bf45..80cb770d653747541416feaf0aff3a8d5e55b039 100644 (file)
@@ -18,12 +18,14 @@ import java.math.BigInteger;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
 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.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
@@ -62,6 +64,8 @@ import org.opendaylight.openflowplugin.impl.registry.flow.DeviceFlowRegistryImpl
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
 import org.opendaylight.openflowplugin.impl.registry.group.DeviceGroupRegistryImpl;
 import org.opendaylight.openflowplugin.impl.registry.meter.DeviceMeterRegistryImpl;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.ExperimenterMessageFromDevBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -99,7 +103,7 @@ import org.slf4j.LoggerFactory;
 /**
  *
  */
-public class DeviceContextImpl implements DeviceContext, ExtensionConverterProviderKeeper {
+public class DeviceContextImpl implements DeviceContext, ExtensionConverterProviderKeeper{
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceContextImpl.class);
 
@@ -132,26 +136,26 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     private ExtensionConverterProvider extensionConverterProvider;
     private final DeviceManager deviceManager;
 
+    private boolean switchFeaturesMandatory;
     private final DeviceInfo deviceInfo;
-
-    private volatile CONTEXT_STATE contextState;
-
-
-    @VisibleForTesting
-    DeviceContextImpl(@Nonnull final ConnectionContext primaryConnectionContext,
-                      @Nonnull final DeviceState deviceState,
-                      @Nonnull final DataBroker dataBroker,
-                      @Nonnull final LifecycleConductor conductor,
-                      @Nonnull final OutboundQueueProvider outboundQueueProvider,
-                      @Nonnull final TranslatorLibrary translatorLibrary,
-                      final DeviceManager manager) {
+    private final ConvertorExecutor convertorExecutor;
+    private volatile CONTEXT_STATE state;
+
+    public DeviceContextImpl(@Nonnull final ConnectionContext primaryConnectionContext,
+                             @Nonnull final DeviceState deviceState,
+                             @Nonnull final DataBroker dataBroker,
+                             @Nonnull final LifecycleConductor conductor,
+                             @Nonnull final OutboundQueueProvider outboundQueueProvider,
+                             @Nonnull final TranslatorLibrary translatorLibrary,
+                             final DeviceManager manager,
+                             @Nonnull final DeviceInfo deviceInfo,
+                             final ConvertorExecutor convertorExecutor) {
         this.primaryConnectionContext = Preconditions.checkNotNull(primaryConnectionContext);
         this.deviceState = Preconditions.checkNotNull(deviceState);
         this.dataBroker = Preconditions.checkNotNull(dataBroker);
         Preconditions.checkNotNull(conductor);
         this.outboundQueueProvider = Preconditions.checkNotNull(outboundQueueProvider);
-        deviceInfo = primaryConnectionContext.getDeviceInfo();
-        this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo, conductor);
+        this.transactionChainManager = new TransactionChainManager(dataBroker, deviceInfo , conductor);
         auxiliaryConnectionContexts = new HashMap<>();
         deviceFlowRegistry = new DeviceFlowRegistryImpl(dataBroker, deviceInfo.getNodeInstanceIdentifier());
         deviceGroupRegistry = new DeviceGroupRegistryImpl();
@@ -173,7 +177,9 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         itemLifeCycleSourceRegistry = new ItemLifeCycleRegistryImpl();
         flowLifeCycleKeeper = new ItemLifeCycleSourceImpl();
         itemLifeCycleSourceRegistry.registerLifeCycleSource(flowLifeCycleKeeper);
-        contextState = CONTEXT_STATE.INITIALIZATION;
+        this.deviceInfo = deviceInfo;
+        this.state = CONTEXT_STATE.INITIALIZATION;
+        this.convertorExecutor = convertorExecutor;
     }
 
     /**
@@ -203,7 +209,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     public void removeAuxiliaryConnectionContext(final ConnectionContext connectionContext) {
         final SwitchConnectionDistinguisher connectionDistinguisher = createConnectionDistinguisher(connectionContext);
         LOG.debug("auxiliary connection dropped: {}, nodeId:{}", connectionContext.getConnectionAdapter()
-                .getRemoteAddress(), deviceInfo.getNodeId());
+                .getRemoteAddress(), getDeviceInfo().getNodeId());
         auxiliaryConnectionContexts.remove(connectionDistinguisher);
     }
 
@@ -212,11 +218,6 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         return deviceState;
     }
 
-    @Override
-    public DeviceInfo getDeviceInfo() {
-        return this.deviceInfo;
-    }
-
     @Override
     public ReadOnlyTransaction getReadTransaction() {
         return dataBroker.newReadOnlyTransaction();
@@ -325,7 +326,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     @Override
     public void processPortStatusMessage(final PortStatusMessage portStatus) {
         messageSpy.spyMessage(portStatus.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
-        final FlowCapableNodeConnector flowCapableNodeConnector = portStatusTranslator.translate(portStatus, deviceInfo, null);
+        final FlowCapableNodeConnector flowCapableNodeConnector = portStatusTranslator.translate(portStatus, getDeviceInfo(), null);
 
         final KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> iiToNodeConnector = provideIIToNodeConnector(portStatus.getPortNo(), portStatus.getVersion());
         try {
@@ -345,8 +346,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     }
 
     private KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> provideIIToNodeConnector(final long portNo, final short version) {
-        final InstanceIdentifier<Node> iiToNodes = deviceInfo.getNodeInstanceIdentifier();
-        final BigInteger dataPathId = deviceInfo.getDatapathId();
+        final InstanceIdentifier<Node> iiToNodes = getDeviceInfo().getNodeInstanceIdentifier();
+        final BigInteger dataPathId = getDeviceInfo().getDatapathId();
         final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(dataPathId.toString(), portNo, version);
         return iiToNodes.child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId));
     }
@@ -355,7 +356,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
     public void processPacketInMessage(final PacketInMessage packetInMessage) {
         messageSpy.spyMessage(packetInMessage.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH);
         final ConnectionAdapter connectionAdapter = getPrimaryConnectionContext().getConnectionAdapter();
-        final PacketReceived packetReceived = packetInTranslator.translate(packetInMessage, deviceInfo, null);
+        final PacketReceived packetReceived = packetInTranslator.translate(packetInMessage, getDeviceInfo(), null);
 
         if (packetReceived == null) {
             LOG.debug("Received a null packet from switch {}", connectionAdapter.getRemoteAddress());
@@ -403,13 +404,13 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         // lookup converter
         final ExperimenterDataOfChoice vendorData = notification.getExperimenterDataOfChoice();
         final MessageTypeKey<? extends ExperimenterDataOfChoice> key = new MessageTypeKey<>(
-                deviceInfo.getVersion(),
+                getDeviceInfo().getVersion(),
                 (Class<? extends ExperimenterDataOfChoice>) vendorData.getImplementedInterface());
         final ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> messageConverter = extensionConverterProvider.getMessageConverter(key);
         if (messageConverter == null) {
             LOG.warn("custom converter for {}[OF:{}] not found",
                     notification.getExperimenterDataOfChoice().getImplementedInterface(),
-                    deviceInfo.getVersion());
+                    getDeviceInfo().getVersion());
             return;
         }
         // build notification
@@ -417,7 +418,7 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         try {
             messageOfChoice = messageConverter.convert(vendorData, MessagePath.MESSAGE_NOTIFICATION);
             final ExperimenterMessageFromDevBuilder experimenterMessageFromDevBld = new ExperimenterMessageFromDevBuilder()
-                .setNode(new NodeRef(deviceInfo.getNodeInstanceIdentifier()))
+                .setNode(new NodeRef(getDeviceInfo().getNodeInstanceIdentifier()))
                     .setExperimenterMessageOfChoice(messageOfChoice);
             // publish
             notificationPublishService.offerNotification(experimenterMessageFromDevBld.build());
@@ -462,8 +463,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
     @Override
     public void onPublished() {
-        Verify.verify(CONTEXT_STATE.INITIALIZATION.equals(contextState));
-        contextState = CONTEXT_STATE.WORKING;
+        Verify.verify(CONTEXT_STATE.INITIALIZATION.equals(getState()));
+        setState(CONTEXT_STATE.WORKING);
         primaryConnectionContext.getConnectionAdapter().setPacketInFiltering(false);
         for (final ConnectionContext switchAuxConnectionContext : auxiliaryConnectionContexts.values()) {
             switchAuxConnectionContext.getConnectionAdapter().setPacketInFiltering(false);
@@ -497,15 +498,15 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
 
     @Override
     public synchronized void shutdownConnection() {
-        LOG.debug("Shutdown method for node {}", deviceInfo.getNodeId());
-        if (CONTEXT_STATE.TERMINATION.equals(contextState)) {
-            LOG.debug("DeviceCtx for Node {} is in termination process.", deviceInfo.getNodeId());
+        LOG.debug("Shutdown method for node {}", getDeviceInfo().getNodeId());
+        if (CONTEXT_STATE.TERMINATION.equals(getState())) {
+            LOG.debug("DeviceCtx for Node {} is in termination process.", getDeviceInfo().getNodeId());
             return;
         }
-        contextState = CONTEXT_STATE.TERMINATION;
+        setState(CONTEXT_STATE.TERMINATION);
 
         if (ConnectionContext.CONNECTION_STATE.RIP.equals(getPrimaryConnectionContext().getConnectionState())) {
-            LOG.debug("ConnectionCtx for Node {} is in RIP state.", deviceInfo.getNodeId());
+            LOG.debug("ConnectionCtx for Node {} is in RIP state.", getDeviceInfo().getNodeId());
             return;
         }
         /* Terminate Auxiliary Connection */
@@ -531,8 +532,41 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi
         return this.transactionChainManager;
     }
 
+    @Override
+    public void setSwitchFeaturesMandatory(boolean switchFeaturesMandatory) {
+        this.switchFeaturesMandatory = switchFeaturesMandatory;
+    }
+
     @Override
     public CONTEXT_STATE getState() {
-        return this.contextState;
+        return this.state;
+    }
+
+    @Override
+    public void setState(CONTEXT_STATE state) {
+        this.state = state;
+    }
+
+    @Override
+    public void startupClusterServices() throws ExecutionException, InterruptedException {
+        LOG.debug("Initializing transaction chain manager for node {}", getDeviceInfo().getNodeId());
+        this.transactionChainManager.activateTransactionManager();
+        LOG.debug("Waiting to get node {} information", getDeviceInfo().getNodeId());
+        DeviceInitializationUtils.initializeNodeInformation(this, switchFeaturesMandatory, this.convertorExecutor).get();
+    }
+
+    @Override
+    public ListenableFuture<Void> stopClusterServices() {
+        return this.transactionChainManager.deactivateTransactionManager();
+    }
+
+    @Override
+    public ServiceGroupIdentifier getServiceIdentifier() {
+        return this.deviceInfo.getServiceIdentifier();
+    }
+
+    @Override
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
     }
 }
index 455278fa1e05de89abc5cd53508c08f0f023cb72..587de817a7a88b85e376994536a0cccca87cdb33 100644 (file)
@@ -142,7 +142,7 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
         Preconditions.checkArgument(connectionContext != null);
 
         DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
-        /**
+        /*
          * This part prevent destroy another device context. Throwing here an exception result to propagate close connection
          * in {@link org.opendaylight.openflowplugin.impl.connection.org.opendaylight.openflowplugin.impl.connection.HandshakeContextImpl}
          * If context already exist we are in state closing process (connection flapping) and we should not propagate connection close
@@ -180,10 +180,14 @@ public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProvi
                 conductor,
                 outboundQueueProvider,
                 translatorLibrary,
-                this);
+                this,
+                connectionContext.getDeviceInfo(),
+                convertorExecutor);
 
         Verify.verify(deviceContexts.putIfAbsent(deviceInfo, deviceContext) == null, "DeviceCtx still not closed.");
 
+        deviceContext.setSwitchFeaturesMandatory(switchFeaturesMandatory);
+
         ((ExtensionConverterProviderKeeper) deviceContext).setExtensionConverterProvider(extensionConverterProvider);
         deviceContext.setNotificationPublishService(conductor.getNotificationPublishService());
 
diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java
new file mode 100644 (file)
index 0000000..b9e8d44
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.lifecycle;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
+import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class LifecycleServiceImpl implements LifecycleService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+
+    private final DeviceContext deviceContext;
+    private final RpcContext rpcContext;
+    private final RoleContext roleContext;
+    private final StatisticsContext statContext;
+
+    public LifecycleServiceImpl(
+            final DeviceContext deviceContext,
+            final RpcContext rpcContext,
+            final RoleContext roleContext,
+            final StatisticsContext statContext) {
+        this.deviceContext = deviceContext;
+        this.rpcContext = rpcContext;
+        this.roleContext = roleContext;
+        this.statContext = statContext;
+    }
+
+    @Override
+    public void instantiateServiceInstance() {
+        LOG.info("Starting device context cluster services for node {}", this.deviceContext.getServiceIdentifier());
+        try {
+            this.deviceContext.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() {
+        return deviceContext.stopClusterServices();
+    }
+
+    @Override
+    public ServiceGroupIdentifier getIdentifier() {
+        return deviceContext.getServiceIdentifier();
+    }
+}
index 0f6d73e2c2e3125f445d35e5fe308a8d6c40b840..87463cc6640d00a6ac889c3de8631dc38fc9e6d6 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlready
 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.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleConductor;
@@ -34,7 +35,6 @@ class RoleContextImpl implements RoleContext {
     private static final Logger LOG = LoggerFactory.getLogger(RoleContextImpl.class);
     private static final int TIMEOUT = 12;
 
-    private final DeviceInfo deviceInfo;
     private final EntityOwnershipService entityOwnershipService;
     private volatile EntityOwnershipCandidateRegistration entityOwnershipCandidateRegistration = null;
     private volatile EntityOwnershipCandidateRegistration txEntityOwnershipCandidateRegistration = null;
@@ -47,27 +47,32 @@ class RoleContextImpl implements RoleContext {
     private final Semaphore roleChangeGuard = new Semaphore(1, true);
 
     private final LifecycleConductor conductor;
-    private volatile CONTEXT_STATE contextState;
+    private final DeviceInfo deviceInfo;
+    private CONTEXT_STATE state;
 
-    RoleContextImpl(final DeviceInfo deviceInfo, final EntityOwnershipService entityOwnershipService, final Entity entity, final Entity txEntity, final LifecycleConductor lifecycleConductor) {
+    RoleContextImpl(final DeviceInfo deviceInfo,
+                    final EntityOwnershipService entityOwnershipService,
+                    final Entity entity,
+                    final Entity txEntity,
+                    final LifecycleConductor lifecycleConductor) {
         this.entityOwnershipService = entityOwnershipService;
         this.entity = entity;
         this.txEntity = txEntity;
-        this.deviceInfo = deviceInfo;
         this.conductor = lifecycleConductor;
-        contextState = CONTEXT_STATE.INITIALIZATION;
+        this.deviceInfo = deviceInfo;
+        state = CONTEXT_STATE.INITIALIZATION;
     }
 
     @Override
     public boolean initialization() {
-        LOG.info("Initialization main candidate for node {}", deviceInfo.getNodeId());
-        contextState = CONTEXT_STATE.WORKING;
+        LOG.info("Initialization main candidate for node {}", getDeviceInfo().getNodeId());
+        setState(CONTEXT_STATE.WORKING);
         return registerCandidate(this.entity);
     }
 
     @Override
     public void unregisterAllCandidates() {
-        LOG.info("Role context closed, unregistering all candidates for ownership for node {}", deviceInfo.getNodeId());
+        LOG.info("Role context closed, unregistering all candidates for ownership for node {}", getDeviceInfo().getNodeId());
         if (isMainCandidateRegistered()) {
             unregisterCandidate(this.entity);
         }
@@ -79,7 +84,7 @@ class RoleContextImpl implements RoleContext {
     @Nullable
     @Override
     public <T> RequestContext<T> createRequestContext() {
-        return new AbstractRequestContext<T>(conductor.reserveXidForDeviceMessage(deviceInfo)) {
+        return new AbstractRequestContext<T>(conductor.reserveXidForDeviceMessage(getDeviceInfo())) {
             @Override
             public void close() {
             }
@@ -107,11 +112,6 @@ class RoleContextImpl implements RoleContext {
         return this.txEntity;
     }
 
-    @Override
-    public DeviceInfo getDeviceInfo() {
-        return deviceInfo;
-    }
-
     @Override
     public boolean isMainCandidateRegistered() {
         return entityOwnershipCandidateRegistration != null;
@@ -186,7 +186,7 @@ class RoleContextImpl implements RoleContext {
 
     @Override
     public void close() {
-        contextState = CONTEXT_STATE.TERMINATION;
+        setState(CONTEXT_STATE.TERMINATION);
         unregisterAllCandidates();
     }
 
@@ -196,11 +196,22 @@ class RoleContextImpl implements RoleContext {
 
     @Override
     public CONTEXT_STATE getState() {
-        return contextState;
+        return this.state;
     }
 
     @Override
-    public void setState(CONTEXT_STATE contextState) {
-        this.contextState = contextState;
+    public void setState(CONTEXT_STATE state) {
+        this.state = state;
     }
+
+    @Override
+    public ServiceGroupIdentifier getServiceIdentifier() {
+        return this.deviceInfo.getServiceIdentifier();
+    }
+
+    @Override
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
+    }
+
 }
index 604806da9d414ad93c7238d8474136cea59056ed..716a9b38db51703378414e955d81d5611589b1ba 100644 (file)
@@ -418,7 +418,7 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se
     }
 
     @Override
-    public <T extends OFPContext> T gainContext(DeviceInfo deviceInfo) {
+    public <T extends OFPContext> T gainContext(final DeviceInfo deviceInfo) {
         return (T) contexts.get(deviceInfo);
     }
 }
index c91a1346754ff0168e5025fb40bae76f075ddf74..1a8cb845f1452b8760ae60369c48f0bf7b4e0fe8 100644 (file)
@@ -17,7 +17,8 @@ import java.util.concurrent.ConcurrentMap;
 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.openflowplugin.api.openflow.OFPContext;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+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;
@@ -38,24 +39,26 @@ class RpcContextImpl implements RpcContext {
     private final XidSequencer xidSequencer;
     private boolean isStatisticsRpcEnabled;
 
-    private volatile CONTEXT_STATE contextState;
-
     // TODO: add private Sal salBroker
     private final ConcurrentMap<Class<?>, RoutedRpcRegistration<?>> rpcRegistrations = new ConcurrentHashMap<>();
     private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
-
-    RpcContextImpl(final RpcProviderRegistry rpcProviderRegistry,
-                          final XidSequencer xidSequencer,
-                          final MessageSpy messageSpy,
-                          final int maxRequests,
-                          final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier) {
+    private CONTEXT_STATE state;
+    private final DeviceInfo deviceInfo;
+
+    RpcContextImpl(final DeviceInfo deviceInfo,
+                   final RpcProviderRegistry rpcProviderRegistry,
+                   final XidSequencer xidSequencer,
+                   final MessageSpy messageSpy,
+                   final int maxRequests,
+                   final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier) {
         this.xidSequencer = Preconditions.checkNotNull(xidSequencer);
         this.messageSpy = Preconditions.checkNotNull(messageSpy);
         this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
         this.nodeInstanceIdentifier = nodeInstanceIdentifier;
 
         tracker = new Semaphore(maxRequests, true);
-        contextState = CONTEXT_STATE.WORKING;
+        setState(CONTEXT_STATE.WORKING);
+        this.deviceInfo = deviceInfo;
     }
 
     /**
@@ -88,12 +91,12 @@ class RpcContextImpl implements RpcContext {
      */
     @Override
     public void close() {
-        if (CONTEXT_STATE.TERMINATION.equals(contextState)){
+        if (CONTEXT_STATE.TERMINATION.equals(getState())){
             if (LOG.isDebugEnabled()) {
                 LOG.debug("RpcContext is already in TERMINATION state.");
             }
         } else {
-            contextState = CONTEXT_STATE.TERMINATION;
+            setState(CONTEXT_STATE.TERMINATION);
             for (final Iterator<Entry<Class<?>, RoutedRpcRegistration<?>>> iterator = Iterators
                     .consumingIterator(rpcRegistrations.entrySet().iterator()); iterator.hasNext(); ) {
                 final RoutedRpcRegistration<?> rpcRegistration = iterator.next().getValue();
@@ -160,6 +163,21 @@ class RpcContextImpl implements RpcContext {
 
     @Override
     public CONTEXT_STATE getState() {
-        return contextState;
+        return this.state;
+    }
+
+    @Override
+    public void setState(CONTEXT_STATE state) {
+        this.state = state;
+    }
+
+    @Override
+    public ServiceGroupIdentifier getServiceIdentifier() {
+        return this.deviceInfo.getServiceIdentifier();
+    }
+
+    @Override
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
     }
 }
index 645409047168083448dd1fe076bf1a99812217fd..a09a395c2a51d4195f4958508dcc15f456467fa9 100644 (file)
@@ -38,9 +38,10 @@ public class RpcManagerImpl implements RpcManager {
 
     private final LifecycleConductor conductor;
 
-    public RpcManagerImpl(final RpcProviderRegistry rpcProviderRegistry,
-                          final int quotaValue,
-                          final LifecycleConductor lifecycleConductor) {
+    public RpcManagerImpl(
+            final RpcProviderRegistry rpcProviderRegistry,
+            final int quotaValue,
+            final LifecycleConductor lifecycleConductor) {
         this.rpcProviderRegistry = rpcProviderRegistry;
         maxRequestsQuota = quotaValue;
         this.conductor = lifecycleConductor;
@@ -57,6 +58,7 @@ public class RpcManagerImpl implements RpcManager {
         final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(deviceInfo));
 
         final RpcContext rpcContext = new RpcContextImpl(
+                deviceInfo,
                 rpcProviderRegistry,
                 deviceContext,
                 deviceContext.getMessageSpy(),
index b34e9529ed2bec2bbb7c8a8f517a092f969ad9ce..fccc2bfc4b1c61d705ed254abda1f90c9d7d639a 100644 (file)
@@ -23,10 +23,10 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
-import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
@@ -64,11 +64,15 @@ class StatisticsContextImpl implements StatisticsContext {
     private StatisticsGatheringService statisticsGatheringService;
     private StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService;
     private Timeout pollTimeout;
+    private final DeviceInfo deviceInfo;
 
     private volatile boolean schedulingEnabled;
-    private volatile CONTEXT_STATE contextState;
+    private volatile CONTEXT_STATE state;
 
-    StatisticsContextImpl(@CheckForNull final DeviceInfo deviceInfo, final boolean shuttingDownStatisticsPolling, final LifecycleConductor lifecycleConductor, final ConvertorExecutor convertorExecutor) {
+    StatisticsContextImpl(@Nonnull final DeviceInfo deviceInfo,
+                          @Nonnull final boolean shuttingDownStatisticsPolling,
+                          @Nonnull final LifecycleConductor lifecycleConductor,
+                         @Nonnull final ConvertorExecutor convertorExecutor) {
         this.deviceContext = Preconditions.checkNotNull(lifecycleConductor.getDeviceContext(deviceInfo));
         this.devState = Preconditions.checkNotNull(deviceContext.getDeviceState());
         this.shuttingDownStatisticsPolling = shuttingDownStatisticsPolling;
@@ -78,7 +82,8 @@ class StatisticsContextImpl implements StatisticsContext {
         statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService(this, deviceContext, convertorExecutor);
         itemLifeCycleListener = new ItemLifecycleListenerImpl(deviceContext);
         statListForCollectingInitialization();
-        contextState = CONTEXT_STATE.WORKING;
+        setState(CONTEXT_STATE.INITIALIZATION);
+        this.deviceInfo = deviceInfo;
     }
 
     @Override
@@ -122,7 +127,7 @@ class StatisticsContextImpl implements StatisticsContext {
 
     private ListenableFuture<Boolean> gatherDynamicData(final boolean initial) {
         if (shuttingDownStatisticsPolling) {
-            LOG.debug("Statistics for device {} is not enabled.", deviceContext.getDeviceInfo().getNodeId());
+            LOG.debug("Statistics for device {} is not enabled.", getDeviceInfo().getNodeId());
             return Futures.immediateFuture(Boolean.TRUE);
         }
         final ListenableFuture<Boolean> errorResultFuture = deviceConnectionCheck();
@@ -192,12 +197,12 @@ class StatisticsContextImpl implements StatisticsContext {
 
     @Override
     public void close() {
-        if (CONTEXT_STATE.TERMINATION.equals(contextState)) {
+        if (CONTEXT_STATE.TERMINATION.equals(getState())) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Statistics context is already in state TERMINATION.");
             }
         } else {
-            contextState = CONTEXT_STATE.TERMINATION;
+            setState(CONTEXT_STATE.TERMINATION);
             schedulingEnabled = false;
             for (final Iterator<RequestContext<?>> iterator = Iterators.consumingIterator(requestContexts.iterator());
                  iterator.hasNext(); ) {
@@ -232,19 +237,19 @@ class StatisticsContextImpl implements StatisticsContext {
     private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture, final boolean initial) {
         if (ConnectionContext.CONNECTION_STATE.RIP.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
             final String errMsg = String.format("Device connection is closed for Node : %s.",
-                    deviceContext.getDeviceInfo().getNodeId());
+                    getDeviceInfo().getNodeId());
             LOG.debug(errMsg);
             resultFuture.setException(new IllegalStateException(errMsg));
             return;
         }
         if ( ! iterator.hasNext()) {
             resultFuture.set(Boolean.TRUE);
-            LOG.debug("Stats collection successfully finished for node {}", deviceContext.getDeviceInfo().getNodeId());
+            LOG.debug("Stats collection successfully finished for node {}", getDeviceInfo().getNodeId());
             return;
         }
 
         final MultipartType nextType = iterator.next();
-        LOG.debug("Stats iterating to next type for node {} of type {}", deviceContext.getDeviceInfo().getNodeId(), nextType);
+        LOG.debug("Stats iterating to next type for node {} of type {}", getDeviceInfo().getNodeId(), nextType);
 
         final ListenableFuture<Boolean> deviceStatisticsCollectionFuture = chooseStat(nextType, initial);
         Futures.addCallback(deviceStatisticsCollectionFuture, new FutureCallback<Boolean>() {
@@ -288,7 +293,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType, final boolean initial) {
         return devState.isFlowStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringOnTheFlyService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPFLOW*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -298,7 +303,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectTableStatistics(final MultipartType multipartType) {
         return devState.isTableStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPTABLE*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -308,7 +313,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectPortStatistics(final MultipartType multipartType) {
         return devState.isPortStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPPORTSTATS*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -318,7 +323,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectQueueStatistics(final MultipartType multipartType) {
         return !devState.isQueueStatisticsAvailable() ? emptyFuture : StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPQUEUE*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -328,7 +333,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectGroupDescStatistics(final MultipartType multipartType) {
         return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPGROUPDESC*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -338,7 +343,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectGroupStatistics(final MultipartType multipartType) {
         return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPGROUP*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -348,7 +353,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectMeterConfigStatistics(final MultipartType multipartType) {
         return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPMETERCONFIG*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -358,7 +363,7 @@ class StatisticsContextImpl implements StatisticsContext {
     private ListenableFuture<Boolean> collectMeterStatistics(final MultipartType multipartType) {
         return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
                 statisticsGatheringService,
-                deviceContext.getDeviceInfo(),
+                getDeviceInfo(),
                 /*MultipartType.OFPMPMETER*/ multipartType,
                 deviceContext,
                 deviceContext,
@@ -383,6 +388,21 @@ class StatisticsContextImpl implements StatisticsContext {
 
     @Override
     public CONTEXT_STATE getState() {
-        return contextState;
+        return this.state;
+    }
+
+    @Override
+    public void setState(CONTEXT_STATE state) {
+        this.state = state;
+    }
+
+    @Override
+    public ServiceGroupIdentifier getServiceIdentifier() {
+        return this.deviceInfo.getServiceIdentifier();
+    }
+
+    @Override
+    public DeviceInfo getDeviceInfo() {
+        return this.deviceInfo;
     }
 }
index 8386755c855c15468c8efa4406a6ba2c2fd2573b..4602217b7a6d21f374921e0a5dd88c8c7b6a600f 100644 (file)
@@ -95,8 +95,6 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
     @Override
     public void onDeviceContextLevelUp(final DeviceInfo deviceInfo) throws Exception {
 
-        final DeviceContext deviceContext = Preconditions.checkNotNull(conductor.getDeviceContext(deviceInfo));
-
         final StatisticsContext statisticsContext = new StatisticsContextImpl(deviceInfo, shuttingDownStatisticsPolling, conductor, convertorExecutor);
         Verify.verify(contexts.putIfAbsent(deviceInfo, statisticsContext) == null, "StatisticsCtx still not closed for Node {}", deviceInfo.getNodeId());
 
@@ -143,7 +141,7 @@ public class StatisticsManagerImpl implements StatisticsManager, StatisticsManag
                 LOG.trace("Statistics gathering for single node was not successful.. ", throwable);
                 calculateTimerDelay(timeCounter);
                 if (throwable instanceof CancellationException) {
-                    /** This often happens when something wrong with akka or DS, so closing connection will help to restart device **/
+                    /* This often happens when something wrong with akka or DS, so closing connection will help to restart device **/
                     conductor.closeConnection(deviceInfo);
                 } else {
                     scheduleNextPolling(deviceState, deviceInfo, statisticsContext, timeCounter);
index 25860087b9502466f46207623870b570fc4a48b6..a1ea39d2dde8603c0ad9ee4694f69d305cbffb70 100644 (file)
@@ -64,6 +64,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.O
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
+import org.opendaylight.yangtools.yang.binding.RpcService;
 
 public class MdSalRegistrationUtils {
 
index 99a1cf4ce51b11e4c21dd51b206262c63edb85ae..298a40e35a97a95c142e3f090bb367e5e7ae7aef 100644 (file)
@@ -27,6 +27,7 @@ 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.openflowplugin.api.openflow.OFPContext;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
@@ -109,7 +110,6 @@ public class LifecycleConductorImplTest {
         when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
         when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
         when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
-        when(rpcManager.gainContext(Mockito.any())).thenReturn(rpcContext);
     }
 
     @Test
index 0aed926c01e29f12234b9e4d6a1437ba38559a63..f5840204e57eab9de3059c1c712ce3e3bf0e8d65 100644 (file)
@@ -75,6 +75,7 @@ import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionCon
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory;
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
 import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.ExperimenterMessageFromDev;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -175,6 +176,8 @@ public class DeviceContextImplTest {
     private DeviceInfo deviceInfo;
     @Mock
     private DeviceManager deviceManager;
+    @Mock
+    private ConvertorExecutor convertorExecutor;
 
     private InOrder inOrderDevState;
 
@@ -225,7 +228,16 @@ public class DeviceContextImplTest {
                 .thenReturn(messageTranslatorFlowRemoved);
         Mockito.when(lifecycleConductor.getMessageIntelligenceAgency()).thenReturn(messageIntelligenceAgency);
 
-        deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager);
+        deviceContext = new DeviceContextImpl(
+                connectionContext,
+                deviceState,
+                dataBroker,
+                lifecycleConductor,
+                outboundQueueProvider,
+                translatorLibrary,
+                       deviceManager,
+                deviceInfo,
+                convertorExecutor);
         deviceContextSpy = Mockito.spy(deviceContext);
 
         xid = new Xid(atomicLong.incrementAndGet());
@@ -236,17 +248,17 @@ public class DeviceContextImplTest {
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
-        new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
+        new DeviceContextImpl(connectionContext, deviceState, null, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager, deviceInfo, convertorExecutor).close();
     }
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullDeviceState() throws Exception {
-        new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
+        new DeviceContextImpl(connectionContext, null, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager, deviceInfo, convertorExecutor).close();
     }
 
     @Test(expected = NullPointerException.class)
     public void testDeviceContextImplConstructorNullTimer() throws Exception {
-        new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager).close();
+        new DeviceContextImpl(null, deviceState, dataBroker, lifecycleConductor, outboundQueueProvider, translatorLibrary, deviceManager, deviceInfo, convertorExecutor).close();
     }
 
     @Test
diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java
new file mode 100644 (file)
index 0000000..7388fcb
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+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.lifecycle.LifecycleService;
+import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
+import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LifecycleServiceImplTest {
+
+    private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER = ServiceGroupIdentifier.create("test node");
+    @Mock
+    private DeviceInfo deviceInfo;
+    @Mock
+    private DeviceContext deviceContext;
+    @Mock
+    private RpcContext rpcContext;
+    @Mock
+    private RoleContext roleContext;
+    @Mock
+    private StatisticsContext statContext;
+
+    private LifecycleService lifecycleService;
+
+    @Before
+    public void setUp() {
+        lifecycleService = new LifecycleServiceImpl(deviceContext, rpcContext, roleContext, statContext);
+        Mockito.when(deviceInfo.getServiceIdentifier()).thenReturn(SERVICE_GROUP_IDENTIFIER);
+    }
+
+    @Test
+    public void instantiateServiceInstance() throws Exception {
+        lifecycleService.instantiateServiceInstance();
+        Mockito.verify(deviceContext).startupClusterServices();
+    }
+
+    @Test
+    public void closeServiceInstance() throws Exception {
+        lifecycleService.closeServiceInstance();
+        Mockito.verify(deviceContext).stopClusterServices();
+    }
+
+}
\ No newline at end of file
index 8349f477a7053abf2224da79a308f856d9a09dbe..0f3ec3c5c151934c659a593dd36895de10857062 100644 (file)
@@ -73,20 +73,14 @@ public class RoleContextImplTest {
             }
         });
 
-        Thread t1 = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                LOG.info("Starting thread 1");
-                Assert.assertTrue(roleContext.initialization());
-            }
+        Thread t1 = new Thread(() -> {
+            LOG.info("Starting thread 1");
+            Assert.assertTrue(roleContext.initialization());
         });
 
-        Thread t2 = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                LOG.info("Starting thread 2");
-                Assert.assertFalse(roleContext.initialization());
-            }
+        Thread t2 = new Thread(() -> {
+            LOG.info("Starting thread 2");
+            Assert.assertFalse(roleContext.initialization());
         });
 
         t1.start();
index 9d982028a88f49c8b6dfae2d0115cdc99cc43537..a88fa53f319ee030360182b21f0feecd67640137 100644 (file)
@@ -55,7 +55,7 @@ public class RpcContextImplTest {
     @Mock
     private DeviceContext deviceContext;
     @Mock
-    private BindingAwareBroker.RoutedRpcRegistration routedRpcReg;
+    private BindingAwareBroker.RoutedRpcRegistration<TestRpcService> routedRpcReg;
     @Mock
     private NotificationPublishService notificationPublishService;
     @Mock
@@ -74,7 +74,13 @@ public class RpcContextImplTest {
         when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(nodeInstanceIdentifier);
         when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
 
-        rpcContext = new RpcContextImpl(rpcProviderRegistry,deviceContext, messageSpy, MAX_REQUESTS,nodeInstanceIdentifier);
+        rpcContext = new RpcContextImpl(
+                deviceInfo,
+                rpcProviderRegistry,
+                deviceContext,
+                messageSpy,
+                MAX_REQUESTS,
+                nodeInstanceIdentifier);
 
         when(rpcProviderRegistry.addRoutedRpcImplementation(TestRpcService.class, serviceInstance)).thenReturn(routedRpcReg);
 
@@ -82,8 +88,13 @@ public class RpcContextImplTest {
 
     @Test
     public void testStoreOrFail() throws Exception {
-        try (final RpcContext rpcContext = new RpcContextImpl(rpcProviderRegistry, xidSequencer,
-                messageSpy, 100, nodeInstanceIdentifier)) {
+        try (final RpcContext rpcContext = new RpcContextImpl(
+                deviceInfo,
+                rpcProviderRegistry,
+                xidSequencer,
+                messageSpy,
+                100,
+                nodeInstanceIdentifier)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNotNull(requestContext);
         }
@@ -91,8 +102,13 @@ public class RpcContextImplTest {
 
     @Test
     public void testStoreOrFailThatFails() throws Exception {
-        try (final RpcContext rpcContext = new RpcContextImpl(rpcProviderRegistry, xidSequencer,
-                messageSpy, 0, nodeInstanceIdentifier)) {
+        try (final RpcContext rpcContext = new RpcContextImpl(
+                deviceInfo,
+                rpcProviderRegistry,
+                xidSequencer,
+                messageSpy,
+                0,
+                nodeInstanceIdentifier)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNull(requestContext);
         }
@@ -100,8 +116,13 @@ public class RpcContextImplTest {
 
     @Test
     public void testStoreAndCloseOrFail() throws Exception {
-        try (final RpcContext rpcContext = new RpcContextImpl(rpcProviderRegistry, deviceContext, messageSpy,
-                100, nodeInstanceIdentifier)) {
+        try (final RpcContext rpcContext = new RpcContextImpl(
+                deviceInfo,
+                rpcProviderRegistry,
+                deviceContext,
+                messageSpy,
+                100,
+                nodeInstanceIdentifier)) {
             final RequestContext<?> requestContext = rpcContext.createRequestContext();
             assertNotNull(requestContext);
             requestContext.close();