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 javax.annotation.Nonnull;
18 import javax.annotation.concurrent.GuardedBy;
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.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
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 RpcProviderRegistry rpcProviderRegistry;
47 private final BundleContext bundleContext;
48 private final ClusterSingletonServiceProvider cssp;
49 private final TopologySessionStatsRegistry stateRegistry;
51 private PCEPTopologyProviderBeanCSS pcepTopoProviderCSS;
53 public PCEPTopologyProviderBean(
54 final ClusterSingletonServiceProvider cssp,
55 final BundleContext bundleContext,
56 final DataBroker dataBroker,
57 final PCEPDispatcher pcepDispatcher,
58 final RpcProviderRegistry rpcProviderRegistry,
59 final TopologySessionListenerFactory sessionListenerFactory,
60 final TopologySessionStatsRegistry stateRegistry) {
61 this.cssp = requireNonNull(cssp);
62 this.bundleContext = requireNonNull(bundleContext);
63 this.pcepDispatcher = requireNonNull(pcepDispatcher);
64 this.dataBroker = requireNonNull(dataBroker);
65 this.sessionListenerFactory = requireNonNull(sessionListenerFactory);
66 this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
67 this.stateRegistry = requireNonNull(stateRegistry);
68 final List<PCEPCapability> capabilities = this.pcepDispatcher.getPCEPSessionNegotiatorFactory()
69 .getPCEPSessionProposalFactory().getCapabilities();
70 final boolean statefulCapability = capabilities.stream().anyMatch(PCEPCapability::isStateful);
71 if (!statefulCapability) {
72 throw new IllegalStateException(STATEFUL_NOT_DEFINED);
76 synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
77 if (this.pcepTopoProviderCSS != null) {
78 return this.pcepTopoProviderCSS.closeServiceInstance();
80 return CommitInfo.emptyFluentFuture();
84 public synchronized void close() throws Exception {
85 if (this.pcepTopoProviderCSS != null) {
86 this.pcepTopoProviderCSS.close();
87 this.pcepTopoProviderCSS = null;
91 @SuppressWarnings("checkstyle:IllegalCatch")
92 synchronized void start(final PCEPTopologyConfiguration configDependencies,
93 final InstructionScheduler instructionScheduler) {
94 Preconditions.checkState(this.pcepTopoProviderCSS == null,
95 "Previous instance %s was not closed.", this);
97 this.pcepTopoProviderCSS = new PCEPTopologyProviderBeanCSS(configDependencies,
98 instructionScheduler, this);
99 } catch (final Exception e) {
100 LOG.debug("Failed to create PCEPTopologyProvider {}", configDependencies.getTopologyId().getValue(), e);
105 public PCEPDispatcher getPCEPDispatcher() {
106 return this.pcepDispatcher;
110 public RpcProviderRegistry getRpcProviderRegistry() {
111 return this.rpcProviderRegistry;
115 public DataBroker getDataBroker() {
116 return this.dataBroker;
120 public TopologySessionListenerFactory getTopologySessionListenerFactory() {
121 return this.sessionListenerFactory;
125 public TopologySessionStatsRegistry getStateRegistry() {
126 return this.stateRegistry;
129 private static class PCEPTopologyProviderBeanCSS implements ClusterSingletonService, AutoCloseable {
130 private final ServiceGroupIdentifier sgi;
131 private final PCEPTopologyProvider pcepTopoProvider;
132 private final InstructionScheduler scheduler;
133 private ServiceRegistration<?> serviceRegistration;
134 private ClusterSingletonServiceRegistration cssRegistration;
136 private boolean serviceInstantiated;
138 PCEPTopologyProviderBeanCSS(final PCEPTopologyConfiguration configDependencies,
139 final InstructionScheduler instructionScheduler, final PCEPTopologyProviderBean bean) {
140 this.scheduler = instructionScheduler;
141 this.sgi = this.scheduler.getIdentifier();
142 this.pcepTopoProvider = PCEPTopologyProvider.create(bean, this.scheduler, configDependencies);
144 final Dictionary<String, String> properties = new Hashtable<>();
145 properties.put(PCEPTopologyProvider.class.getName(), configDependencies.getTopologyId().getValue());
146 this.serviceRegistration = bean.bundleContext
147 .registerService(DefaultTopologyReference.class.getName(), this.pcepTopoProvider, properties);
148 LOG.info("PCEP Topology Provider service {} registered", getIdentifier().getValue());
149 this.cssRegistration = bean.cssp.registerClusterSingletonService(this);
153 @SuppressWarnings("checkstyle:IllegalCatch")
154 public synchronized void instantiateServiceInstance() {
155 LOG.info("PCEP Topology Provider Singleton Service {} instantiated", getIdentifier().getValue());
157 this.pcepTopoProvider.instantiateServiceInstance();
158 } catch (final Exception e) {
159 LOG.error("Failed to instantiate PCEP Topology provider", e);
161 this.serviceInstantiated = true;
165 public synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
166 LOG.info("Close PCEP Topology Provider Singleton Service {}", getIdentifier().getValue());
167 if (this.serviceInstantiated) {
168 this.serviceInstantiated = false;
169 return this.pcepTopoProvider.closeServiceInstance();
171 return CommitInfo.emptyFluentFuture();
176 public ServiceGroupIdentifier getIdentifier() {
181 public synchronized void close() throws Exception {
182 if (this.cssRegistration != null) {
183 this.cssRegistration.close();
184 this.cssRegistration = null;
186 if (this.serviceRegistration != null) {
187 this.serviceRegistration.unregister();
188 this.serviceRegistration = null;
190 this.scheduler.close();