*/
package org.opendaylight.openflowplugin.impl.lifecycle;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Verify;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.ExecutorService;
import javax.annotation.Nonnull;
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.opendaylight.openflowplugin.api.openflow.OFPContext.ContextState;
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;
private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
+ private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
+ private final MastershipChangeListener mastershipChangeListener;
+ private final ExecutorService executorService;
private ClusterSingletonServiceRegistration registration;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
- private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
private ServiceGroupIdentifier serviceGroupIdentifier;
private DeviceInfo deviceInfo;
- private boolean terminationState = false;
- private final MastershipChangeListener mastershipChangeListener;
-
+ private volatile ContextState state = ContextState.INITIALIZATION;
- public LifecycleServiceImpl(@Nonnull final MastershipChangeListener mastershipChangeListener) {
+ public LifecycleServiceImpl(@Nonnull final MastershipChangeListener mastershipChangeListener,
+ @Nonnull final ExecutorService executorService) {
this.mastershipChangeListener = mastershipChangeListener;
+ this.executorService = executorService;
}
@Override
public void makeDeviceSlave(final DeviceContext deviceContext) {
-
- final DeviceInfo deviceInf = Objects.isNull(deviceInfo) ? deviceContext.getDeviceInfo() : deviceInfo;
+ deviceInfo = MoreObjects.firstNonNull(deviceInfo, deviceContext.getDeviceInfo());
Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
@Override
LOG.debug("Role SLAVE was successfully propagated on device, node {}",
deviceContext.getDeviceInfo().getLOGValue());
}
- mastershipChangeListener.onSlaveRoleAcquired(deviceInf);
+ mastershipChangeListener.onSlaveRoleAcquired(deviceInfo);
}
@Override
- public void onFailure(Throwable throwable) {
+ public void onFailure(@Nonnull Throwable throwable) {
LOG.warn("Was not able to set role SLAVE to device on node {} ",
deviceContext.getDeviceInfo().getLOGValue());
- mastershipChangeListener.onSlaveRoleNotAcquired(deviceInf);
+ mastershipChangeListener.onSlaveRoleNotAcquired(deviceInfo);
}
});
-
}
@Override
public void instantiateServiceInstance() {
+ executorService.submit(() -> {
+ LOG.info("Starting clustering services for node {}", deviceInfo.getLOGValue());
- LOG.info("Starting clustering MASTER services for node {}", deviceInfo.getLOGValue());
- if (!clusterInitializationPhaseHandler.onContextInstantiateService(mastershipChangeListener)) {
- mastershipChangeListener.onNotAbleToStartMastershipMandatory(deviceInfo, "Cannot initialize device.");
- }
+ if (!clusterInitializationPhaseHandler.onContextInstantiateService(mastershipChangeListener)) {
+ mastershipChangeListener.onNotAbleToStartMastershipMandatory(deviceInfo, "Cannot initialize device.");
+ }
+ });
}
@Override
public ListenableFuture<Void> closeServiceInstance() {
+ LOG.info("Closing clustering services for node {}", deviceInfo.getLOGValue());
return Futures.immediateFuture(null);
}
@Override
public void close() {
- if (terminationState) {
+ if (ContextState.TERMINATION.equals(state)) {
if (LOG.isDebugEnabled()) {
- LOG.debug("LifecycleService is already in TERMINATION state.");
+ LOG.debug("LifecycleService for node {} is already in TERMINATION state.", deviceInfo.getLOGValue());
}
} else {
- this.terminationState = true;
+ state = ContextState.TERMINATION;
// We are closing, so cleanup all managers now
deviceRemovedHandlers.forEach(h -> h.onDeviceRemoved(deviceInfo));
// If we are still registered and we are not already closing, then close the registration
if (Objects.nonNull(registration)) {
try {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Closing clustering services for node {}", deviceInfo.getLOGValue());
- }
+ LOG.info("Closing clustering services registration for node {}", deviceInfo.getLOGValue());
registration.close();
+ registration = null;
} catch (final Exception e) {
- LOG.warn("Failed to close clustering services for node {} with exception: ",
+ LOG.warn("Failed to close clustering services registration for node {} with exception: ",
deviceInfo.getLOGValue(), e);
}
}
@Override
public void registerService(@Nonnull final ClusterSingletonServiceProvider singletonServiceProvider,
@Nonnull final DeviceContext deviceContext) {
-
+ Verify.verify(Objects.isNull(registration));
this.clusterInitializationPhaseHandler = deviceContext;
this.serviceGroupIdentifier = deviceContext.getServiceIdentifier();
this.deviceInfo = deviceContext.getDeviceInfo();
singletonServiceProvider.registerClusterSingletonService(this));
LOG.info("Registered clustering services for node {}", deviceInfo.getLOGValue());
-
}
@Override