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.Verify;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.Objects;
15 import java.util.concurrent.ConcurrentHashMap;
16 import javax.annotation.Nonnull;
17 import javax.annotation.Nullable;
18 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
19 import org.opendaylight.openflowplugin.api.openflow.OFPManager;
20 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
21 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionStatus;
22 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
23 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
24 import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager;
25 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChain;
26 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChainHolder;
27 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
28 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
29 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager;
30 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
31 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.ContextChainState;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.openflow.provider.config.ContextChainConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
35 import org.opendaylight.yangtools.yang.common.RpcResult;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class ContextChainHolderImpl implements ContextChainHolder {
41 private static final Logger LOG = LoggerFactory.getLogger(ContextChainHolderImpl.class);
42 private static final String NOT_ALL_MANAGER_WERE_SET = "Not all manager were set.";
43 private static final String MANAGER_WAS_SET = " manager was set";
44 private static final String CONTEXT_CREATED_FOR_CONNECTION = " context created for connection: {}";
45 private static final String SINGLETON_SERVICE_PROVIDER_WAS_NOT_SET_YET
46 = "Singleton service provider was not set yet.";
48 private DeviceManager deviceManager;
49 private RpcManager rpcManager;
50 private StatisticsManager statisticsManager;
51 private ConcurrentHashMap<DeviceInfo, ContextChain> contextChainMap = new ConcurrentHashMap<>();
52 private ConcurrentHashMap<DeviceInfo, ConnectionContext> latestConnections = new ConcurrentHashMap<>();
53 private final ContextChainConfig config;
54 private ClusterSingletonServiceProvider singletonServicesProvider;
56 public ContextChainHolderImpl(final ContextChainConfig config) {
61 public <T extends OFPManager> void addManager(final T manager) {
62 if (Objects.isNull(deviceManager) && manager instanceof DeviceManager) {
63 LOG.info("Device" + MANAGER_WAS_SET);
64 deviceManager = (DeviceManager) manager;
65 } else if (Objects.isNull(rpcManager) && manager instanceof RpcManager) {
66 LOG.info("RPC" + MANAGER_WAS_SET);
67 rpcManager = (RpcManager) manager;
68 } else if (Objects.isNull(statisticsManager) && manager instanceof StatisticsManager) {
69 LOG.info("Statistics" + MANAGER_WAS_SET);
70 statisticsManager = (StatisticsManager) manager;
75 public ContextChain createContextChain(final ConnectionContext connectionContext) {
77 final DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
78 final String deviceInfoLOGValue = deviceInfo.getLOGValue();
80 if (LOG.isDebugEnabled()) {
81 LOG.debug("Creating a new chain" + CONTEXT_CREATED_FOR_CONNECTION, deviceInfoLOGValue);
84 ContextChain contextChain = new ContextChainImpl();
85 LifecycleService lifecycleService = new LifecycleServiceImpl(this);
87 if (LOG.isDebugEnabled()) {
88 LOG.debug("Lifecycle services" + CONTEXT_CREATED_FOR_CONNECTION, deviceInfoLOGValue);
91 final DeviceContext deviceContext = deviceManager.createContext(connectionContext);
93 if (LOG.isDebugEnabled()) {
94 LOG.debug("Device" + CONTEXT_CREATED_FOR_CONNECTION, deviceInfoLOGValue);
97 final RpcContext rpcContext = rpcManager.createContext(connectionContext.getDeviceInfo(), deviceContext);
99 if (LOG.isDebugEnabled()) {
100 LOG.debug("RPC" + CONTEXT_CREATED_FOR_CONNECTION, deviceInfoLOGValue);
103 final StatisticsContext statisticsContext
104 = statisticsManager.createContext(deviceContext);
106 if (LOG.isDebugEnabled()) {
107 LOG.debug("Statistics" + CONTEXT_CREATED_FOR_CONNECTION, deviceInfoLOGValue);
110 deviceContext.setLifecycleInitializationPhaseHandler(statisticsContext);
111 statisticsContext.setLifecycleInitializationPhaseHandler(rpcContext);
112 statisticsContext.setInitialSubmitHandler(deviceContext);
114 contextChain.addLifecycleService(lifecycleService);
115 contextChain.addContext(deviceContext);
116 contextChain.addContext(rpcContext);
117 contextChain.addContext(statisticsContext);
118 contextChain.makeDeviceSlave();
125 public ListenableFuture<Void> connectionLost(final DeviceInfo deviceInfo) {
126 if (!this.checkChainContext(deviceInfo)) {
127 return Futures.immediateFuture(null);
133 public void destroyContextChain(final DeviceInfo deviceInfo) {
134 ContextChain chain = contextChainMap.get(deviceInfo);
135 if (Objects.nonNull(chain)) {
141 public void pairConnection(final ConnectionContext connectionContext) {
142 DeviceInfo deviceInfo = connectionContext.getDeviceInfo();
143 latestConnections.put(deviceInfo, connectionContext);
144 if (checkChainContext(deviceInfo)) {
145 contextChainMap.get(deviceInfo).changePrimaryConnection(connectionContext);
150 public ConnectionStatus deviceConnected(final ConnectionContext connectionContext) throws Exception {
152 Verify.verify(this.checkAllManagers(), NOT_ALL_MANAGER_WERE_SET);
153 Verify.verifyNotNull(this.singletonServicesProvider, SINGLETON_SERVICE_PROVIDER_WAS_NOT_SET_YET);
155 LOG.info("Device {} connected.", connectionContext.getDeviceInfo().getLOGValue());
156 ContextChain chain = contextChainMap.get(connectionContext.getDeviceInfo());
158 if (Objects.isNull(chain)) {
159 contextChainMap.put(connectionContext.getDeviceInfo(), createContextChain(connectionContext));
161 this.pairConnection(connectionContext);
164 return ConnectionStatus.MAY_CONTINUE;
168 public void addSingletonServicesProvider(final ClusterSingletonServiceProvider singletonServicesProvider) {
169 this.singletonServicesProvider = singletonServicesProvider;
173 public void onNotAbleToStartMastership(final DeviceInfo deviceInfo) {
174 ContextChain contextChain = contextChainMap.get(deviceInfo);
175 if (Objects.nonNull(contextChain)) {
176 LOG.warn("Not able to set MASTER role on device {}", deviceInfo.getLOGValue());
177 if (contextChain.getContextChainState().equals(ContextChainState.INITIALIZED)) {
178 contextChain.getPrimaryConnectionContext().closeConnection(false);
180 contextChain.sleepTheChainAndDropConnection();
186 public void onMasterRoleAcquired(final DeviceInfo deviceInfo) {
187 ContextChain contextChain = contextChainMap.get(deviceInfo);
188 if (Objects.nonNull(contextChain)) {
189 if (contextChain.getContextChainState().equals(ContextChainState.WORKINGMASTER)) {
190 if (LOG.isDebugEnabled()) {
191 LOG.debug("Device {} already working as MASTER no changes need to be done.",
192 deviceInfo.getLOGValue());
195 if (contextChain.getContextChainState().equals(ContextChainState.INITIALIZED)) {
196 LOG.info("Device {} has not finish initial gathering yet.",
197 deviceInfo.getLOGValue());
199 contextChain.startChain();
205 public void onSlaveRoleAcquired(final DeviceInfo deviceInfo) {
206 ContextChain contextChain = contextChainMap.get(deviceInfo);
207 if (Objects.nonNull(contextChain)) {
208 if (contextChain.getContextChainState().equals(ContextChainState.INITIALIZED)) {
209 contextChain.registerServices(this.singletonServicesProvider);
211 contextChain.stopChain();
217 public void onSlaveRoleNotAcquired(final DeviceInfo deviceInfo) {
218 ContextChain contextChain = contextChainMap.get(deviceInfo);
219 if (Objects.nonNull(contextChain)) {
220 contextChain.sleepTheChainAndDropConnection();
224 private boolean checkAllManagers() {
225 return Objects.nonNull(deviceManager) && Objects.nonNull(rpcManager) && Objects.nonNull(statisticsManager);
228 private boolean checkChainContext(final DeviceInfo deviceInfo) {
229 return contextChainMap.containsKey(deviceInfo);