2 * Copyright (c) 2015 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.protocol.bgp.rib.impl;
10 import static java.util.Objects.requireNonNull;
12 import java.util.EnumMap;
13 import java.util.HashMap;
15 import java.util.Optional;
16 import javax.annotation.concurrent.GuardedBy;
17 import javax.annotation.concurrent.ThreadSafe;
18 import org.opendaylight.protocol.bgp.rib.impl.spi.PeerExportGroupRegistry;
19 import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
20 import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
21 import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup.PeerExporTuple;
22 import org.opendaylight.protocol.concepts.AbstractRegistration;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * There is one ExportPolicyPeerTracker per table
34 * - peerTables: keep track of registered peers, the ones which support this table.
35 * - peerTables: flag indicates whether the structure of the peer has been created, and therefore it can start
37 * - peerAddPathTables: keeps track of peer which supports Additional Path for this table and which Add Path
38 * configuration they are using.
39 * - groups: Contains peers grouped by peerRole and therefore sharing the same export policy.
42 final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker {
43 private static final Logger LOG = LoggerFactory.getLogger(ExportPolicyPeerTrackerImpl.class);
45 private final Map<YangInstanceIdentifier, PeerRole> peerRoles = new HashMap<>();
47 private final Map<PeerId, SendReceive> peerAddPathTables = new HashMap<>();
49 private final Map<PeerId, Boolean> peerTables = new HashMap<>();
50 private final PolicyDatabase policyDatabase;
51 private final TablesKey localTableKey;
53 private final Map<PeerRole, PeerExportGroupRegistry> groups = new EnumMap<>(PeerRole.class);
55 ExportPolicyPeerTrackerImpl(final PolicyDatabase policyDatabase, final TablesKey localTablesKey) {
56 this.policyDatabase = requireNonNull(policyDatabase);
57 this.localTableKey = localTablesKey;
60 private synchronized AbstractRegistration addToExportGroups(final PeerId peerId,
61 final YangInstanceIdentifier peerPath, final PeerRole peerRole) {
62 final PeerExportGroupRegistry peerExp = this.groups.computeIfAbsent(peerRole,
63 k -> new PeerExportGroupImpl(this.policyDatabase.exportPolicyForRole(peerRole)));
65 final AbstractRegistration registration = peerExp.registerPeer(peerId, new PeerExporTuple(peerPath, peerRole));
67 return new AbstractRegistration() {
69 protected void removeRegistration() {
71 if (ExportPolicyPeerTrackerImpl.this.groups.get(peerRole).isEmpty()) {
72 ExportPolicyPeerTrackerImpl.this.groups.remove(peerRole);
79 public synchronized AbstractRegistration registerPeer(final PeerId peerId, final SendReceive sendReceive,
80 final YangInstanceIdentifier peerPath, final PeerRole peerRole,
81 final Optional<SimpleRoutingPolicy> optSimpleRoutingPolicy) {
82 if (sendReceive != null) {
83 this.peerAddPathTables.put(peerId, sendReceive);
84 LOG.debug("Supported Add BestPath table {} added to peer {}", sendReceive, peerId);
86 final SimpleRoutingPolicy simpleRoutingPolicy = optSimpleRoutingPolicy.orElse(null);
87 if (SimpleRoutingPolicy.AnnounceNone != simpleRoutingPolicy) {
88 this.peerTables.put(peerId, false);
90 this.peerRoles.put(peerPath, peerRole);
91 LOG.debug("Supported table {} added to peer {} role {}", this.localTableKey, peerId, peerRole);
92 final AbstractRegistration registration = addToExportGroups(peerId, peerPath, peerRole);
94 final Object lock = this;
95 return new AbstractRegistration() {
97 protected void removeRegistration() {
99 final SendReceive sendReceiveValue = ExportPolicyPeerTrackerImpl.this.peerAddPathTables.remove(peerId);
100 if (sendReceiveValue != null) {
101 LOG.debug("Supported Add BestPath table {} removed to peer {}", sendReceiveValue, peerId);
103 ExportPolicyPeerTrackerImpl.this.peerTables.remove(peerId);
104 LOG.debug("Removed peer {} from supported table {}", peerId, ExportPolicyPeerTrackerImpl.this.localTableKey);
105 ExportPolicyPeerTrackerImpl.this.peerRoles.remove(peerPath);
106 registration.close();
113 public synchronized PeerExportGroup getPeerGroup(final PeerRole role) {
114 return this.groups.get(requireNonNull(role));
118 public synchronized boolean isTableSupported(final PeerId peerId) {
119 return this.peerTables.containsKey(peerId);
123 public synchronized PeerRole getRole(final YangInstanceIdentifier peerId) {
124 return this.peerRoles.get(peerId);
128 public synchronized boolean isAddPathSupportedByPeer(final PeerId peerId) {
129 final SendReceive sendReceive = this.peerAddPathTables.get(peerId);
130 return sendReceive != null && (sendReceive.equals(SendReceive.Both) || sendReceive.equals(SendReceive.Receive));
134 public synchronized void registerPeerAsInitialized(final PeerId peerId) {
135 this.peerTables.computeIfPresent(peerId, (k, v) -> true);
139 public synchronized boolean isTableStructureInitialized(final PeerId peerId) {
140 return this.peerTables.get(peerId);