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.closeTopology;
12 import static org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyProviderUtil.filterPcepTopologies;
13 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
15 import java.net.InetSocketAddress;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.stream.Collectors;
21 import javax.annotation.concurrent.GuardedBy;
22 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
23 import org.opendaylight.bgpcep.programming.spi.InstructionSchedulerFactory;
24 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
27 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
28 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
29 import org.opendaylight.protocol.concepts.KeyMapping;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev171025.pcep.config.SessionConfig;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pce.config.rev171025.PcepTopologyTypeConfig;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
35 import org.opendaylight.yangtools.concepts.ListenerRegistration;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.osgi.service.blueprint.container.BlueprintContainer;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class PCEPTopologyDeployerImpl implements ClusteredDataTreeChangeListener<Topology>, AutoCloseable {
43 private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyDeployerImpl.class);
45 private final BlueprintContainer container;
46 private final InstanceIdentifier<NetworkTopology> networTopology;
47 private final DataBroker dataBroker;
48 private final InstructionSchedulerFactory instructionSchedulerFactory;
50 private final Map<TopologyId, PCEPTopologyProviderBean> pcepTopologyServices = new HashMap<>();
51 private ListenerRegistration<PCEPTopologyDeployerImpl> listenerRegistration;
53 public PCEPTopologyDeployerImpl(final BlueprintContainer container,
54 final DataBroker dataBroker, final InstructionSchedulerFactory instructionSchedulerFactory) {
55 this.container = requireNonNull(container);
56 this.dataBroker = requireNonNull(dataBroker);
57 this.instructionSchedulerFactory = requireNonNull(instructionSchedulerFactory);
58 this.networTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
61 public synchronized void init() {
62 this.listenerRegistration = this.dataBroker.registerDataTreeChangeListener(
63 new DataTreeIdentifier<>(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());
72 .iterator().forEachRemaining(topo -> {
73 switch (topo.getModificationType()) {
74 case SUBTREE_MODIFIED:
75 updateTopologyProvider(topo.getDataAfter());
78 createTopologyProvider(topo.getDataAfter());
81 removeTopologyProvider(topo.getDataBefore());
87 private synchronized void updateTopologyProvider(final Topology topology) {
88 if (!filterPcepTopologies(topology.getTopologyTypes())) {
91 final TopologyId topologyId = topology.getTopologyId();
92 final PCEPTopologyProviderBean previous = this.pcepTopologyServices.remove(topology.getTopologyId());
93 closeTopology(previous, topologyId);
94 createTopologyProvider(topology);
97 private synchronized void createTopologyProvider(final Topology topology) {
98 if (!filterPcepTopologies(topology.getTopologyTypes())) {
101 final TopologyId topologyId = topology.getTopologyId();
102 if (this.pcepTopologyServices.containsKey(topology.getTopologyId())) {
103 LOG.warn("Topology Provider {} already exist. New instance won't be created", topologyId);
107 final PcepTopologyTypeConfig pcepTopo = topology.getAugmentation(PcepTopologyTypeConfig.class);
109 final SessionConfig config = pcepTopo.getSessionConfig();
111 final InstructionScheduler instructionScheduler = this.instructionSchedulerFactory
112 .createInstructionScheduler(topologyId.getValue());
114 final InetSocketAddress inetAddress = PCEPTopologyProviderUtil
115 .getInetSocketAddress(config.getListenAddress(), config.getListenPort());
117 final KeyMapping keys = PCEPTopologyProviderUtil.contructKeys(topology);
118 final PCEPTopologyConfigDependencies dependencies = new PCEPTopologyConfigDependencies(
119 inetAddress, keys, instructionScheduler, topology.getTopologyId(),
120 config.getRpcTimeout());
122 final PCEPTopologyProviderBean pcepTopologyProviderBean = (PCEPTopologyProviderBean) this.container
123 .getComponentInstance(PCEPTopologyProviderBean.class.getSimpleName());
124 this.pcepTopologyServices.put(topologyId, pcepTopologyProviderBean);
125 pcepTopologyProviderBean.start(dependencies);
128 private synchronized void removeTopologyProvider(final Topology topo) {
129 if (!filterPcepTopologies(topo.getTopologyTypes())) {
132 final TopologyId topologyId = topo.getTopologyId();
133 final PCEPTopologyProviderBean topology = this.pcepTopologyServices.remove(topologyId);
134 closeTopology(topology, topologyId);
138 public synchronized void close() {
139 if (this.listenerRegistration != null) {
140 this.listenerRegistration.close();
141 this.listenerRegistration = null;
143 this.pcepTopologyServices.entrySet().iterator()
144 .forEachRemaining(entry -> closeTopology(entry.getValue(), entry.getKey()));
145 this.pcepTopologyServices.clear();