2 * Copyright (c) 2020 Orange. 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.server.provider;
10 import static java.util.Objects.requireNonNull;
12 import java.util.HashMap;
14 import javax.annotation.PreDestroy;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.algo.PathComputationProvider;
19 import org.opendaylight.bgpcep.pcep.server.PathComputation;
20 import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
21 import org.opendaylight.graph.ConnectedGraph;
22 import org.opendaylight.graph.ConnectedGraphProvider;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev220720.graph.topology.GraphKey;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
29 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
30 import org.osgi.service.component.annotations.Activate;
31 import org.osgi.service.component.annotations.Component;
32 import org.osgi.service.component.annotations.Deactivate;
33 import org.osgi.service.component.annotations.Reference;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
39 @Component(immediate = true)
40 public final class DefaultPceServerProvider implements PceServerProvider, AutoCloseable {
41 private static final Logger LOG = LoggerFactory.getLogger(DefaultPceServerProvider.class);
42 private final ConnectedGraphProvider graphProvider;
43 private final PathComputationProvider algoProvider;
44 private final DataBroker dataBroker;
45 private final RpcConsumerRegistry rpcRegistry;
46 private Map<TopologyId, PathManagerProvider> pathManagers = new HashMap<TopologyId, PathManagerProvider>();
47 private Map<TopologyId, PathManagerListener> pathListeners = new HashMap<TopologyId, PathManagerListener>();
48 private Map<TopologyId, PcepTopologyListener> pcepListeners = new HashMap<TopologyId, PcepTopologyListener>();
49 private volatile ConnectedGraph tedGraph;
50 private volatile GraphKey graphKey;
54 public DefaultPceServerProvider(@Reference final ConnectedGraphProvider graphProvider,
55 @Reference final PathComputationProvider pathComputationProvider,
56 @Reference final DataBroker dataBroker,
57 @Reference final RpcConsumerRegistry rpcConsumerRegistry) {
58 this.graphProvider = requireNonNull(graphProvider);
59 this.algoProvider = requireNonNull(pathComputationProvider);
60 this.dataBroker = requireNonNull(dataBroker);
61 this.rpcRegistry = requireNonNull(rpcConsumerRegistry);
68 for (PathManagerListener pathListener: pathListeners.values()) {
72 pathListeners.clear();
73 for (PcepTopologyListener pcepListener: pcepListeners.values()) {
77 pcepListeners.clear();
78 for (PathManagerProvider pathManager: pathManagers.values()) {
85 private void closeListenerAndManager(TopologyId key) {
87 PathManagerListener pathListener = pathListeners.remove(key);
88 if (pathListener != null) {
91 PcepTopologyListener pcepListener = pcepListeners.remove(key);
92 if (pcepListener != null) {
95 PathManagerProvider pathManager = pathManagers.remove(key);
96 if (pathManager != null) {
102 public @Nullable PathComputation getPathComputation() {
103 /* Check that we have a valid graph */
104 final ConnectedGraph graph = getTedGraph();
105 return graph == null ? null : new PathComputationImpl(tedGraph, algoProvider);
108 public ConnectedGraph getTedGraph() {
109 /* Leave a chance to get a valid Graph in case of late fulfillment */
110 if (tedGraph == null) {
117 * Set Traffic Engineering Graph. This method is necessary as the TedGraph could be available
118 * after the PathComputationFactory start e.g. manual insertion of a ted Graph, or late tedGraph fulfillment
119 * from BGP Link State.
121 private void setTedGraph() {
122 tedGraph = graphProvider.getConnectedGraph(graphKey);
126 public void registerPcepTopology(KeyedInstanceIdentifier<Topology, TopologyKey> topology, GraphKey key) {
127 TopologyId topoKey = requireNonNull(topology).getKey().getTopologyId();
128 this.graphKey = requireNonNull(key);
130 LOG.info("Start PCE Server components for Topology {} with TED {}", topoKey.getValue(), graphKey.getName());
132 /* First close current Listener & Manager if there are active */
133 closeListenerAndManager(topoKey);
135 /* Then create Path Manger */
136 PathManagerProvider pathManager = new PathManagerProvider(dataBroker, topology, rpcRegistry, this);
139 PathManagerListener pathListener = new PathManagerListener(dataBroker, topology, pathManager);
140 PcepTopologyListener pcepListener = new PcepTopologyListener(dataBroker, topology, pathManager);
142 /* Finally, register all of them for later deletion */
143 pathManagers.put(topoKey, pathManager);
144 pathListeners.put(topoKey, pathListener);
145 pcepListeners.put(topoKey, pcepListener);
149 public void unRegisterPcepTopology(KeyedInstanceIdentifier<Topology, TopologyKey> topology) {
150 TopologyId topoKey = requireNonNull(topology).getKey().getTopologyId();
151 this.graphKey = null;
153 LOG.info("Stop PCE Server for Topology {}", topoKey.getValue());
154 closeListenerAndManager(topoKey);