import io.netty.util.Timeout;
import java.math.BigInteger;
import java.util.List;
+import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.openflowplugin.api.openflow.OFPContext;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
/**
* The central entity of OFP is the Device Context, which encapsulate the logical state of a switch
AutoCloseable,
DeviceReplyProcessor,
TxFacade,
- DeviceRegistry{
+ DeviceRegistry,
+ RequestContextStack{
/**
* Method close all auxiliary connections and primary connection.
void replaceConnectionContext(ConnectionContext connectionContext);
boolean isSkipTableFeatures();
+
+ /**
+ * Setter for sal role service
+ * @param salRoleService
+ */
+ void setSalRoleService(@Nonnull final SalRoleService salRoleService);
+
+ /**
+ * Make device slave
+ * @return listenable future from sal role service
+ */
+ ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
}
package org.opendaylight.openflowplugin.api.openflow.device;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceDisconnectedHandler;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
void setBarrierInterval(long barrierTimeoutLimit);
+ CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(DeviceInfo deviceInfo);
}
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterInitializationPhaseHandler;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterLifecycleSupervisor;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
*/
void setRpcContext(final RpcContext rpcContext);
- /**
- * Setter for role context
- * @param roleContext actual role context created per device
- */
- void setRoleContext(final RoleContext roleContext);
-
/**
* Setter for statistics context
* @param statContext actual statistics context created per device
+++ /dev/null
-/**
- * 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.api.openflow.role;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import javax.annotation.Nonnull;
-import org.opendaylight.openflowplugin.api.openflow.OFPContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-/**
- * Role context for change role on cluster
- */
-public interface RoleContext extends RequestContextStack, OFPContext {
-
- /**
- * Setter for sal role service
- * @param salRoleService
- */
- void setSalRoleService(@Nonnull final SalRoleService salRoleService);
-
- /**
- * Make device slave
- * @return listenable future from sal role service
- */
- ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
-}
+++ /dev/null
-/*
- * 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.api.openflow.role;
-
-import com.google.common.util.concurrent.CheckedFuture;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-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;
-
-/**
- * Manager for role change on device
- */
-public interface RoleManager extends
- DeviceLifecycleSupervisor,
- DeviceInitializationPhaseHandler,
- AutoCloseable,
- DeviceTerminationPhaseHandler {
-
- CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo);
-
-}
import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionManager;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterManager;
import org.opendaylight.openflowplugin.impl.connection.ConnectionManagerImpl;
import org.opendaylight.openflowplugin.impl.device.DeviceManagerImpl;
-import org.opendaylight.openflowplugin.impl.role.RoleManagerImpl;
import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl;
import org.opendaylight.openflowplugin.impl.statistics.StatisticsManagerImpl;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl;
private int barrierCountLimit;
private long echoReplyTimeout;
private DeviceManager deviceManager;
- private RoleManager roleManager;
private RpcManager rpcManager;
private RpcProviderRegistry rpcProviderRegistry;
private StatisticsManager statisticsManager;
((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
rpcManager = new RpcManagerImpl(rpcProviderRegistry, rpcRequestsQuota, extensionConverterManager, convertorManager, notificationPublishService);
- roleManager = new RoleManagerImpl(dataBroker, hashedWheelTimer);
statisticsManager = new StatisticsManagerImpl(rpcProviderRegistry, isStatisticsPollingOff, hashedWheelTimer, convertorManager);
/* Initialization Phase ordering - OFP Device Context suite */
connectionManager.setDeviceConnectedHandler(deviceManager);
deviceManager.setDeviceInitializationPhaseHandler(statisticsManager);
statisticsManager.setDeviceInitializationPhaseHandler(rpcManager);
- rpcManager.setDeviceInitializationPhaseHandler(roleManager);
- roleManager.setDeviceInitializationPhaseHandler(deviceManager);
+ rpcManager.setDeviceInitializationPhaseHandler(deviceManager);
/* Termination Phase ordering - OFP Device Context suite */
deviceManager.setDeviceTerminationPhaseHandler(rpcManager);
rpcManager.setDeviceTerminationPhaseHandler(statisticsManager);
- statisticsManager.setDeviceTerminationPhaseHandler(roleManager);
- roleManager.setDeviceTerminationPhaseHandler(deviceManager);
+ statisticsManager.setDeviceTerminationPhaseHandler(deviceManager);
rpcManager.setStatisticsRpcEnabled(isStatisticsRpcEnabled);
rpcManager.close();
statisticsManager.close();
- // TODO: needs to close org.opendaylight.openflowplugin.impl.role.OpenflowOwnershipListener after RoleContexts are down
- // TODO: must not be executed prior to all living RoleContexts have been closed (via closing living DeviceContexts)
- roleManager.close();
-
// Manually shutdown all remaining running threads in pool
threadPool.shutdown();
}
package org.opendaylight.openflowplugin.impl.device;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
+import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
+import io.netty.util.TimerTask;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
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.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
+import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
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.rpc.AbstractRequestContext;
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.packet.service.rev130709.PacketReceived;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final float LOW_WATERMARK_FACTOR = 0.75f;
// TODO: high water mark factor should be parametrized
private static final float HIGH_WATERMARK_FACTOR = 0.95f;
+
+ // Timeout in seconds after what we will give up on propagating role
+ private static final int SET_ROLE_TIMEOUT = 10;
+
private boolean initialized;
private static final Long RETRY_DELAY = 100L;
private static final int RETRY_COUNT = 3;
+ private SalRoleService salRoleService = null;
+ private final HashedWheelTimer hashedWheelTimer;
private ConnectionContext primaryConnectionContext;
private final DeviceState deviceState;
private final DataBroker dataBroker;
private final ConvertorExecutor convertorExecutor;
private volatile CONTEXT_STATE state;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
+ private final DeviceManager myManager;
DeviceContextImpl(
@Nonnull final ConnectionContext primaryConnectionContext,
@Nonnull final TranslatorLibrary translatorLibrary,
@Nonnull final DeviceManager manager,
final ConvertorExecutor convertorExecutor,
- final boolean skipTableFeatures) {
+ final boolean skipTableFeatures,
+ final HashedWheelTimer hashedWheelTimer,
+ final DeviceManager myManager) {
this.primaryConnectionContext = primaryConnectionContext;
this.deviceInfo = primaryConnectionContext.getDeviceInfo();
+ this.hashedWheelTimer = hashedWheelTimer;
+ this.myManager = myManager;
this.deviceState = new DeviceStateImpl();
this.dataBroker = dataBroker;
this.auxiliaryConnectionContexts = new HashMap<>();
@Override
public ListenableFuture<Void> stopClusterServices(boolean deviceDisconnected) {
- return initialized
- ? this.transactionChainManager.deactivateTransactionManager()
- : Futures.immediateFuture(null);
+
+ ListenableFuture<Void> deactivateTxManagerFuture =
+ initialized ? transactionChainManager.deactivateTransactionManager() : Futures.immediateFuture(null);
+
+ if (!deviceDisconnected) {
+ ListenableFuture<Void> makeSlaveFuture = Futures.transform(makeDeviceSlave(), new Function<RpcResult<SetRoleOutput>, Void>() {
+ @Nullable
+ @Override
+ public Void apply(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
+ return null;
+ }
+ });
+
+ Futures.addCallback(makeSlaveFuture, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(@Nullable Void aVoid) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("Was not able to set role SLAVE to device on node {} ", deviceInfo.getLOGValue());
+ LOG.trace("Error occurred on device role setting, probably connection loss: ", throwable);
+ myManager.removeDeviceFromOperationalDS(deviceInfo);
+ }
+ });
+
+ return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
+ @Override
+ public ListenableFuture<Void> apply(Void aVoid) throws Exception {
+ return makeSlaveFuture;
+ }
+ });
+ } else {
+ return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
+ @Override
+ public ListenableFuture<Void> apply(Void aVoid) throws Exception {
+ return myManager.removeDeviceFromOperationalDS(deviceInfo);
+ }
+ });
+ }
}
@Override
return this.skipTableFeatures;
}
+ @Override
+ public void setSalRoleService(@Nonnull SalRoleService salRoleService) {
+ this.salRoleService = salRoleService;
+ }
+
@Override
public void setLifecycleInitializationPhaseHandler(final ClusterInitializationPhaseHandler handler) {
this.clusterInitializationPhaseHandler = handler;
return false;
}
+ Futures.addCallback(sendRoleChangeToDevice(OfpRole.BECOMEMASTER), new RpcResultFutureCallback());
+
return this.clusterInitializationPhaseHandler.onContextInstantiateService(getPrimaryConnectionContext());
}
this.initialized = true;
}
}
+
+ @Nullable
+ @Override
+ public <T> RequestContext<T> createRequestContext() {
+ return new AbstractRequestContext<T>(deviceInfo.reserveXidForDeviceMessage()) {
+ @Override
+ public void close() {
+ }
+ };
+
+ }
+
+ ListenableFuture<RpcResult<SetRoleOutput>> sendRoleChangeToDevice(final OfpRole newRole) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Sending new role {} to device {}", newRole, deviceInfo.getNodeId());
+ }
+ final Future<RpcResult<SetRoleOutput>> setRoleOutputFuture;
+ if (deviceInfo.getVersion() >= OFConstants.OFP_VERSION_1_3) {
+ final SetRoleInput setRoleInput = (new SetRoleInputBuilder()).setControllerRole(newRole)
+ .setNode(new NodeRef(deviceInfo.getNodeInstanceIdentifier())).build();
+ setRoleOutputFuture = this.salRoleService.setRole(setRoleInput);
+ final TimerTask timerTask = timeout -> {
+ if (!setRoleOutputFuture.isDone()) {
+ LOG.warn("New role {} was not propagated to device {} during {} sec", newRole, deviceInfo.getLOGValue(), SET_ROLE_TIMEOUT);
+ setRoleOutputFuture.cancel(true);
+ }
+ };
+ hashedWheelTimer.newTimeout(timerTask, SET_ROLE_TIMEOUT, TimeUnit.SECONDS);
+ } else {
+ LOG.info("Device: {} with version: {} does not support role", deviceInfo.getLOGValue(), deviceInfo.getVersion());
+ return Futures.immediateFuture(null);
+ }
+ return JdkFutureAdapters.listenInPoolThread(setRoleOutputFuture);
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave() {
+ return sendRoleChangeToDevice(OfpRole.BECOMESLAVE);
+ }
+
+ private class RpcResultFutureCallback implements FutureCallback<RpcResult<SetRoleOutput>> {
+ @Override
+ public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue());
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("Was not able to set MASTER role on device, node {}", deviceInfo.getLOGValue());
+ shutdownConnection();
+ }
+ }
}
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
+import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.TimeUnit;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
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.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl;
import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
connectionAdapter.registerOutboundQueueHandler(outboundQueueProvider, barrierCountLimit, barrierIntervalNanos);
connectionContext.setOutboundQueueHandleRegistration(outboundQueueHandlerRegistration);
+ final LifecycleService lifecycleService = new LifecycleServiceImpl();
+
final DeviceContext deviceContext = new DeviceContextImpl(
connectionContext,
dataBroker,
translatorLibrary,
this,
convertorExecutor,
- skipTableFeatures);
+ skipTableFeatures,
+ hashedWheelTimer,
+ this);
+ deviceContext.setSalRoleService(new SalRoleServiceImpl(deviceContext, deviceContext));
deviceContexts.put(deviceInfo, deviceContext);
- final LifecycleService lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
deviceContext.putLifecycleServiceIntoTxChainManager(lifecycleService);
lifecycleServices.put(deviceInfo, lifecycleService);
+ addCallbackToDeviceInitializeToSlave(deviceInfo, deviceContext, lifecycleService);
+
deviceContext.setSwitchFeaturesMandatory(switchFeaturesMandatory);
((ExtensionConverterProviderKeeper) deviceContext).setExtensionConverterProvider(extensionConverterProvider);
return ConnectionStatus.MAY_CONTINUE;
}
- private void updatePacketInRateLimiters() {
- synchronized (deviceContexts) {
- final int deviceContextsSize = deviceContexts.size();
- if (deviceContextsSize > 0) {
- long freshNotificationLimit = globalNotificationQuota / deviceContextsSize;
- if (freshNotificationLimit < 100) {
- freshNotificationLimit = 100;
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("fresh notification limit = {}", freshNotificationLimit);
- }
- for (final DeviceContext deviceContext : deviceContexts.values()) {
- deviceContext.updatePacketInRateLimit(freshNotificationLimit);
- }
- }
- }
- }
-
@Override
public TranslatorLibrary oook() {
return translatorLibrary;
this.barrierIntervalNanos = TimeUnit.MILLISECONDS.toNanos(barrierTimeoutLimit);
}
+ @Override
+ public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
+ final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
+ delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier());
+ final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
+
+ Futures.addCallback(delFuture, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(final Void result) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue());
+ }
+ }
+
+ @Override
+ public void onFailure(@Nonnull final Throwable t) {
+ LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t);
+ }
+ });
+
+ return delFuture;
+ }
+
+
+ private void addCallbackToDeviceInitializeToSlave(final DeviceInfo deviceInfo, final DeviceContext deviceContext, final LifecycleService lifecycleService) {
+ Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
+ @Override
+ public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ LOG.warn("Was not able to set role SLAVE to device on node {} ",deviceInfo.getLOGValue());
+ lifecycleService.closeConnection();
+ }
+ });
+ }
+
+ private void updatePacketInRateLimiters() {
+ synchronized (deviceContexts) {
+ final int deviceContextsSize = deviceContexts.size();
+ if (deviceContextsSize > 0) {
+ long freshNotificationLimit = globalNotificationQuota / deviceContextsSize;
+ if (freshNotificationLimit < 100) {
+ freshNotificationLimit = 100;
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("fresh notification limit = {}", freshNotificationLimit);
+ }
+ for (final DeviceContext deviceContext : deviceContexts.values()) {
+ deviceContext.updatePacketInRateLimit(freshNotificationLimit);
+ }
+ }
+ }
+ }
+
+ @VisibleForTesting
+ void setDeviceContext(final DeviceInfo deviceInfo, final DeviceContext deviceContext) {
+ this.deviceContexts.putIfAbsent(deviceInfo, deviceContext);
+ }
+
+ @VisibleForTesting
+ int getDeviceContextCount() {
+ return this.deviceContexts.size();
+ }
+
+
}
*/
package org.opendaylight.openflowplugin.impl.lifecycle;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterInitializationPhaseHandler;
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.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+ private boolean inClosing = false;
private DeviceContext deviceContext;
private RpcContext rpcContext;
- private RoleContext roleContext;
private StatisticsContext statContext;
private ClusterSingletonServiceRegistration registration;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
@Override
public void instantiateServiceInstance() {
-
LOG.info("Starting clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
if (!this.clusterInitializationPhaseHandler.onContextInstantiateService(null)) {
@Override
public ListenableFuture<Void> closeServiceInstance() {
-
- LOG.info("Stopping clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
+ LOG.info("Closing clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
final boolean connectionInterrupted =
this.deviceContext
.getConnectionState()
.equals(ConnectionContext.CONNECTION_STATE.RIP);
- roleContext.stopClusterServices(connectionInterrupted);
- statContext.stopClusterServices(connectionInterrupted);
- rpcContext.stopClusterServices(connectionInterrupted);
- return deviceContext.stopClusterServices(connectionInterrupted);
+ // If connection was interrupted and we are not trying to close service, then we received something
+ // we do not wanted to receive, so do not continue
+ if (connectionInterrupted && !inClosing) {
+ LOG.warn("Failed to close clustering MASTER services for node {} because they are already closed",
+ LifecycleServiceImpl.this.deviceContext.getDeviceInfo().getLOGValue());
+
+ return Futures.immediateCancelledFuture();
+ }
+ // Chain all jobs that will stop our services
+ final List<ListenableFuture<Void>> futureList = new ArrayList<>();
+ futureList.add(statContext.stopClusterServices(connectionInterrupted));
+ futureList.add(rpcContext.stopClusterServices(connectionInterrupted));
+ futureList.add(deviceContext.stopClusterServices(connectionInterrupted));
+
+ // When we stopped all jobs then we are not in closing state anymore (at least from plugin perspective)
+ return Futures.transform(Futures.successfulAsList(futureList), new Function<List<Void>, Void>() {
+ @Nullable
+ @Override
+ public Void apply(@Nullable List<Void> input) {
+ LOG.debug("Closed clustering MASTER services for node {}",
+ LifecycleServiceImpl.this.deviceContext.getDeviceInfo().getLOGValue());
+ return null;
+ }
+ });
}
@Override
@Override
public void close() throws Exception {
- if (registration != null) {
- LOG.info("Unregistering clustering MASTER services for node {}", this.deviceContext.getDeviceInfo().getLOGValue());
+ // If we are still registered and we are not already closing, then close the registration
+ if (Objects.nonNull(registration) && !inClosing) {
+ inClosing = true;
registration.close();
registration = null;
}
this.clusterInitializationPhaseHandler = deviceContext;
this.deviceContext.setLifecycleInitializationPhaseHandler(this.statContext);
this.statContext.setLifecycleInitializationPhaseHandler(this.rpcContext);
- this.rpcContext.setLifecycleInitializationPhaseHandler(this.roleContext);
- this.roleContext.setLifecycleInitializationPhaseHandler(this);
+ this.rpcContext.setLifecycleInitializationPhaseHandler(this);
//Set initial submit handler
this.statContext.setInitialSubmitHandler(this.deviceContext);
//Register cluster singleton service
this.rpcContext = rpcContext;
}
- @Override
- public void setRoleContext(final RoleContext roleContext) {
- this.roleContext = roleContext;
- }
-
@Override
public void setStatContext(final StatisticsContext statContext) {
this.statContext = statContext;
}
private void fillDeviceFlowRegistry() {
-
- final ListenableFuture<List<Optional<FlowCapableNode>>> deviceFlowRegistryFill = deviceContext.getDeviceFlowRegistry().fill();
+ final ListenableFuture<List<Optional<FlowCapableNode>>> deviceFlowRegistryFill = deviceContext.getDeviceFlowRegistry().fill();
Futures.addCallback(deviceFlowRegistryFill, new DeviceFlowRegistryCallback(deviceFlowRegistryFill));
}
+++ /dev/null
-/**
- * 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.role;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.TimerTask;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterInitializationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
-import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Role context try to make change device role on device
- */
-class RoleContextImpl implements RoleContext {
-
- private static final Logger LOG = LoggerFactory.getLogger(RoleContextImpl.class);
-
- // Timeout in seconds after what we will give up on propagating role
- private static final int SET_ROLE_TIMEOUT = 10;
-
- private SalRoleService salRoleService = null;
- private final HashedWheelTimer hashedWheelTimer;
- private final DeviceInfo deviceInfo;
- private CONTEXT_STATE state;
- private final RoleManager myManager;
- private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
- private final LifecycleService lifecycleService;
-
- RoleContextImpl(final DeviceInfo deviceInfo,
- final HashedWheelTimer hashedWheelTimer,
- final RoleManager myManager,
- final LifecycleService lifecycleService) {
- this.deviceInfo = deviceInfo;
- this.state = CONTEXT_STATE.WORKING;
- this.myManager = myManager;
- this.hashedWheelTimer = hashedWheelTimer;
- this.lifecycleService = lifecycleService;
- }
-
- @Nullable
- @Override
- public <T> RequestContext<T> createRequestContext() {
- return new AbstractRequestContext<T>(deviceInfo.reserveXidForDeviceMessage()) {
- @Override
- public void close() {
- }
- };
- }
-
- @Override
- public void setSalRoleService(@Nonnull final SalRoleService salRoleService) {
- Preconditions.checkNotNull(salRoleService);
- this.salRoleService = salRoleService;
- }
-
- @Override
- public CONTEXT_STATE getState() {
- 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;
- }
-
- public void startupClusterServices() throws ExecutionException, InterruptedException {
- Futures.addCallback(sendRoleChangeToDevice(OfpRole.BECOMEMASTER), new RpcResultFutureCallback());
- }
-
- @Override
- public ListenableFuture<Void> stopClusterServices(final boolean deviceDisconnected) {
-
- if (!deviceDisconnected) {
- ListenableFuture<Void> future = Futures.transform(makeDeviceSlave(), new Function<RpcResult<SetRoleOutput>, Void>() {
- @Nullable
- @Override
- public Void apply(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
- return null;
- }
- });
-
- Futures.addCallback(future, new FutureCallback<Void>() {
- @Override
- public void onSuccess(@Nullable Void aVoid) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
- }
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.warn("Was not able to set role SLAVE to device on node {} ", deviceInfo.getLOGValue());
- LOG.trace("Error occurred on device role setting, probably connection loss: ", throwable);
- myManager.removeDeviceFromOperationalDS(deviceInfo);
- }
- });
- return future;
- } else {
- return myManager.removeDeviceFromOperationalDS(deviceInfo);
- }
- }
-
- @Override
- public ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave(){
- return sendRoleChangeToDevice(OfpRole.BECOMESLAVE);
- }
-
- @VisibleForTesting
- ListenableFuture<RpcResult<SetRoleOutput>> sendRoleChangeToDevice(final OfpRole newRole) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Sending new role {} to device {}", newRole, deviceInfo.getNodeId());
- }
- final Future<RpcResult<SetRoleOutput>> setRoleOutputFuture;
- if (deviceInfo.getVersion() >= OFConstants.OFP_VERSION_1_3) {
- final SetRoleInput setRoleInput = (new SetRoleInputBuilder()).setControllerRole(newRole)
- .setNode(new NodeRef(deviceInfo.getNodeInstanceIdentifier())).build();
- setRoleOutputFuture = this.salRoleService.setRole(setRoleInput);
- final TimerTask timerTask = timeout -> {
- if (!setRoleOutputFuture.isDone()) {
- LOG.warn("New role {} was not propagated to device {} during 5 sec", newRole, deviceInfo.getLOGValue());
- setRoleOutputFuture.cancel(true);
- }
- };
- hashedWheelTimer.newTimeout(timerTask, SET_ROLE_TIMEOUT, TimeUnit.SECONDS);
- } else {
- LOG.info("Device: {} with version: {} does not support role", deviceInfo.getLOGValue(), deviceInfo.getVersion());
- return Futures.immediateFuture(null);
- }
- return JdkFutureAdapters.listenInPoolThread(setRoleOutputFuture);
- }
-
- @Override
- public void setLifecycleInitializationPhaseHandler(final ClusterInitializationPhaseHandler handler) {
- this.clusterInitializationPhaseHandler = handler;
- }
-
- @Override
- public boolean onContextInstantiateService(final ConnectionContext connectionContext) {
-
- if (connectionContext.getConnectionState().equals(ConnectionContext.CONNECTION_STATE.RIP)) {
- LOG.warn("Connection on device {} was interrupted, will stop starting master services.", deviceInfo.getLOGValue());
- return false;
- }
-
- Futures.addCallback(sendRoleChangeToDevice(OfpRole.BECOMEMASTER), new RpcResultFutureCallback());
- return this.clusterInitializationPhaseHandler.onContextInstantiateService(connectionContext);
- }
-
- private class RpcResultFutureCallback implements FutureCallback<RpcResult<SetRoleOutput>> {
- @Override
- public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Role MASTER was successfully set on device, node {}", deviceInfo.getLOGValue());
- }
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.warn("Was not able to set MASTER role on device, node {}", deviceInfo.getLOGValue());
- lifecycleService.closeConnection();
- }
- }
-}
+++ /dev/null
-/**
- * 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.role;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
-import com.google.common.collect.Iterators;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import io.netty.util.HashedWheelTimer;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-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.DeviceTerminationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
-import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Gets invoked from RpcManagerInitial, registers a candidate with EntityOwnershipService.
- * On receipt of the ownership notification, makes an rpc call to SalRoleService.
- *
- * Hands over to StatisticsManager at the end.
- */
-public class RoleManagerImpl implements RoleManager {
- private static final Logger LOG = LoggerFactory.getLogger(RoleManagerImpl.class);
-
- // Maximum limit of timeout retries when cleaning DS, to prevent infinite recursive loops
- private static final int MAX_CLEAN_DS_RETRIES = 3;
-
- private DeviceInitializationPhaseHandler deviceInitializationPhaseHandler;
- private DeviceTerminationPhaseHandler deviceTerminationPhaseHandler;
- private final DataBroker dataBroker;
- private final ConcurrentMap<DeviceInfo, RoleContext> contexts = new ConcurrentHashMap<>();
- private final HashedWheelTimer hashedWheelTimer;
-
- public RoleManagerImpl(final DataBroker dataBroker, final HashedWheelTimer hashedWheelTimer) {
- this.dataBroker = Preconditions.checkNotNull(dataBroker);
- this.hashedWheelTimer = hashedWheelTimer;
- }
-
- @Override
- public void setDeviceInitializationPhaseHandler(final DeviceInitializationPhaseHandler handler) {
- deviceInitializationPhaseHandler = handler;
- }
-
- @Override
- public void onDeviceContextLevelUp(@CheckForNull final DeviceInfo deviceInfo, final LifecycleService lifecycleService) throws Exception {
- final DeviceContext deviceContext = Preconditions.checkNotNull(lifecycleService.getDeviceContext());
- final RoleContext roleContext = new RoleContextImpl(deviceInfo, hashedWheelTimer, this, lifecycleService);
- roleContext.setSalRoleService(new SalRoleServiceImpl(roleContext, deviceContext));
- Verify.verify(contexts.putIfAbsent(deviceInfo, roleContext) == null, "Role context for master Node %s is still not closed.", deviceInfo.getLOGValue());
- Futures.addCallback(roleContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
- @Override
- public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Role SLAVE was successfully propagated on device, node {}", deviceInfo.getLOGValue());
- }
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- LOG.warn("Was not able to set role SLAVE to device on node {} ",deviceInfo.getLOGValue());
- lifecycleService.closeConnection();
- }
- });
- lifecycleService.setRoleContext(roleContext);
- deviceInitializationPhaseHandler.onDeviceContextLevelUp(deviceInfo, lifecycleService);
- }
-
- @Override
- public void close() {
- LOG.debug("Close method on role manager was called.");
- for (final Iterator<RoleContext> iterator = Iterators.consumingIterator(contexts.values().iterator()); iterator.hasNext();) {
- // got here because last known role is LEADER and DS might need clearing up
- final RoleContext roleContext = iterator.next();
- contexts.remove(roleContext.getDeviceInfo());
- removeDeviceFromOperationalDS(roleContext.getDeviceInfo());
- }
- }
-
- @Override
- public void onDeviceContextLevelDown(final DeviceInfo deviceInfo) {
- contexts.remove(deviceInfo);
- deviceTerminationPhaseHandler.onDeviceContextLevelDown(deviceInfo);
- }
-
- @Override
- public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
- final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
- delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier());
- final CheckedFuture<Void, TransactionCommitFailedException> delFuture = delWtx.submit();
-
- Futures.addCallback(delFuture, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Delete Node {} was successful", deviceInfo.getLOGValue());
- }
- }
-
- @Override
- public void onFailure(@Nonnull final Throwable t) {
- LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t);
- }
- });
-
- return delFuture;
- }
-
- @Override
- public void setDeviceTerminationPhaseHandler(final DeviceTerminationPhaseHandler handler) {
- deviceTerminationPhaseHandler = handler;
- }
-
- @VisibleForTesting
- RoleContext getRoleContext(final DeviceInfo deviceInfo){
- return contexts.get(deviceInfo);
- }
-
-}
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
@Override
public void onSuccess(final RpcResult<UpdateFlowOutput> o) {
- final UpdatedFlow updated = input.getUpdatedFlow();
- final OriginalFlow original = input.getOriginalFlow();
- FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(original);
-
- FlowRegistryKey updatedflowRegistryKey = FlowRegistryKeyFactory.create(updated);
- final FlowRef flowRef = input.getFlowRef();
final DeviceFlowRegistry deviceFlowRegistry = deviceContext.getDeviceFlowRegistry();
- if (flowRef == null) {
- // then this is equivalent to a delete
- deviceFlowRegistry.removeDescriptor(flowRegistryKey);
+ final UpdatedFlow updated = input.getUpdatedFlow();
+ final OriginalFlow original = input.getOriginalFlow();
+ final FlowRegistryKey origFlowRegistryKey = FlowRegistryKeyFactory.create(original);
+ final FlowRegistryKey updatedFlowRegistryKey = FlowRegistryKeyFactory.create(updated);
+ final FlowDescriptor origFlowDescriptor = deviceFlowRegistry.retrieveIdForFlow(origFlowRegistryKey);
+
+ final boolean isUpdate = Objects.nonNull(origFlowDescriptor);
+ final FlowId fLowId = Objects.nonNull(input.getFlowRef())
+ ? input.getFlowRef().getValue().firstKeyOf(Flow.class).getId()
+ : isUpdate ? origFlowDescriptor.getFlowId() : deviceFlowRegistry.storeIfNecessary(updatedFlowRegistryKey);
+ final FlowDescriptor updatedFlowDescriptor = FlowDescriptorFactory.create(updated.getTableId(), fLowId);
+ if (isUpdate) {
+ deviceFlowRegistry.removeDescriptor(origFlowRegistryKey);
+ deviceFlowRegistry.store(updatedFlowRegistryKey, updatedFlowDescriptor);
+ }
- if (itemLifecycleListener != null) {
- final FlowDescriptor flowDescriptor =
- deviceContext.getDeviceFlowRegistry().retrieveIdForFlow( flowRegistryKey);
- KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
- itemLifecycleListener.onRemoved(flowPath);
- }
- } else {
- // this is either an add or an update
- final FlowId flowId = flowRef.getValue().firstKeyOf(Flow.class, FlowKey.class).getId();
- final FlowDescriptor flowDescriptor = FlowDescriptorFactory.create(updated.getTableId(), flowId);
+ if (itemLifecycleListener != null) {
+ final KeyedInstanceIdentifier<Flow, FlowKey> flowPath =
+ createFlowPath(
+ updatedFlowDescriptor,
+ deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
- deviceFlowRegistry.update(updatedflowRegistryKey, flowDescriptor);
+ final Flow flow = new FlowBuilder(updated)
+ .setId(updatedFlowDescriptor.getFlowId())
+ .build();
- if (itemLifecycleListener != null) {
- KeyedInstanceIdentifier<Flow, FlowKey> flowPath = createFlowPath(flowDescriptor,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier());
- final FlowBuilder flowBuilder = new FlowBuilder(
- input.getUpdatedFlow()).setId(flowDescriptor.getFlowId());
-
- boolean isUpdate = null !=
- deviceFlowRegistry.retrieveIdForFlow(flowRegistryKey);
- if (isUpdate) {
- itemLifecycleListener.onUpdated(flowPath, flowBuilder.build());
- } else {
- itemLifecycleListener.onAdded(flowPath, flowBuilder.build());
- }
+ if (Objects.nonNull(origFlowDescriptor)) {
+ itemLifecycleListener.onUpdated(flowPath, flow);
+ } else {
+ itemLifecycleListener.onAdded(flowPath, flow);
}
}
}
import java.util.Collections;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
final short tableId = flowStat.getTableId();
final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
- final FlowId flowId = registry.storeIfNecessary(flowRegistryKey);
-
- final FlowKey flowKey = new FlowKey(flowId);
- flowBuilder.setKey(flowKey);
- final TableKey tableKey = new TableKey(tableId);
- final InstanceIdentifier<Flow> flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+ final FlowDescriptor flowDescriptor = registry.retrieveIdForFlow(flowRegistryKey);
+
+ if(Objects.nonNull(flowDescriptor)) {
+ final FlowId flowId = flowDescriptor.getFlowId();
+ final FlowKey flowKey = new FlowKey(flowId);
+ flowBuilder.setKey(flowKey);
+ final TableKey tableKey = new TableKey(tableId);
+ final InstanceIdentifier<Flow> flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+ } else {
+ LOG.warn("Skip write statistics. Flow hash: {} not present in DeviceFlowRegistry", flowRegistryKey.hashCode());
+ }
}
}
} catch (Exception e) {
translatorLibrary,
deviceManager,
convertorExecutor,
- false);
+ false, timer, deviceManager);
deviceContextSpy = Mockito.spy(deviceContext);
xid = new Xid(atomicLong.incrementAndGet());
@Test(expected = NullPointerException.class)
public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
- new DeviceContextImpl(connectionContext, null, null, translatorLibrary, deviceManager, convertorExecutor,false).close();
+ new DeviceContextImpl(connectionContext, null, null, translatorLibrary, deviceManager, convertorExecutor,false, timer, deviceManager).close();
}
@Test(expected = NullPointerException.class)
public void testDeviceContextImplConstructorNullTimer() throws Exception {
- new DeviceContextImpl(null, dataBroker, null, translatorLibrary, deviceManager,convertorExecutor,false).close();
+ new DeviceContextImpl(null, dataBroker, null, translatorLibrary, deviceManager,convertorExecutor,false, timer, deviceManager).close();
}
@Test
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.Spy;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPortBuilder;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
@RunWith(MockitoJUnitRunner.class)
public class DeviceManagerImplTest {
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
@Mock
private ConvertorExecutor convertorExecutor;
-
+ @Mock
+ private KeyedInstanceIdentifier<Node, NodeKey> key;
@Before
public void setUp() throws Exception {
OpenflowPortsUtil.init();
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterInitializationPhaseHandler;
import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
@Mock
private RpcContext rpcContext;
@Mock
- private RoleContext roleContext;
- @Mock
private StatisticsContext statContext;
@Mock
private ConnectionContext connectionContext;
Mockito.when(connectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
Mockito.when(deviceInfo.getLOGValue()).thenReturn(TEST_NODE);
+ Mockito.when(deviceContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(statContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(rpcContext.stopClusterServices(Mockito.anyBoolean())).thenReturn(Futures.immediateFuture(null));
+
lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
lifecycleService.setRpcContext(rpcContext);
- lifecycleService.setRoleContext(roleContext);
lifecycleService.setStatContext(statContext);
lifecycleService.registerService(clusterSingletonServiceProvider);
}
@Test
public void instantiateServiceInstance() throws Exception {
lifecycleService.instantiateServiceInstance();
- Mockito.verify(deviceContext).setLifecycleInitializationPhaseHandler(Mockito.<ClusterInitializationPhaseHandler>any());
- Mockito.verify(statContext).setLifecycleInitializationPhaseHandler(Mockito.<ClusterInitializationPhaseHandler>any());
- Mockito.verify(statContext).setInitialSubmitHandler(Mockito.<ClusterInitializationPhaseHandler>any());
- Mockito.verify(rpcContext).setLifecycleInitializationPhaseHandler(Mockito.<ClusterInitializationPhaseHandler>any());
- Mockito.verify(roleContext).setLifecycleInitializationPhaseHandler(Mockito.<ClusterInitializationPhaseHandler>any());
+ Mockito.verify(deviceContext).setLifecycleInitializationPhaseHandler(Mockito.any());
+ Mockito.verify(statContext).setLifecycleInitializationPhaseHandler(Mockito.any());
+ Mockito.verify(statContext).setInitialSubmitHandler(Mockito.any());
+ Mockito.verify(rpcContext).setLifecycleInitializationPhaseHandler(Mockito.any());
}
@Test
Mockito.verify(statContext).stopClusterServices(false);
Mockito.verify(deviceContext).stopClusterServices(false);
Mockito.verify(rpcContext).stopClusterServices(false);
- Mockito.verify(roleContext).stopClusterServices(false);
}
@Test
Mockito.verify(deviceContext).shutdownConnection();
}
-}
\ No newline at end of file
+}
+++ /dev/null
-/**
- * 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.role;
-
-
-import com.google.common.util.concurrent.Futures;
-import io.netty.util.HashedWheelTimer;
-import org.junit.Assert;
-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.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
-import org.opendaylight.openflowplugin.api.OFConstants;
-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.role.RoleManager;
-import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RoleContextImplTest {
-
- @Mock
- HashedWheelTimer hashedWheelTimer;
- @Mock
- private DeviceInfo deviceInfo;
- @Mock
- private RoleManager roleManager;
- @Mock
- private LifecycleService lifecycleService;
- @Mock
- private SalRoleService salRoleService;
-
- private final NodeId nodeId = NodeId.getDefaultInstance("openflow:1");
- private RoleContext roleContext;
- private RoleContextImpl roleContextSpy;
-
- @Before
- public void setup() throws CandidateAlreadyRegisteredException {
- roleContext = new RoleContextImpl(deviceInfo, hashedWheelTimer, roleManager, lifecycleService);
- roleContext.setSalRoleService(salRoleService);
- Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
- Mockito.when(salRoleService.setRole(Mockito.<SetRoleInput>any())).thenReturn(Futures.immediateFuture(null));
- Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(DeviceStateUtil.createNodeInstanceIdentifier(nodeId));
- roleContextSpy = Mockito.spy((RoleContextImpl) roleContext);
- }
-
- @Test
- public void testCreateRequestContext() throws Exception {
- roleContext.createRequestContext();
- Mockito.verify(deviceInfo).reserveXidForDeviceMessage();
- }
-
- @Test(expected = NullPointerException.class)
- public void testSetSalRoleService() throws Exception {
- roleContext.setSalRoleService(null);
- }
-
- @Test
- public void testGetNodeId() throws Exception {
- Assert.assertTrue(roleContext.getDeviceInfo().getNodeId().equals(nodeId));
- }
-
- @Test
- public void startupClusterServices() throws Exception {
- roleContextSpy.startupClusterServices();
- Mockito.verify(roleContextSpy).sendRoleChangeToDevice(OfpRole.BECOMEMASTER);
- }
-
- @Test
- public void startupClusterServicesVersion10() throws Exception {
- Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
- roleContextSpy.startupClusterServices();
- Mockito.verify(roleContextSpy).sendRoleChangeToDevice(OfpRole.BECOMEMASTER);
- }
-
- @Test
- public void startupClusterServicesVersion13() throws Exception {
- Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
- roleContextSpy.startupClusterServices();
- Mockito.verify(roleContextSpy).sendRoleChangeToDevice(OfpRole.BECOMEMASTER);
- }
-
- @Test
- public void stopClusterServicesNotDisconnected() throws Exception {
- roleContextSpy.stopClusterServices(false);
- Mockito.verify(roleContextSpy).sendRoleChangeToDevice(OfpRole.BECOMESLAVE);
- Mockito.verify(roleManager, Mockito.never()).removeDeviceFromOperationalDS(Mockito.<DeviceInfo>any());
- }
-
- @Test
- public void stopClusterServicesDisconnected() throws Exception {
- roleContextSpy.stopClusterServices(true);
- Mockito.verify(roleManager, Mockito.atLeastOnce()).removeDeviceFromOperationalDS(Mockito.<DeviceInfo>any());
- }
-
- @Test
- public void makeDeviceSlave() throws Exception {
- roleContextSpy.makeDeviceSlave();
- Mockito.verify(roleContextSpy).sendRoleChangeToDevice(OfpRole.BECOMESLAVE);
- }
-
-}
+++ /dev/null
-/*
- * 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.role;
-
-
-import static org.mockito.Mockito.verify;
-
-import com.google.common.base.VerifyException;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import io.netty.util.HashedWheelTimer;
-import java.math.BigInteger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceTerminationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
-import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
-import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
-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;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RoleManagerImplTest {
-
- @Mock
- DataBroker dataBroker;
- @Mock
- DeviceContext deviceContext;
- @Mock
- DeviceManager deviceManager;
- @Mock
- ConnectionContext connectionContext;
- @Mock
- FeaturesReply featuresReply;
- @Mock
- DeviceInitializationPhaseHandler deviceInitializationPhaseHandler;
- @Mock
- DeviceTerminationPhaseHandler deviceTerminationPhaseHandler;
- @Mock
- WriteTransaction writeTransaction;
- @Mock
- DeviceState deviceState;
- @Mock
- DeviceInfo deviceInfo;
- @Mock
- DeviceInfo deviceInfo2;
- @Mock
- MessageSpy messageSpy;
- @Mock
- OutboundQueue outboundQueue;
- @Mock
- GetFeaturesOutput featuresOutput;
- @Mock
- LifecycleService lifecycleService;
-
- private RoleManagerImpl roleManager;
- private RoleManagerImpl roleManagerSpy;
- private RoleContext roleContextSpy;
- private final NodeId nodeId = NodeId.getDefaultInstance("openflow:1");
- private final NodeId nodeId2 = NodeId.getDefaultInstance("openflow:2");
-
- private InOrder inOrder;
-
- @Before
- public void setUp() throws Exception {
- CheckedFuture<Void, TransactionCommitFailedException> future = Futures.immediateCheckedFuture(null);
- Mockito.when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
- Mockito.when(deviceContext.getDeviceState()).thenReturn(deviceState);
- Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
- Mockito.when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
- Mockito.when(deviceContext.getPrimaryConnectionContext().getOutboundQueueProvider()).thenReturn(outboundQueue);
- Mockito.when(connectionContext.getFeatures()).thenReturn(featuresReply);
- Mockito.when(connectionContext.getNodeId()).thenReturn(nodeId);
- Mockito.when(connectionContext.getConnectionState()).thenReturn(ConnectionContext.CONNECTION_STATE.WORKING);
- Mockito.when(deviceInfo.getDatapathId()).thenReturn(new BigInteger("1"));
- Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
- Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
- Mockito.doNothing().when(deviceInitializationPhaseHandler).onDeviceContextLevelUp(Mockito.<DeviceInfo>any(), Mockito.<LifecycleService>any());
- Mockito.doNothing().when(deviceTerminationPhaseHandler).onDeviceContextLevelDown(Mockito.<DeviceInfo>any());
- Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
- Mockito.when(writeTransaction.submit()).thenReturn(future);
- Mockito.when(deviceInfo.getNodeId()).thenReturn(nodeId);
- Mockito.when(deviceInfo2.getNodeId()).thenReturn(nodeId2);
- Mockito.when(deviceInfo.getDatapathId()).thenReturn(BigInteger.TEN);
- Mockito.when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(DeviceStateUtil.createNodeInstanceIdentifier(nodeId));
- Mockito.when(lifecycleService.getDeviceContext()).thenReturn(deviceContext);
- roleManager = new RoleManagerImpl(dataBroker, new HashedWheelTimer());
- roleManager.setDeviceInitializationPhaseHandler(deviceInitializationPhaseHandler);
- roleManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
- roleManagerSpy = Mockito.spy(roleManager);
- roleManagerSpy.onDeviceContextLevelUp(deviceInfo, lifecycleService);
- roleContextSpy = Mockito.spy(roleManager.getRoleContext(deviceInfo));
- Mockito.when(roleContextSpy.getDeviceInfo()).thenReturn(deviceInfo);
- Mockito.when(roleContextSpy.getDeviceInfo().getNodeId()).thenReturn(nodeId);
- inOrder = Mockito.inOrder(roleManagerSpy, roleContextSpy);
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test(expected = VerifyException.class)
- public void testOnDeviceContextLevelUp() throws Exception {
- roleManagerSpy.onDeviceContextLevelUp(deviceInfo, lifecycleService);
- inOrder.verify(roleManagerSpy).onDeviceContextLevelUp(deviceInfo, lifecycleService);
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testCloseMaster() throws Exception {
- roleManagerSpy.close();
- inOrder.verify(roleManagerSpy).removeDeviceFromOperationalDS(Mockito.eq(deviceInfo));
- inOrder.verifyNoMoreInteractions();
- }
-
- @Test
- public void testOnDeviceContextLevelDown() throws Exception {
- roleManagerSpy.onDeviceContextLevelDown(deviceInfo);
- inOrder.verify(roleManagerSpy).onDeviceContextLevelDown(deviceInfo);
- inOrder.verifyNoMoreInteractions();
- }
-}
\ No newline at end of file
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
@Mock
private DeviceFlowRegistry mockedFlowRegistry;
@Mock
+ private FlowDescriptor mockedFlowDescriptor;
+ @Mock
private ReadOnlyTransaction mockedReadOnlyTx;
private AbstractRequestContext<List<MultipartReply>> dummyRequestContext;
when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
when(mockedDeviceContext.getDeviceFlowRegistry()).thenReturn(mockedFlowRegistry);
+ when(mockedFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(mockedFlowDescriptor);
final InstanceIdentifier<FlowCapableNode> nodePath = mockedDeviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
final FlowCapableNodeBuilder flowNodeBuilder = new FlowCapableNodeBuilder();
final MatchBuilder matchBuilder = new MatchBuilder()
.setMatchEntry(Collections.<MatchEntry>emptyList());
final FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder()
-.setTableId(tableId)
+ .setTableId(tableId)
.setPriority(2)
.setCookie(BigInteger.ZERO)
.setByteCount(BigInteger.TEN)
verify(mockedReadOnlyTx, times(1)).read(LogicalDatastoreType.OPERATIONAL, nodePath);
verify(mockedReadOnlyTx, times(1)).close();
- verify(mockedFlowRegistry).storeIfNecessary(Matchers.<FlowRegistryKey> any());
verify(mockedDeviceContext, times(1)).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL),
eq(tableIdent), Matchers.<Table> any());
/*
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
@Mock
private DeviceMeterRegistry deviceMeterRegistry;
@Mock
+ private FlowDescriptor flowDescriptor;
+ @Mock
+ private FlowId flowId;
+ @Mock
private GetFeaturesOutput features;
@Mock
private ReadOnlyTransaction readTx;
when(deviceContext.getDeviceFlowRegistry()).thenReturn(deviceFlowRegistry);
when(deviceContext.getDeviceGroupRegistry()).thenReturn(deviceGroupRegistry);
when(deviceContext.getDeviceMeterRegistry()).thenReturn(deviceMeterRegistry);
+ when(deviceFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(flowDescriptor);
when(deviceContext.getReadTransaction()).thenReturn(readTx);
when(txFacade.getReadTransaction()).thenReturn(readTx);
when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionAdapter);
public void testGatherStatistics_flow() throws Exception {
final short tableId = 0;
final MultipartType type = MultipartType.OFPMPFLOW;
- when(deviceFlowRegistry.storeIfNecessary(Matchers.any(FlowRegistryKey.class)))
- .thenReturn(new FlowId("openflow:21"));
final InstanceIdentifier<FlowCapableNode> nodePath = deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
final TableBuilder tableDataBld = new TableBuilder();
final Optional<FlowCapableNode> flowNodeOpt = Optional.of(flowNodeBuilder.build());
final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowNodeFuture = Futures.immediateCheckedFuture(flowNodeOpt);
when(readTx.read(LogicalDatastoreType.OPERATIONAL, nodePath)).thenReturn(flowNodeFuture);
+ when(flowDescriptor.getFlowId()).thenReturn(flowId);
final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder matchBld =
new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder()
final FlowBuilder flowBld = new FlowBuilder()
.setTableId((short) 0)
.setMatch(new MatchBuilder().build());
- final KeyedInstanceIdentifier<Flow, FlowKey> flowPath = dummyNodePath.augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey((short) 0))
- .child(Flow.class, new FlowKey(new FlowId("openflow:21")));
+ final KeyedInstanceIdentifier<Table, TableKey> tablePath = dummyNodePath.augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey((short) 0));
+ final KeyedInstanceIdentifier<Flow, FlowKey> flowPath = tablePath.child(Flow.class, new FlowKey(flowId));
+
verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
- verify(deviceFlowRegistry).storeIfNecessary(FlowRegistryKeyFactory.create(flowBld.build()));
- verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(flowPath), Matchers.any(Flow.class));
+ verify(deviceFlowRegistry).retrieveIdForFlow(FlowRegistryKeyFactory.create(flowBld.build()));
+
+ final InOrder inOrder = Mockito.inOrder(txFacade);
+ inOrder.verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(Table.class));
+ inOrder.verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(flowPath), Matchers.any(Flow.class));
}
@Test