From 867da8f64fbc12f407db3d41e96b216f7f62eb5b Mon Sep 17 00:00:00 2001 From: Jozef Bacigal Date: Mon, 18 Jul 2016 15:46:41 +0200 Subject: [PATCH] Bug 5596 Created lifecycle service - created general API for cluster services - changed OFPContext and OFPManager API Change-Id: I6506a1dcc328e98aca21446d46b8dd09445a4b61 Signed-off-by: Jozef Bacigal --- openflowplugin-api/pom.xml | 4 + .../api/openflow/OFPContext.java | 49 ++++++-- .../api/openflow/device/DeviceContext.java | 24 ++-- .../api/openflow/device/DeviceInfo.java | 6 + .../openflow/lifecycle/LifecycleService.java | 17 +++ .../api/openflow/role/RoleContext.java | 8 +- .../api/openflow/role/RoleManager.java | 11 +- .../api/openflow/rpc/RpcManager.java | 1 + .../statistics/StatisticsContext.java | 2 + .../statistics/StatisticsManager.java | 1 + .../connection/ConnectionContextImpl.java | 8 ++ .../impl/device/DeviceContextImpl.java | 108 ++++++++++++------ .../impl/device/DeviceManagerImpl.java | 8 +- .../impl/lifecycle/LifecycleServiceImpl.java | 61 ++++++++++ .../impl/role/RoleContextImpl.java | 47 +++++--- .../impl/role/RoleManagerImpl.java | 2 +- .../impl/rpc/RpcContextImpl.java | 44 ++++--- .../impl/rpc/RpcManagerImpl.java | 8 +- .../statistics/StatisticsContextImpl.java | 58 +++++++--- .../statistics/StatisticsManagerImpl.java | 4 +- .../impl/util/MdSalRegistrationUtils.java | 1 + .../impl/LifecycleConductorImplTest.java | 2 +- .../impl/device/DeviceContextImplTest.java | 20 +++- .../lifecycle/LifecycleServiceImplTest.java | 59 ++++++++++ .../impl/role/RoleContextImplTest.java | 18 +-- .../impl/rpc/RpcContextImplTest.java | 37 ++++-- 26 files changed, 454 insertions(+), 154 deletions(-) create mode 100644 openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java create mode 100644 openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java create mode 100644 openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java diff --git a/openflowplugin-api/pom.xml b/openflowplugin-api/pom.xml index 4edbc3ce47..ef9bb385f2 100644 --- a/openflowplugin-api/pom.xml +++ b/openflowplugin-api/pom.xml @@ -95,6 +95,10 @@ org.opendaylight.controller sal-common-api + + org.opendaylight.mdsal + mdsal-singleton-common-api + diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java index 9e8227e5b5..7bd11c9be7 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OFPContext.java @@ -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 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(); + } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java index c5baf45cf6..f0d0f0086f 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceContext.java @@ -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. *

