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.bgpcep.pcep.topology.provider.config;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.FluentFuture;
14 import java.util.Dictionary;
15 import java.util.Hashtable;
16 import java.util.List;
17 import org.checkerframework.checker.lock.qual.GuardedBy;
18 import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
19 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
20 import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
21 import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
22 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
23 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
24 import org.opendaylight.mdsal.binding.api.DataBroker;
25 import org.opendaylight.mdsal.binding.api.RpcProviderService;
26 import org.opendaylight.mdsal.common.api.CommitInfo;
27 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
28 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
29 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
30 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
31 import org.opendaylight.protocol.pcep.PCEPCapability;
32 import org.opendaylight.protocol.pcep.PCEPDispatcher;
33 import org.osgi.framework.BundleContext;
34 import org.osgi.framework.ServiceRegistration;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDependencies, AutoCloseable {
39 private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProviderBean.class);
41 private static final String STATEFUL_NOT_DEFINED =
42 "Stateful capability not defined, aborting PCEP Topology Deployer instantiation";
43 private final PCEPDispatcher pcepDispatcher;
44 private final DataBroker dataBroker;
45 private final TopologySessionListenerFactory sessionListenerFactory;
46 private final RpcProviderService rpcProviderRegistry;
47 private final BundleContext bundleContext;
48 private final ClusterSingletonServiceProvider cssp;
49 private final TopologySessionStatsRegistry stateRegistry;
50 private final PceServerProvider pceServerProvider;
52 private PCEPTopologyProviderBeanCSS pcepTopoProviderCSS;
54 public PCEPTopologyProviderBean(
55 final ClusterSingletonServiceProvider cssp,
56 final BundleContext bundleContext,
57 final DataBroker dataBroker,
58 final PCEPDispatcher pcepDispatcher,
59 final RpcProviderService rpcProviderRegistry,
60 final TopologySessionListenerFactory sessionListenerFactory,
61 final TopologySessionStatsRegistry stateRegistry,
62 final PceServerProvider pceServerProvider) {
63 this.cssp = requireNonNull(cssp);
64 this.bundleContext = requireNonNull(bundleContext);
65 this.pcepDispatcher = requireNonNull(pcepDispatcher);
66 this.dataBroker = requireNonNull(dataBroker);
67 this.sessionListenerFactory = requireNonNull(sessionListenerFactory);
68 this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
69 this.stateRegistry = requireNonNull(stateRegistry);
70 this.pceServerProvider = requireNonNull(pceServerProvider);
71 final List<PCEPCapability> capabilities = this.pcepDispatcher.getPCEPSessionNegotiatorFactory()
72 .getPCEPSessionProposalFactory().getCapabilities();
73 final boolean statefulCapability = capabilities.stream().anyMatch(PCEPCapability::isStateful);
74 if (!statefulCapability) {
75 throw new IllegalStateException(STATEFUL_NOT_DEFINED);
79 synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
80 if (this.pcepTopoProviderCSS != null) {
81 return this.pcepTopoProviderCSS.closeServiceInstance();
83 return CommitInfo.emptyFluentFuture();
87 public synchronized void close() throws Exception {
88 if (this.pcepTopoProviderCSS != null) {
89 this.pcepTopoProviderCSS.close();
90 this.pcepTopoProviderCSS = null;
94 @SuppressWarnings("checkstyle:IllegalCatch")
95 synchronized void start(final PCEPTopologyConfiguration configDependencies,
96 final InstructionScheduler instructionScheduler) {
97 Preconditions.checkState(this.pcepTopoProviderCSS == null,
98 "Previous instance %s was not closed.", this);
100 this.pcepTopoProviderCSS = new PCEPTopologyProviderBeanCSS(configDependencies,
101 instructionScheduler, this);
102 } catch (final Exception e) {
103 LOG.debug("Failed to create PCEPTopologyProvider {}", configDependencies.getTopologyId().getValue(), e);
108 public PCEPDispatcher getPCEPDispatcher() {
109 return this.pcepDispatcher;
113 public RpcProviderService getRpcProviderRegistry() {
114 return this.rpcProviderRegistry;
118 public DataBroker getDataBroker() {
119 return this.dataBroker;
123 public TopologySessionListenerFactory getTopologySessionListenerFactory() {
124 return this.sessionListenerFactory;
128 public TopologySessionStatsRegistry getStateRegistry() {
129 return this.stateRegistry;
133 public PceServerProvider getPceServerProvider() {
134 return this.pceServerProvider;
137 private static class PCEPTopologyProviderBeanCSS implements ClusterSingletonService, AutoCloseable {
138 private final ServiceGroupIdentifier sgi;
139 private final PCEPTopologyProvider pcepTopoProvider;
140 private final InstructionScheduler scheduler;
141 private ServiceRegistration<?> serviceRegistration;
142 private ClusterSingletonServiceRegistration cssRegistration;
144 private boolean serviceInstantiated;
146 PCEPTopologyProviderBeanCSS(final PCEPTopologyConfiguration configDependencies,
147 final InstructionScheduler instructionScheduler, final PCEPTopologyProviderBean bean) {
148 this.scheduler = instructionScheduler;
149 this.sgi = this.scheduler.getIdentifier();
150 this.pcepTopoProvider = PCEPTopologyProvider.create(bean, this.scheduler, configDependencies);
152 final Dictionary<String, String> properties = new Hashtable<>();
153 properties.put(PCEPTopologyProvider.class.getName(), configDependencies.getTopologyId().getValue());
154 this.serviceRegistration = bean.bundleContext
155 .registerService(DefaultTopologyReference.class.getName(), this.pcepTopoProvider, properties);
156 LOG.info("PCEP Topology Provider service {} registered", getIdentifier().getName());
157 this.cssRegistration = bean.cssp.registerClusterSingletonService(this);
161 @SuppressWarnings("checkstyle:IllegalCatch")
162 public synchronized void instantiateServiceInstance() {
163 LOG.info("PCEP Topology Provider Singleton Service {} instantiated", getIdentifier().getName());
165 this.pcepTopoProvider.instantiateServiceInstance();
166 } catch (final Exception e) {
167 LOG.error("Failed to instantiate PCEP Topology provider", e);
169 this.serviceInstantiated = true;
173 public synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
174 LOG.info("Close PCEP Topology Provider Singleton Service {}", getIdentifier().getName());
175 if (this.serviceInstantiated) {
176 this.serviceInstantiated = false;
177 return this.pcepTopoProvider.closeServiceInstance();
179 return CommitInfo.emptyFluentFuture();
183 public ServiceGroupIdentifier getIdentifier() {
188 public synchronized void close() throws Exception {
189 if (this.cssRegistration != null) {
190 this.cssRegistration.close();
191 this.cssRegistration = null;
193 if (this.serviceRegistration != null) {
194 this.serviceRegistration.unregister();
195 this.serviceRegistration = null;
197 this.scheduler.close();