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.Function;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.HashSet;
15 import java.util.List;
17 import javax.annotation.Nullable;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
20 import org.opendaylight.openflowplugin.api.openflow.OFPContext;
21 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
22 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
23 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChain;
24 import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
25 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
26 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.ContextChainState;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 public class ContextChainImpl implements ContextChain {
33 private static final Logger LOG = LoggerFactory.getLogger(ContextChainImpl.class);
35 private Set<OFPContext> contexts = new HashSet<>();
36 private StatisticsContext statisticsContext;
37 private DeviceContext deviceContext;
38 private RpcContext rpcContext;
39 private volatile ContextChainState contextChainState;
40 private LifecycleService lifecycleService;
41 private ConnectionContext primaryConnectionContext;
43 public ContextChainImpl() {
44 this.contextChainState = ContextChainState.INITIALIZED;
48 public <T extends OFPContext> void addContext(final T context) {
49 if (context instanceof StatisticsContext) {
50 this.statisticsContext = (StatisticsContext) context;
52 if (context instanceof DeviceContext) {
53 this.deviceContext = (DeviceContext) context;
55 if (context instanceof RpcContext) {
56 this.rpcContext = (RpcContext) context;
60 contexts.add(context);
64 public void addLifecycleService(final LifecycleService lifecycleService) {
65 this.lifecycleService = lifecycleService;
69 public ListenableFuture<Void> stopChain(boolean connectionDropped) {
70 //TODO: stopClusterServices change parameter
71 final List<ListenableFuture<Void>> futureList = new ArrayList<>();
72 futureList.add(statisticsContext.stopClusterServices());
73 futureList.add(rpcContext.stopClusterServices());
74 futureList.add(deviceContext.stopClusterServices(connectionDropped));
76 return Futures.transform(Futures.successfulAsList(futureList), new Function<List<Void>, Void>() {
79 public Void apply(@Nullable List<Void> input) {
80 LOG.debug("Closed clustering MASTER services for node {}", deviceContext.getDeviceInfo().getLOGValue());
87 public ListenableFuture<Void> startChain() {
88 if (ContextChainState.INITIALIZED.equals(this.contextChainState)) {
89 return Futures.transform(this.statisticsContext.initialGatherDynamicData(), new Function<Boolean, Void>() {
92 public Void apply(@Nullable Boolean aBoolean) {
93 contextChainState = ContextChainState.WORKINGMASTER;
98 this.contextChainState = ContextChainState.WORKINGMASTER;
100 return Futures.immediateFuture(null);
104 public void close() {
105 deviceContext.close();
107 statisticsContext.close();
108 lifecycleService.close();
112 public void changePrimaryConnection(final ConnectionContext connectionContext) {
113 this.primaryConnectionContext = connectionContext;
114 this.contextChainState = ContextChainState.INITIALIZED;
115 for (OFPContext context : contexts) {
116 context.replaceConnection(connectionContext);
121 public ContextChainState getContextChainState() {
122 return contextChainState;
126 public ListenableFuture<Void> connectionDropped() {
127 ContextChainState oldState = this.contextChainState;
128 this.contextChainState = ContextChainState.SLEEPING;
129 if (oldState.equals(ContextChainState.WORKINGMASTER)) {
130 return this.stopChain(true);
132 return Futures.immediateFuture(null);
136 public void sleepTheChainAndDropConnection() {
137 this.contextChainState = ContextChainState.SLEEPING;
138 this.primaryConnectionContext.closeConnection(true);
142 public void registerServices(@NonNull final ClusterSingletonServiceProvider clusterSingletonServiceProvider) {
143 this.contextChainState = ContextChainState.WORKINGSLAVE;
144 this.lifecycleService.registerService(
145 clusterSingletonServiceProvider,
147 this.deviceContext.getServiceIdentifier(),
148 this.deviceContext.getDeviceInfo());
152 public void makeDeviceSlave() {
153 this.lifecycleService.makeDeviceSlave(this.deviceContext);
157 public void closePrimaryConnection() {
158 this.primaryConnectionContext.closeConnection(true);
162 public DeviceContext provideDeviceContext() {
163 return this.deviceContext;
167 public void sleepTheChain() {
168 this.contextChainState = ContextChainState.SLEEPING;
169 this.stopChain(true);