*/ -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 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); + } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java index 75b0f13266..9272c919b2 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/DeviceInfo.java @@ -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 index 0000000000..72f84dd1ea --- /dev/null +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/lifecycle/LifecycleService.java @@ -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 { +} diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java index ea3d243599..263bc51bc3 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleContext.java @@ -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 diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java index bc851df3b6..c1f73ed0e6 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/role/RoleManager.java @@ -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"; diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java index 0339f8435e..d191527081 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcManager.java @@ -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; diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java index 22e975231a..d681cfde8f 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsContext.java @@ -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; diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java index ee4f67273b..162a531bfe 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/statistics/StatisticsManager.java @@ -25,4 +25,5 @@ public interface StatisticsManager extends DeviceLifecycleSupervisor, DeviceInit @Override void close(); + } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionContextImpl.java index d81d47a80d..aebb3fe3d3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/connection/ConnectionContextImpl.java @@ -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 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) { diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java index fd2e77c773..80cb770d65 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImpl.java @@ -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 iiToNodeConnector = provideIIToNodeConnector(portStatus.getPortNo(), portStatus.getVersion()); try { @@ -345,8 +346,8 @@ public class DeviceContextImpl implements DeviceContext, ExtensionConverterProvi } private KeyedInstanceIdentifier provideIIToNodeConnector(final long portNo, final short version) { - final InstanceIdentifier iiToNodes = deviceInfo.getNodeInstanceIdentifier(); - final BigInteger dataPathId = deviceInfo.getDatapathId(); + final InstanceIdentifier 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 key = new MessageTypeKey<>( - deviceInfo.getVersion(), + getDeviceInfo().getVersion(), (Class) vendorData.getImplementedInterface()); final ConvertorMessageFromOFJava 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 stopClusterServices() { + return this.transactionChainManager.deactivateTransactionManager(); + } + + @Override + public ServiceGroupIdentifier getServiceIdentifier() { + return this.deviceInfo.getServiceIdentifier(); + } + + @Override + public DeviceInfo getDeviceInfo() { + return this.deviceInfo; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index 455278fa1e..587de817a7 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -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 index 0000000000..b9e8d445a0 --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImpl.java @@ -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 closeServiceInstance() { + return deviceContext.stopClusterServices(); + } + + @Override + public ServiceGroupIdentifier getIdentifier() { + return deviceContext.getServiceIdentifier(); + } +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java index 0f6d73e2c2..87463cc664 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java @@ -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 RequestContext createRequestContext() { - return new AbstractRequestContext(conductor.reserveXidForDeviceMessage(deviceInfo)) { + return new AbstractRequestContext(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; + } + } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java index 604806da9d..716a9b38db 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleManagerImpl.java @@ -418,7 +418,7 @@ public class RoleManagerImpl implements RoleManager, EntityOwnershipListener, Se } @Override - public T gainContext(DeviceInfo deviceInfo) { + public T gainContext(final DeviceInfo deviceInfo) { return (T) contexts.get(deviceInfo); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java index c91a134675..1a8cb845f1 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java @@ -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, RoutedRpcRegistration> rpcRegistrations = new ConcurrentHashMap<>(); private final KeyedInstanceIdentifier nodeInstanceIdentifier; - - RpcContextImpl(final RpcProviderRegistry rpcProviderRegistry, - final XidSequencer xidSequencer, - final MessageSpy messageSpy, - final int maxRequests, - final KeyedInstanceIdentifier 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 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, 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; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java index 6454090471..a09a395c2a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java @@ -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(), diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java index b34e9529ed..fccc2bfc4b 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java @@ -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 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 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> iterator = Iterators.consumingIterator(requestContexts.iterator()); iterator.hasNext(); ) { @@ -232,19 +237,19 @@ class StatisticsContextImpl implements StatisticsContext { private void statChainFuture(final Iterator iterator, final SettableFuture 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 deviceStatisticsCollectionFuture = chooseStat(nextType, initial); Futures.addCallback(deviceStatisticsCollectionFuture, new FutureCallback() { @@ -288,7 +293,7 @@ class StatisticsContextImpl implements StatisticsContext { private ListenableFuture 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 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 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 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 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 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 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 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; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java index 8386755c85..4602217b7a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsManagerImpl.java @@ -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); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java index 25860087b9..a1ea39d2dd 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/util/MdSalRegistrationUtils.java @@ -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 { diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java index 99a1cf4ce5..298a40e35a 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/LifecycleConductorImplTest.java @@ -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 diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java index 0aed926c01..f5840204e5 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/device/DeviceContextImplTest.java @@ -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 index 0000000000..7388fcb596 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/lifecycle/LifecycleServiceImplTest.java @@ -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 diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java index 8349f477a7..0f3ec3c5c1 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/role/RoleContextImplTest.java @@ -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(); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java index 9d982028a8..a88fa53f31 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImplTest.java @@ -55,7 +55,7 @@ public class RpcContextImplTest { @Mock private DeviceContext deviceContext; @Mock - private BindingAwareBroker.RoutedRpcRegistration routedRpcReg; + private BindingAwareBroker.RoutedRpcRegistration 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(); -- 2.36.6