2 * Copyright (c) 2017 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 static com.google.common.util.concurrent.Service.State.FAILED;
11 import static com.google.common.util.concurrent.Service.State.NEW;
12 import static com.google.common.util.concurrent.Service.State.RUNNING;
13 import static com.google.common.util.concurrent.Service.State.STARTING;
14 import static com.google.common.util.concurrent.Service.State.STOPPING;
15 import static com.google.common.util.concurrent.Service.State.TERMINATED;
17 import com.google.common.util.concurrent.FutureCallback;
18 import com.google.common.util.concurrent.Futures;
19 import com.google.common.util.concurrent.ListenableFuture;
20 import com.google.common.util.concurrent.Monitor;
21 import com.google.common.util.concurrent.Monitor.Guard;
22 import com.google.common.util.concurrent.MoreExecutors;
23 import com.google.common.util.concurrent.Service;
24 import java.util.function.Function;
25 import javax.annotation.Nonnull;
26 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
27 import org.opendaylight.openflowplugin.api.openflow.OFPContext;
28 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
29 import org.opendaylight.openflowplugin.api.openflow.lifecycle.ContextChainMastershipWatcher;
30 import org.opendaylight.openflowplugin.api.openflow.lifecycle.GuardedContext;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public class GuardedContextImpl implements GuardedContext {
35 private static final Logger LOG = LoggerFactory.getLogger(GuardedContextImpl.class);
37 private final Monitor monitor = new Monitor();
38 private final OFPContext delegate;
39 private Service.State state = NEW;
41 private final Guard isStartable = new Guard(monitor) {
43 public boolean isSatisfied() {
44 return state == NEW || state == TERMINATED;
48 private final Guard isStoppable = new Guard(monitor) {
50 public boolean isSatisfied() {
51 return state.compareTo(RUNNING) <= 0;
55 private final Guard isCloseable = new Guard(monitor) {
57 public boolean isSatisfied() {
58 return state != FAILED;
62 GuardedContextImpl(final OFPContext delegate) {
63 this.delegate = delegate;
67 public Service.State state() {
69 final Service.State stateSnapshot = state;
75 public <T> T map(final Function<OFPContext, T> transformer) {
76 return transformer.apply(delegate);
80 public void instantiateServiceInstance() {
81 if (monitor.enterIf(isStartable)) {
83 LOG.info("Starting {} service for node {}", this, getDeviceInfo());
85 delegate.instantiateServiceInstance();
91 throw new IllegalStateException("Service " + this + " has already been started");
96 @SuppressWarnings("checkstyle:IllegalCatch")
97 public ListenableFuture<?> closeServiceInstance() {
98 ListenableFuture<?> result = Futures.immediateFuture(null);
100 if (monitor.enterIf(isStoppable)) {
102 LOG.info("Stopping {} service for node {}", this, getDeviceInfo());
104 final ListenableFuture<?> resultFuture = delegate.closeServiceInstance();
106 Futures.addCallback(resultFuture, new FutureCallback<Object>() {
108 public void onSuccess(final Object result) {
113 public void onFailure(final Throwable throwable) {
116 }, MoreExecutors.directExecutor());
118 result = resultFuture;
119 } catch (final Exception e) {
120 result = Futures.immediateFailedFuture(e);
132 public ServiceGroupIdentifier getIdentifier() {
133 return delegate.getIdentifier();
137 public String toString() {
138 return delegate.getClass().getSimpleName() + "[" + state + "]";
142 public DeviceInfo getDeviceInfo() {
143 return delegate.getDeviceInfo();
147 public void registerMastershipWatcher(@Nonnull final ContextChainMastershipWatcher contextChainMastershipWatcher) {
148 delegate.registerMastershipWatcher(contextChainMastershipWatcher);
152 public void close() {
153 if (monitor.enterIf(isCloseable)) {
155 LOG.info("Terminating {} service for node {}", this, getDeviceInfo());