/**
* About to stop services in cluster not master anymore or going down
* @return Future most of services need time to be closed
- * @param connectionInterrupted true if clustering services stopping by device disconnect
*/
- default ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ default ListenableFuture<Void> stopClusterServices() {
return Futures.immediateFailedFuture(new RejectedExecutionException("Cannot stop abstract services, check implementation of cluster services"));
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
void setNotificationPublishService(NotificationPublishService notificationPublishService);
+ void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
+
+ void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService);
/**
* Method initializes all DeviceManager, RpcManager and related contexts.
*/
void update(Map<String,Object> props);
- void setClusteringSingletonServicesProvider(ClusterSingletonServiceProvider singletonServicesProvider);
-
void setSkipTableFeatures(boolean skipTableFeatures);
void setBasicTimerDelay(long basicTimerDelay);
void sendNodeAddedNotification();
void sendNodeRemovedNotification();
+
+ void cleanupDeviceData();
}
package org.opendaylight.openflowplugin.api.openflow.device;
import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.openflowplugin.api.openflow.OFPManager;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceConnectedHandler;
OFPManager,
DeviceConnectedHandler,
DeviceDisconnectedHandler,
- TranslatorLibrarian {
+ TranslatorLibrarian,
+ EntityOwnershipListener {
/**
* invoked after all services injected
package org.opendaylight.openflowplugin.api.openflow.lifecycle;
import javax.annotation.CheckForNull;
+
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowplugin.api.openflow.OFPContext;
providerConfig.getThreadPoolMaxThreads().getValue(),
providerConfig.getThreadPoolTimeout());
+ //Set services
openflowPluginProvider.setSwitchConnectionProviders(switchConnectionProviders);
openflowPluginProvider.setDataBroker(dataBroker);
openflowPluginProvider.setRpcProviderRegistry(rpcRegistry);
openflowPluginProvider.setNotificationProviderService(notificationService);
openflowPluginProvider.setNotificationPublishService(notificationPublishService);
+ openflowPluginProvider.setEntityOwnershipServiceProvider(entityOwnershipService);
+ openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider);
+
+ //Set config parameters
openflowPluginProvider.setSwitchFeaturesMandatory(providerConfig.isSwitchFeaturesMandatory());
openflowPluginProvider.setFlowRemovedNotification(providerConfig.isEnableFlowRemovedNotification());
openflowPluginProvider.setIsStatisticsRpcEnabled(providerConfig.isIsStatisticsRpcEnabled());
openflowPluginProvider.setBarrierInterval(providerConfig.getBarrierIntervalTimeoutLimit().getValue());
openflowPluginProvider.setEchoReplyTimeout(providerConfig.getEchoReplyTimeout().getValue());
openflowPluginProvider.setStatisticsPollingOn(providerConfig.isIsStatisticsPollingOn());
- openflowPluginProvider.setClusteringSingletonServicesProvider(singletonServiceProvider);
openflowPluginProvider.setSkipTableFeatures(providerConfig.isSkipTableFeatures());
openflowPluginProvider.setBasicTimerDelay(providerConfig.getBasicTimerDelay().getValue());
openflowPluginProvider.setMaximumTimerDelay(providerConfig.getMaximumTimerDelay().getValue());
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
private ConnectionManager connectionManager;
private NotificationService notificationProviderService;
private NotificationPublishService notificationPublishService;
+ private EntityOwnershipService entityOwnershipService;
+ private ClusterSingletonServiceProvider singletonServicesProvider;
private ExtensionConverterManager extensionConverterManager;
private DataBroker dataBroker;
private Collection<SwitchConnectionProvider> switchConnectionProviders;
private long maximumTimerDelay;
private final ThreadPoolExecutor threadPool;
- private ClusterSingletonServiceProvider singletonServicesProvider;
public OpenFlowPluginProviderImpl(final long rpcRequestsQuota,
final long globalNotificationQuota,
this.singletonServicesProvider = singletonServicesProvider;
}
+ @Override
+ public void setEntityOwnershipServiceProvider(EntityOwnershipService entityOwnershipService) {
+ this.entityOwnershipService = entityOwnershipService;
+ }
+
@Override
public void setSkipTableFeatures(final boolean skipTableFeatures){
this.skipTableFeatures = skipTableFeatures;
getMessageIntelligenceAgency(),
isFlowRemovedNotificationOn,
singletonServicesProvider,
- notificationPublishService,
+ entityOwnershipService,
hashedWheelTimer,
convertorManager,
- skipTableFeatures);
+ skipTableFeatures,
+ notificationPublishService);
((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
final ListenableFuture<Void> deactivateTxManagerFuture = initialized
? transactionChainManager.deactivateTransactionManager()
: Futures.immediateFuture(null);
+ final boolean connectionInterrupted =
+ this.getPrimaryConnectionContext()
+ .getConnectionState()
+ .equals(ConnectionContext.CONNECTION_STATE.RIP);
if (!connectionInterrupted) {
- final 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());
- }
- sendNodeAddedNotification();
- }
-
- @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);
- }
- });
-
- return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
- @Override
- public ListenableFuture<Void> apply(Void aVoid) throws Exception {
- // Add fallback to remove device from operational DS if setting slave fails
- return Futures.withFallback(makeSlaveFuture, t ->
- myManager.removeDeviceFromOperationalDS(deviceInfo));
- }
- });
- } else {
- return Futures.transform(deactivateTxManagerFuture, new AsyncFunction<Void, Void>() {
- @Override
- public ListenableFuture<Void> apply(Void aVoid) throws Exception {
- return myManager.removeDeviceFromOperationalDS(deviceInfo);
- }
- });
+ LOG.info("This controller instance is now acting as a non-owner for node {}", deviceInfo.getLOGValue());
}
+
+ return deactivateTxManagerFuture;
+ }
+
+ @Override
+ public void cleanupDeviceData() {
+ myManager.removeDeviceFromOperationalDS(deviceInfo);
}
@Override
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 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.clustering.EntityOwnershipChange;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
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.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
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.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DeviceManagerImpl implements DeviceManager, ExtensionConverterProviderKeeper {
private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class);
+ private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
private final long globalNotificationQuota;
private final boolean switchFeaturesMandatory;
+ private final EntityOwnershipListenerRegistration eosListenerRegistration;
private boolean isFlowRemovedNotificationOn;
private boolean skipTableFeatures;
private static final int SPY_RATE = 10;
private DeviceTerminationPhaseHandler deviceTerminPhaseHandler;
private final ConcurrentMap<DeviceInfo, DeviceContext> deviceContexts = new ConcurrentHashMap<>();
+ private final ConcurrentMap<DeviceInfo, DeviceContext> removeddeviceContexts = new ConcurrentHashMap<>();
private final ConcurrentMap<DeviceInfo, LifecycleService> lifecycleServices = new ConcurrentHashMap<>();
private long barrierIntervalNanos;
private ExtensionConverterProvider extensionConverterProvider;
private ScheduledThreadPoolExecutor spyPool;
private final ClusterSingletonServiceProvider singletonServiceProvider;
+ private final EntityOwnershipService entityOwnershipService;
private final NotificationPublishService notificationPublishService;
private final MessageSpy messageSpy;
private final HashedWheelTimer hashedWheelTimer;
final MessageSpy messageSpy,
final boolean isFlowRemovedNotificationOn,
final ClusterSingletonServiceProvider singletonServiceProvider,
- final NotificationPublishService notificationPublishService,
+ final EntityOwnershipService entityOwnershipService,
final HashedWheelTimer hashedWheelTimer,
final ConvertorExecutor convertorExecutor,
- final boolean skipTableFeatures) {
+ final boolean skipTableFeatures,
+ final NotificationPublishService notificationPublishService) {
- this.dataBroker = dataBroker;
-
- /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
- final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- final NodesBuilder nodesBuilder = new NodesBuilder();
- nodesBuilder.setNode(Collections.<Node>emptyList());
- tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build());
- try {
- tx.submit().get();
- } catch (ExecutionException | InterruptedException e) {
- LOG.error("Creation of node failed.", e);
- throw new IllegalStateException(e);
- }
+ this.dataBroker = dataBroker;
+ this.entityOwnershipService = entityOwnershipService;
this.switchFeaturesMandatory = switchFeaturesMandatory;
this.globalNotificationQuota = globalNotificationQuota;
this.isFlowRemovedNotificationOn = isFlowRemovedNotificationOn;
this.singletonServiceProvider = singletonServiceProvider;
this.notificationPublishService = notificationPublishService;
this.messageSpy = messageSpy;
+
+ this.eosListenerRegistration = Verify.verifyNotNull(entityOwnershipService.registerListener
+ (SERVICE_ENTITY_TYPE, this));
+
+ /* merge empty nodes to oper DS to predict any problems with missing parent for Node */
+ final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ final NodesBuilder nodesBuilder = new NodesBuilder();
+ nodesBuilder.setNode(Collections.<Node>emptyList());
+ tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodesBuilder.build());
+ try {
+ tx.submit().get();
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("Creation of node failed.", e);
+ throw new IllegalStateException(e);
+ }
}
Optional.ofNullable(spyPool).ifPresent(ScheduledThreadPoolExecutor::shutdownNow);
spyPool = null;
+ if (Objects.nonNull(eosListenerRegistration)) {
+ try {
+ LOG.debug("Closing entity ownership listener");
+ eosListenerRegistration.close();
+ } catch (Exception e) {
+ LOG.debug("Failed to close entity ownership listener registration with exception",e);
+ }
+ }
+
}
@Override
@Override
public CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(final DeviceInfo deviceInfo) {
+ return removeDeviceFromOperationalDS(deviceInfo.getNodeInstanceIdentifier(), deviceInfo.getLOGValue());
+ }
+
+ private CheckedFuture<Void, TransactionCommitFailedException> removeDeviceFromOperationalDS(
+ final KeyedInstanceIdentifier<Node, NodeKey> nodeIid, final String nodeName) {
+ Preconditions.checkNotNull(nodeIid, "Node IID must not be null");
+
final WriteTransaction delWtx = dataBroker.newWriteOnlyTransaction();
- delWtx.delete(LogicalDatastoreType.OPERATIONAL, deviceInfo.getNodeInstanceIdentifier());
+ delWtx.delete(LogicalDatastoreType.OPERATIONAL, nodeIid);
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());
+ LOG.debug("Delete Node {} was successful", nodeName);
}
}
@Override
public void onFailure(@Nonnull final Throwable t) {
- LOG.warn("Delete node {} failed with exception {}", deviceInfo.getLOGValue(), t);
+ LOG.warn("Delete node {} failed with exception {}", nodeName, 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 onDeviceRemoved(DeviceInfo deviceInfo) {
- deviceContexts.remove(deviceInfo);
+ DeviceContext deviceContext = deviceContexts.remove(deviceInfo);
+ removeddeviceContexts.putIfAbsent(deviceInfo, deviceContext);
LOG.debug("Device context removed for node {}", deviceInfo.getLOGValue());
lifecycleServices.remove(deviceInfo);
LOG.debug("Lifecycle service removed for node {}", deviceInfo.getLOGValue());
}
+
+ @Override
+ public void ownershipChanged(EntityOwnershipChange entityOwnershipChange) {
+ if (!entityOwnershipChange.hasOwner()) {
+ final YangInstanceIdentifier yii = entityOwnershipChange.getEntity().getId();
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates niiwp =
+ (YangInstanceIdentifier.NodeIdentifierWithPredicates) yii.getLastPathArgument();
+ String entityName = niiwp.getKeyValues().values().iterator().next().toString();
+ LOG.info("Entity ownership changed for device : {} : {}", entityName, entityOwnershipChange);
+
+ if (entityName != null ){
+ if (!removeddeviceContexts.isEmpty()) {
+ for (DeviceInfo device : removeddeviceContexts.keySet()) {
+ if (device.getNodeId().getValue().equals(entityName)) {
+ LOG.info("Cleaning up operational data of the node : {}", entityName);
+ // No owner present for the entity, clean up the data and remove it from
+ // removed context.
+ removeddeviceContexts.remove(device).cleanupDeviceData();
+ return;
+ }
+ }
+ }
+ removeDeviceFromOperationalDS(DeviceStateUtil.createNodeInstanceIdentifier(new NodeId(entityName)),
+ entityName);
+ }
+ }
+ }
}
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
+
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.slf4j.LoggerFactory;
public class LifecycleServiceImpl implements LifecycleService {
-
private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+
+ private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
+ private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
private DeviceContext deviceContext;
private RpcContext rpcContext;
private StatisticsContext statContext;
private ClusterSingletonServiceRegistration registration;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
- private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
- private volatile CONTEXT_STATE state = CONTEXT_STATE.INITIALIZATION;
@Override
@Override
public ListenableFuture<Void> closeServiceInstance() {
- final boolean connectionInterrupted =
- this.deviceContext
- .getPrimaryConnectionContext()
- .getConnectionState()
- .equals(ConnectionContext.CONNECTION_STATE.RIP);
// 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));
+ futureList.add(statContext.stopClusterServices());
+ futureList.add(rpcContext.stopClusterServices());
+ futureList.add(deviceContext.stopClusterServices());
return Futures.transform(Futures.successfulAsList(futureList), new Function<List<Void>, Void>() {
@Nullable
// If we are still registered and we are not already closing, then close the registration
if (Objects.nonNull(registration)) {
try {
- LOG.debug("Closing clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.debug("Closing clustering singleton services for node {}", getDeviceInfo().getLOGValue());
registration.close();
} catch (Exception e) {
- LOG.debug("Failed to close clustering MASTER services for node {} with exception: ",
+ LOG.debug("Failed to close clustering singleton services for node {} with exception: ",
getDeviceInfo().getLOGValue(), e);
}
}
@Override
public void registerService(final ClusterSingletonServiceProvider singletonServiceProvider) {
- LOG.debug("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.debug("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
// lifecycle service -> device context -> statistics context -> rpc context -> role context -> lifecycle service
this.clusterInitializationPhaseHandler = deviceContext;
// Register cluster singleton service
try {
this.registration = Verify.verifyNotNull(singletonServiceProvider.registerClusterSingletonService(this));
- LOG.info("Registered clustering MASTER services for node {}", getDeviceInfo().getLOGValue());
+ LOG.info("Registered clustering singleton services for node {}", getDeviceInfo().getLOGValue());
} catch (Exception e) {
LOG.warn("Failed to register cluster singleton service for node {}, with exception: {}", getDeviceInfo(), e);
closeConnection();
}
} else {
try {
- stopClusterServices(true).get();
+ stopClusterServices().get();
} catch (Exception e) {
LOG.debug("Failed to close RpcContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
}
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
if (CONTEXT_STATE.TERMINATION.equals(getState())) {
return Futures.immediateCancelledFuture();
}
}
} else {
try {
- stopClusterServices(true).get();
+ stopClusterServices().get();
} catch (Exception e) {
LOG.debug("Failed to close StatisticsContext for node {} with exception: ", getDeviceInfo().getLOGValue(), e);
}
}
@Override
- public ListenableFuture<Void> stopClusterServices(boolean connectionInterrupted) {
+ public ListenableFuture<Void> stopClusterServices() {
if (CONTEXT_STATE.TERMINATION.equals(getState())) {
return Futures.immediateCancelledFuture();
}
provider.setNotificationProviderService(notificationService);
provider.setSwitchConnectionProviders(Lists.newArrayList(switchConnectionProvider));
provider.setClusteringSingletonServicesProvider(clusterSingletonServiceProvider);
+ provider.setEntityOwnershipServiceProvider(entityOwnershipService);
}
@After
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
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.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
@Mock
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
@Mock
+ private EntityOwnershipService entityOwnershipService;
+ @Mock
+ private EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
+ @Mock
private ConvertorExecutor convertorExecutor;
@Mock
private KeyedInstanceIdentifier<Node, NodeKey> key;
when(mockedDataBroker.newWriteOnlyTransaction()).thenReturn(mockedWriteTransaction);
when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
+ when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration);
final DeviceManagerImpl deviceManager = new DeviceManagerImpl(
mockedDataBroker,
messageIntelligenceAgency,
true,
clusterSingletonServiceProvider,
- null,
- new HashedWheelTimer(),
- convertorExecutor,
- false);
+ entityOwnershipService, new HashedWheelTimer(), convertorExecutor, false, null
+ );
deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler);
deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
@Mock
private ClusterSingletonServiceRegistration clusterSingletonServiceRegistration;
+ @Mock
+ EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
private LifecycleService lifecycleService;
Mockito.when(clusterSingletonServiceProvider.registerClusterSingletonService(Mockito.any()))
.thenReturn(clusterSingletonServiceRegistration);
- 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));
+ Mockito.when(deviceContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(statContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
+ Mockito.when(rpcContext.stopClusterServices()).thenReturn(Futures.immediateFuture(null));
lifecycleService = new LifecycleServiceImpl();
lifecycleService.setDeviceContext(deviceContext);
@Test
public void closeServiceInstance() throws Exception {
lifecycleService.closeServiceInstance().get();
- Mockito.verify(statContext).stopClusterServices(false);
- Mockito.verify(deviceContext).stopClusterServices(false);
- Mockito.verify(rpcContext).stopClusterServices(false);
+ Mockito.verify(statContext).stopClusterServices();
+ Mockito.verify(deviceContext).stopClusterServices();
+ Mockito.verify(rpcContext).stopClusterServices();
}
@Test