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;
11 import static org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderUtil.filterPcepTopologies;
12 import static org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.concurrent.TimeUnit;
19 import java.util.stream.Collectors;
20 import org.checkerframework.checker.lock.qual.GuardedBy;
21 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
22 import org.opendaylight.bgpcep.programming.spi.InstructionSchedulerFactory;
23 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
24 import org.opendaylight.mdsal.binding.api.DataBroker;
25 import org.opendaylight.mdsal.binding.api.DataObjectModification;
26 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
27 import org.opendaylight.mdsal.binding.api.DataTreeModification;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev171025.pcep.config.SessionConfig;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.config.rev181109.PcepTopologyTypeConfig;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
33 import org.opendaylight.yangtools.concepts.ListenerRegistration;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.osgi.service.blueprint.container.BlueprintContainer;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public class PCEPTopologyDeployerImpl implements ClusteredDataTreeChangeListener<Topology>, AutoCloseable {
41 private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyDeployerImpl.class);
43 private static final long TIMEOUT_NS = TimeUnit.SECONDS.toNanos(5);
44 private final BlueprintContainer container;
45 private final InstanceIdentifier<NetworkTopology> networTopology;
46 private final DataBroker dataBroker;
47 private final InstructionSchedulerFactory instructionSchedulerFactory;
49 private final Map<TopologyId, PCEPTopologyProviderBean> pcepTopologyServices = new HashMap<>();
50 private ListenerRegistration<PCEPTopologyDeployerImpl> listenerRegistration;
52 public PCEPTopologyDeployerImpl(final BlueprintContainer container,
53 final DataBroker dataBroker, final InstructionSchedulerFactory instructionSchedulerFactory) {
54 this.container = requireNonNull(container);
55 this.dataBroker = requireNonNull(dataBroker);
56 this.instructionSchedulerFactory = requireNonNull(instructionSchedulerFactory);
57 this.networTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
60 public synchronized void init() {
61 LOG.info("PCEP Topology Deployer initialized");
62 this.listenerRegistration = this.dataBroker.registerDataTreeChangeListener(
63 DataTreeIdentifier.create(CONFIGURATION, this.networTopology.child(Topology.class)), this);
67 public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Topology>> changes) {
68 final List<DataObjectModification<Topology>> topoChanges = changes.stream()
69 .map(DataTreeModification::getRootNode)
70 .collect(Collectors.toList());
71 topoChanges.stream().iterator().forEachRemaining(topo -> {
72 switch (topo.getModificationType()) {
73 case SUBTREE_MODIFIED:
75 updateTopologyProvider(topo.getDataAfter());
78 removeTopologyProvider(topo.getDataBefore());
85 private synchronized void updateTopologyProvider(final Topology topology) {
86 if (!filterPcepTopologies(topology.getTopologyTypes())) {
89 final TopologyId topologyId = topology.getTopologyId();
90 LOG.info("Updating Topology {}", topologyId);
91 final PCEPTopologyProviderBean previous = this.pcepTopologyServices.remove(topology.getTopologyId());
92 closeTopology(previous, topologyId);
93 createTopologyProvider(topology);
96 private synchronized void createTopologyProvider(final Topology topology) {
97 if (!filterPcepTopologies(topology.getTopologyTypes())) {
100 final TopologyId topologyId = topology.getTopologyId();
101 if (this.pcepTopologyServices.containsKey(topology.getTopologyId())) {
102 LOG.warn("Topology Provider {} already exist. New instance won't be created", topologyId);
105 LOG.info("Creating Topology {}", topologyId);
106 LOG.trace("Topology {}.", topology);
108 final SessionConfig config = topology.augmentation(PcepTopologyTypeConfig.class).getSessionConfig();
109 final InstructionScheduler instructionScheduler = this.instructionSchedulerFactory
110 .createInstructionScheduler(topologyId.getValue());
112 final PCEPTopologyConfiguration dependencies = new PCEPTopologyConfiguration(config, topology);
114 final PCEPTopologyProviderBean pcepTopologyProviderBean = (PCEPTopologyProviderBean) this.container
115 .getComponentInstance(PCEPTopologyProviderBean.class.getSimpleName());
116 this.pcepTopologyServices.put(topologyId, pcepTopologyProviderBean);
117 pcepTopologyProviderBean.start(dependencies, instructionScheduler);
120 private synchronized void removeTopologyProvider(final Topology topology) {
121 if (!filterPcepTopologies(topology.getTopologyTypes())) {
124 final TopologyId topologyId = topology.getTopologyId();
125 closeTopology(this.pcepTopologyServices.remove(topologyId), topologyId);
129 public synchronized void close() {
130 LOG.info("PCEP Topology Deployer closing");
131 if (this.listenerRegistration != null) {
132 this.listenerRegistration.close();
133 this.listenerRegistration = null;
135 for (Map.Entry<TopologyId, PCEPTopologyProviderBean> entry:this.pcepTopologyServices.entrySet()) {
136 closeTopology(entry.getValue(), entry.getKey());
138 this.pcepTopologyServices.clear();
139 LOG.info("PCEP Topology Deployer closed");
143 @SuppressWarnings("checkstyle:IllegalCatch")
144 private synchronized void closeTopology(final PCEPTopologyProviderBean topology, final TopologyId topologyId) {
145 if (topology == null) {
148 LOG.info("Removing Topology {}", topologyId);
150 topology.closeServiceInstance().get(TIMEOUT_NS, TimeUnit.NANOSECONDS);
152 } catch (final Exception e) {
153 LOG.error("Topology {} instance failed to close service instance", topologyId, e);