2 * Copyright (c) 2016 Cisco Systems, Inc. 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.bgp.topology.provider.config;
10 import static java.util.Objects.requireNonNull;
12 import java.util.Collection;
13 import java.util.HashSet;
15 import java.util.stream.Collectors;
16 import javax.annotation.PreDestroy;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.checkerframework.checker.lock.qual.GuardedBy;
20 import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
21 import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyProvider;
22 import org.opendaylight.bgpcep.bgp.topology.provider.spi.TopologyReferenceSingletonService;
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.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
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.network.topology.Topology;
32 import org.opendaylight.yangtools.concepts.AbstractRegistration;
33 import org.opendaylight.yangtools.concepts.ListenerRegistration;
34 import org.opendaylight.yangtools.concepts.Registration;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.osgi.service.component.annotations.Activate;
37 import org.osgi.service.component.annotations.Component;
38 import org.osgi.service.component.annotations.Deactivate;
39 import org.osgi.service.component.annotations.Reference;
40 import org.osgi.service.component.annotations.RequireServiceComponentRuntime;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 @Component(service = BgpTopologyDeployer.class, immediate = true)
46 @RequireServiceComponentRuntime
47 public final class BgpTopologyDeployerImpl implements BgpTopologyDeployer, AutoCloseable,
48 ClusteredDataTreeChangeListener<Topology> {
50 private static final Logger LOG = LoggerFactory.getLogger(BgpTopologyDeployerImpl.class);
51 private static final InstanceIdentifier<Topology> TOPOLOGY_IID =
52 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class);
55 private final Set<BgpTopologyProvider> topologyProviders = new HashSet<>();
57 private final Set<Topology> topologies = new HashSet<>();
58 private final DataBroker dataBroker;
59 private final ClusterSingletonServiceProvider singletonProvider;
60 private ListenerRegistration<BgpTopologyDeployerImpl> registration;
62 private boolean closed;
66 public BgpTopologyDeployerImpl(@Reference final DataBroker dataBroker,
67 @Reference final ClusterSingletonServiceProvider singletonProvider) {
68 this.dataBroker = requireNonNull(dataBroker);
69 this.singletonProvider = requireNonNull(singletonProvider);
70 registration = dataBroker.registerDataTreeChangeListener(
71 DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_IID), this);
72 LOG.info("BGP topology deployer started.");
76 public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Topology>> changes) {
78 LOG.trace("BGP Topology Provider Deployer was already closed, skipping changes.");
81 for (final DataTreeModification<Topology> change : changes) {
82 final DataObjectModification<Topology> rootNode = change.getRootNode();
83 final Topology dataBefore = rootNode.getDataBefore();
84 final Topology dataAfter = rootNode.getDataAfter();
85 LOG.trace("BGP topology deployer configuration changed: modification type: [{}],"
86 + " data before:[{}], data after: [{}]", rootNode.getModificationType(), dataBefore, dataAfter);
87 switch (rootNode.getModificationType()) {
89 filterTopologyBuilders(dataBefore)
90 .forEach(provider -> provider.onTopologyBuilderRemoved(dataBefore));
91 topologies.remove(dataBefore);
93 case SUBTREE_MODIFIED:
94 filterTopologyBuilders(dataBefore).forEach(provider
95 -> provider.onTopologyBuilderRemoved(dataBefore));
96 topologies.remove(dataBefore);
97 filterTopologyBuilders(dataAfter).forEach(provider
98 -> provider.onTopologyBuilderCreated(dataAfter));
99 topologies.add(dataAfter);
102 filterTopologyBuilders(dataAfter).forEach(provider
103 -> provider.onTopologyBuilderCreated(dataAfter));
104 topologies.add(dataAfter);
113 public synchronized AbstractRegistration registerTopologyProvider(final BgpTopologyProvider topologyBuilder) {
114 filterTopologies(topologyBuilder).forEach(topology -> topologyBuilder.onTopologyBuilderCreated(topology));
115 topologyProviders.add(topologyBuilder);
116 return new AbstractRegistration() {
118 protected void removeRegistration() {
119 synchronized (BgpTopologyDeployerImpl.this) {
120 filterTopologies(topologyBuilder)
121 .forEach(topology -> topologyBuilder.onTopologyBuilderRemoved(topology));
122 topologyProviders.remove(topologyBuilder);
129 public DataBroker getDataBroker() {
134 public Registration registerService(final TopologyReferenceSingletonService topologyProviderService) {
135 return singletonProvider.registerClusterSingletonService(topologyProviderService);
141 public synchronized void close() {
142 if (registration != null) {
143 registration.close();
147 LOG.info("BGP topology deployer stopped.");
151 private Iterable<BgpTopologyProvider> filterTopologyBuilders(final Topology topology) {
152 return topologyProviders.stream().filter(input -> input.topologyTypeFilter(topology))
153 .collect(Collectors.toList());
156 private Iterable<Topology> filterTopologies(final BgpTopologyProvider topologyBuilder) {
157 return topologies.stream().filter(topology -> topologyBuilder.topologyTypeFilter(topology))
158 .collect(Collectors.toList());