import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
+import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup.PeerExporTuple;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
if (peerGroup != null) {
final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(routePeerId, attributes);
- for (final Map.Entry<PeerId, YangInstanceIdentifier> pid : peerGroup.getPeers()) {
+ for (final Map.Entry<PeerId, PeerExporTuple> pid : peerGroup.getPeers()) {
final PeerId destPeer = pid.getKey();
final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(destPeer);
if (filterRoutes(routePeerId, destPeer, peerPT, localTK, discPeers) && peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
if (destPeerSupAddPath) {
- update(destPeer, getAdjRibOutYII(ribSup, pid.getValue(), routeIdAddPath, localTK), effectiveAttributes, addPathValue,
+ update(destPeer, getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeIdAddPath, localTK), effectiveAttributes,
+ addPathValue,
ribSup, tx);
} else {
- update(destPeer, getAdjRibOutYII(ribSup, pid.getValue(), routeId, localTK), effectiveAttributes, value, ribSup, tx);
+ update(destPeer, getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeId, localTK), effectiveAttributes, value, ribSup, tx);
}
}
}
final ContainerNode effAttrib = peerGroup.effectiveAttributes(routePeerId, attributes);
peerGroup.getPeers().stream()
.filter(pid -> filterRoutes(routePeerId, pid.getKey(), peerPT, localTK, discPeers))
- .forEach(pid -> update(pid.getKey(), getAdjRibOutYII(ribSup, pid.getValue(), routeId, localTK), effAttrib, value, ribSup, tx));
+ .forEach(pid -> update(pid.getKey(), getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeId, localTK), effAttrib, value, ribSup, tx));
}
}
}
import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.ATTRS_EXTENSION_Q;
import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.SEGMENTS_NID;
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.UnsignedInteger;
-import java.util.AbstractMap;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mockito.Mock;
private static final NodeIdentifier ORIGIN_VALUE_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q, "value").intern());
private static final NodeIdentifier AS_PATH_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q, AsPath.QNAME.getLocalName()).intern());
private static final NodeIdentifier ATOMIC_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q, AtomicAggregate.QNAME.getLocalName()));
- private static final Function<YangInstanceIdentifier, Map.Entry<PeerId, YangInstanceIdentifier>> GENERATE_PEER_ID =
- input -> PEER_YII.equals(input) ? new AbstractMap.SimpleImmutableEntry<>(PEER_ID, input) : new AbstractMap.SimpleImmutableEntry<>(PEER_ID2, input);
private static final QName Q_NAME = BindingReflections.findQName(Ipv4Routes.class).intern();
private static final NodeIdentifier ROUTE_ATTRIBUTES_IDENTIFIER = new NodeIdentifier(QName.create(Q_NAME, Attributes.QNAME.getLocalName().intern()));
private static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, "prefix").intern();
private void mockExportGroup() {
Mockito.doReturn(this.attributes).when(this.peg).effectiveAttributes(Mockito.any(PeerId.class), Mockito.any(ContainerNode.class));
Mockito.doReturn(null).when(this.pegNot).effectiveAttributes(Mockito.any(PeerId.class), Mockito.any(ContainerNode.class));
- Collection<YangInstanceIdentifier> value = Arrays.asList(PEER_YII, PEER_YII2);
- final Collection<Map.Entry<PeerId, YangInstanceIdentifier>> peers = ImmutableList.copyOf(Collections2.transform(value, GENERATE_PEER_ID));
- final Collection<Map.Entry<PeerId, YangInstanceIdentifier>> peersEmpty = ImmutableList.copyOf(Collections2.transform(Collections.<YangInstanceIdentifier>emptyList(), GENERATE_PEER_ID));
- Mockito.doReturn(peers).when(this.peg).getPeers();
- Mockito.doReturn(peersEmpty).when(this.pegNot).getPeers();
+
+ Map<PeerId, PeerExportGroup.PeerExporTuple> peers = new HashMap<>();
+ Mockito.doReturn(ImmutableList.copyOf(peers.entrySet())).when(this.pegNot).getPeers();
+
+ peers.put(PEER_ID, new PeerExportGroup.PeerExporTuple(PEER_YII, PeerRole.Ibgp));
+ peers.put(PEER_ID2, new PeerExportGroup.PeerExporTuple(PEER_YII2, PeerRole.Ibgp));
+
+ Mockito.doReturn(ImmutableList.copyOf(peers.entrySet())).when(this.peg).getPeers();
}
private void mockExportPolicies() {
public void close() {
this.registerDataTreeChangeListener.close();
}
+
+ boolean isMpSupported() {
+ return this.mpSupport;
+ }
}
if (listener != null) {
listener.close();
this.adjRibOutListenerSet.remove(listener);
- createAdjRibOutListener(RouterIds.createPeerId(session.getBgpId()), key, true);
+ createAdjRibOutListener(RouterIds.createPeerId(session.getBgpId()), key, listener.isMpSupported());
} else {
LOG.info("Ignoring RouteRefresh message. Afi/Safi is not supported: {}, {}.", rrAfi, rrSafi);
}
//try to add a support for old-school BGP-4, if peer did not advertise IPv4-Unicast MP capability
private void addBgp4Support(final PeerId peerId, final boolean announceNone) {
final TablesKey key = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
- this.tables.add(key);
- if (!announceNone) {
+ if (this.tables.add(key) && !announceNone) {
createAdjRibOutListener(peerId, key, false);
}
}
*/
package org.opendaylight.protocol.bgp.rib.impl;
-import com.google.common.base.Function;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
+
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
-import java.util.AbstractMap;
-import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
+import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup.PeerExporTuple;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker {
private static final Logger LOG = LoggerFactory.getLogger(ExportPolicyPeerTrackerImpl.class);
- private static final Function<YangInstanceIdentifier, Entry<PeerId, YangInstanceIdentifier>> GENERATE_PEER_ID = new Function<YangInstanceIdentifier, Entry<PeerId, YangInstanceIdentifier>>() {
- @Override
- public Entry<PeerId, YangInstanceIdentifier> apply(final YangInstanceIdentifier input) {
- final PeerId peerId = IdentifierUtils.peerId((NodeIdentifierWithPredicates) input.getLastPathArgument());
- return new AbstractMap.SimpleImmutableEntry<>(peerId, input);
- }
- };
private static final QName SEND_RECEIVE = QName.create(SupportedTables.QNAME, "send-receive").intern();
private static final NodeIdentifier SEND_RECEIVE_NID = new NodeIdentifier(SEND_RECEIVE);
private final Map<YangInstanceIdentifier, PeerRole> peerRoles = new HashMap<>();
return Collections.emptyMap();
}
- // Index things nicely for easy access
- final Multimap<PeerRole, YangInstanceIdentifier> roleToIds = ArrayListMultimap.create(PeerRole.values().length, 2);
- final Map<PeerId, PeerRole> idToRole = new HashMap<>();
- for (final Entry<YangInstanceIdentifier, PeerRole> e : peerPathRoles.entrySet()) {
- roleToIds.put(e.getValue(), e.getKey());
- idToRole.put(IdentifierUtils.peerId((NodeIdentifierWithPredicates) e.getKey().getLastPathArgument()), e.getValue());
- }
-
- // Optimized immutable copy, reused for all PeerGroups
- final Map<PeerId, PeerRole> allPeerRoles = ImmutableMap.copyOf(idToRole);
-
- final Map<PeerRole, PeerExportGroup> ret = new EnumMap<>(PeerRole.class);
- for (final Entry<PeerRole, Collection<YangInstanceIdentifier>> e : roleToIds.asMap().entrySet()) {
- final AbstractExportPolicy policy = this.policyDatabase.exportPolicyForRole(e.getKey());
- final Collection<Entry<PeerId, YangInstanceIdentifier>> peers = ImmutableList.copyOf(Collections2.transform(e.getValue(), GENERATE_PEER_ID));
+ final Map<PeerId, PeerExporTuple> immutablePeers = ImmutableMap.copyOf(peerPathRoles.entrySet().stream()
+ .collect(toMap(peer -> IdentifierUtils.peerKeyToPeerId(peer.getKey()), peer -> new PeerExporTuple(peer.getKey(), peer.getValue()))));
- ret.put(e.getKey(), new PeerExportGroupImpl(peers, allPeerRoles, policy));
- }
+ final Map<PeerRole, PeerExportGroup> ret = peerPathRoles.values().stream().collect(Collectors.toSet()).stream().filter(role -> role != PeerRole.Internal)
+ .collect(toMap(identity(), role -> new PeerExportGroupImpl(immutablePeers, this.policyDatabase.exportPolicyForRole(role)),
+ (oldKey, newKey) -> oldKey, () -> new EnumMap<>(PeerRole.class)));
return ret;
}
for (final DataTreeCandidate tc : changes) {
final YangInstanceIdentifier rootPath = tc.getRootPath();
final DataTreeCandidateNode rootNode = tc.getRootNode();
- final NodeIdentifierWithPredicates peerKey = IdentifierUtils.peerKey(rootPath);
- final PeerId peerId = IdentifierUtils.peerId(peerKey);
+ final PeerId peerId = IdentifierUtils.peerKeyToPeerId(rootPath);
+
filterOutPeerRole(peerId, rootNode, rootPath);
filterOutChangesToSupportedTables(peerId, rootNode);
filterOutAnyChangeOutsideEffRibsIn(peerId, rootNode, ret, rootPath, tx);
LOG.debug("Data Changed for Peer role {} path {}, dataBefore {}, dataAfter {}", roleChange.getIdentifier(),
peerPath , roleChange.getDataBefore(), maybePeerRole);
final PeerRole role = PeerRoleUtil.roleForChange(maybePeerRole);
- SimpleRoutingPolicy srp = getSimpleRoutingPolicy(rootNode);
- if(PeerRole.Internal == role || SimpleRoutingPolicy.AnnounceNone == srp) {
+ final SimpleRoutingPolicy srp = getSimpleRoutingPolicy(rootNode);
+ if(SimpleRoutingPolicy.AnnounceNone == srp) {
return;
}
this.peerPolicyTracker.peerRoleChanged(peerPath, role);
import com.google.common.base.Preconditions;
import java.util.Collection;
import java.util.Map;
-import java.util.Map.Entry;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
final class PeerExportGroupImpl implements PeerExportGroup {
- private final Collection<Entry<PeerId, YangInstanceIdentifier>> peers;
- private final Map<PeerId, PeerRole> peerRoles;
+ private final Map<PeerId, PeerExporTuple> peers;
private final AbstractExportPolicy policy;
- PeerExportGroupImpl(final Collection<Entry<PeerId, YangInstanceIdentifier>> peers, final Map<PeerId, PeerRole> peerRoles, final AbstractExportPolicy policy) {
+ public PeerExportGroupImpl(final Map<PeerId, PeerExporTuple> peers, final AbstractExportPolicy policy) {
this.peers = Preconditions.checkNotNull(peers);
- this.peerRoles = Preconditions.checkNotNull(peerRoles);
this.policy = Preconditions.checkNotNull(policy);
}
@Override
public ContainerNode effectiveAttributes(final PeerId sourcePeerId, final ContainerNode attributes) {
- final PeerRole peerRole = peerRoles.get(sourcePeerId);
- return attributes == null || peerRole == null ? null : policy.effectiveAttributes(peerRole, attributes);
+ final PeerExporTuple peer = this.peers.get(sourcePeerId);
+ return attributes == null || peer == null ? null : policy.effectiveAttributes(peer.getRole(), attributes);
}
@Override
- public Collection<Entry<PeerId, YangInstanceIdentifier>> getPeers() {
- return peers;
+ public Collection<Map.Entry<PeerId, PeerExporTuple>> getPeers() {
+ return peers.entrySet();
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
public final class IdentifierUtils {
- private static final Predicate<PathArgument> IS_PEER = new Predicate<PathArgument>() {
- @Override
- public boolean apply(final PathArgument input) {
- return input instanceof NodeIdentifierWithPredicates && Peer.QNAME.equals(input.getNodeType());
- }
- };
- private static final Predicate<PathArgument> IS_TABLES = new Predicate<PathArgument>() {
- @Override
- public boolean apply(final PathArgument input) {
- return Tables.QNAME.equals(input.getNodeType());
- }
- };
+ private static final Predicate<PathArgument> IS_PEER = input -> input instanceof NodeIdentifierWithPredicates && Peer.QNAME.equals(input.getNodeType());
+ private static final Predicate<PathArgument> IS_TABLES = input -> Tables.QNAME.equals(input.getNodeType());
private static final QName PEER_ID = QName.create(Peer.QNAME, "peer-id").intern();
private IdentifierUtils() {
return new PeerId((String) peerKey.getKeyValues().get(PEER_ID));
}
+ public static PeerId peerKeyToPeerId(final YangInstanceIdentifier id) {
+ return peerId(peerKey(id));
+ }
+
+
static NodeIdentifierWithPredicates tableKey(final YangInstanceIdentifier id) {
return firstKeyOf(id, IS_TABLES);
}
import java.util.Collection;
import java.util.Map;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
* A collection of peers sharing the same export policy.
*/
public interface PeerExportGroup {
+ final class PeerExporTuple {
+ private final YangInstanceIdentifier yii;
+ private final PeerRole role;
+
+ public PeerExporTuple(final YangInstanceIdentifier yii, final PeerRole role) {
+ this.yii = yii;
+ this.role = role;
+ }
+
+ public YangInstanceIdentifier getYii() {
+ return yii;
+ }
+
+ public PeerRole getRole() {
+ return role;
+ }
+ }
+
/**
* Transform outgoing attributes according to policy per Peer
+ *
* @param sourcePeerId root Peer
* @param attributes attributes container
* @return return attributes container after apply policy
ContainerNode effectiveAttributes(PeerId sourcePeerId, ContainerNode attributes);
/**
- *
* @return map of peer
*/
- Collection<Map.Entry<PeerId, YangInstanceIdentifier>> getPeers();
+ Collection<Map.Entry<PeerId, PeerExporTuple>> getPeers();
}