2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.impl.lifecycle;
10 import com.google.common.base.MoreObjects;
11 import com.google.common.base.Verify;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Objects;
18 import java.util.concurrent.ExecutorService;
19 import javax.annotation.Nonnull;
20 import javax.annotation.Nullable;
21 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
22 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
23 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
24 import org.opendaylight.openflowplugin.api.openflow.OFPContext.ContextState;
25 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
26 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
27 import org.opendaylight.openflowplugin.api.openflow.device.handlers.ClusterInitializationPhaseHandler;
28 import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceRemovedHandler;
29 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
30 import org.opendaylight.openflowplugin.api.openflow.lifecycle.MastershipChangeListener;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
32 import org.opendaylight.yangtools.yang.common.RpcResult;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 public class LifecycleServiceImpl implements LifecycleService {
38 private static final Logger LOG = LoggerFactory.getLogger(LifecycleServiceImpl.class);
40 private final List<DeviceRemovedHandler> deviceRemovedHandlers = new ArrayList<>();
41 private final MastershipChangeListener mastershipChangeListener;
42 private final ExecutorService executorService;
43 private ClusterSingletonServiceRegistration registration;
44 private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
45 private ServiceGroupIdentifier serviceGroupIdentifier;
46 private DeviceInfo deviceInfo;
47 private volatile ContextState state = ContextState.INITIALIZATION;
49 public LifecycleServiceImpl(@Nonnull final MastershipChangeListener mastershipChangeListener,
50 @Nonnull final ExecutorService executorService) {
51 this.mastershipChangeListener = mastershipChangeListener;
52 this.executorService = executorService;
56 public void makeDeviceSlave(final DeviceContext deviceContext) {
57 deviceInfo = MoreObjects.firstNonNull(deviceInfo, deviceContext.getDeviceInfo());
59 Futures.addCallback(deviceContext.makeDeviceSlave(), new FutureCallback<RpcResult<SetRoleOutput>>() {
61 public void onSuccess(@Nullable RpcResult<SetRoleOutput> setRoleOutputRpcResult) {
62 if (LOG.isDebugEnabled()) {
63 LOG.debug("Role SLAVE was successfully propagated on device, node {}",
64 deviceContext.getDeviceInfo().getLOGValue());
66 mastershipChangeListener.onSlaveRoleAcquired(deviceInfo);
70 public void onFailure(@Nonnull Throwable throwable) {
71 LOG.warn("Was not able to set role SLAVE to device on node {} ",
72 deviceContext.getDeviceInfo().getLOGValue());
73 mastershipChangeListener.onSlaveRoleNotAcquired(deviceInfo);
79 public void instantiateServiceInstance() {
80 executorService.submit(() -> {
81 LOG.info("Starting clustering services for node {}", deviceInfo.getLOGValue());
83 if (!clusterInitializationPhaseHandler.onContextInstantiateService(mastershipChangeListener)) {
84 mastershipChangeListener.onNotAbleToStartMastershipMandatory(deviceInfo, "Cannot initialize device.");
90 public ListenableFuture<Void> closeServiceInstance() {
91 LOG.info("Closing clustering services for node {}", deviceInfo.getLOGValue());
92 return Futures.immediateFuture(null);
97 public ServiceGroupIdentifier getIdentifier() {
98 return this.serviceGroupIdentifier;
102 public void close() {
103 if (ContextState.TERMINATION.equals(state)) {
104 if (LOG.isDebugEnabled()) {
105 LOG.debug("LifecycleService for node {} is already in TERMINATION state.", deviceInfo.getLOGValue());
108 state = ContextState.TERMINATION;
110 // We are closing, so cleanup all managers now
111 deviceRemovedHandlers.forEach(h -> h.onDeviceRemoved(deviceInfo));
113 // If we are still registered and we are not already closing, then close the registration
114 if (Objects.nonNull(registration)) {
116 LOG.info("Closing clustering services registration for node {}", deviceInfo.getLOGValue());
117 registration.close();
119 } catch (final Exception e) {
120 LOG.warn("Failed to close clustering services registration for node {} with exception: ",
121 deviceInfo.getLOGValue(), e);
128 public void registerService(@Nonnull final ClusterSingletonServiceProvider singletonServiceProvider,
129 @Nonnull final DeviceContext deviceContext) {
130 Verify.verify(Objects.isNull(registration));
131 this.clusterInitializationPhaseHandler = deviceContext;
132 this.serviceGroupIdentifier = deviceContext.getServiceIdentifier();
133 this.deviceInfo = deviceContext.getDeviceInfo();
134 this.registration = Verify.verifyNotNull(
135 singletonServiceProvider.registerClusterSingletonService(this));
137 LOG.info("Registered clustering services for node {}", deviceInfo.getLOGValue());
141 public void registerDeviceRemovedHandler(@Nonnull final DeviceRemovedHandler deviceRemovedHandler) {
142 if (!deviceRemovedHandlers.contains(deviceRemovedHandler)) {
143 deviceRemovedHandlers.add(deviceRemovedHandler);