--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.rib.impl;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.util.Arrays;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+import org.opendaylight.protocol.bgp.rib.impl.state.BGPPeerStateImpl;
+import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
+import org.opendaylight.protocol.bgp.rib.spi.Peer;
+import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
+import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
+import org.opendaylight.protocol.bgp.rib.spi.state.BGPErrorHandlingState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AbstractPeer extends BGPPeerStateImpl implements BGPRouteEntryImportParameters, TransactionChainListener,
+ Peer {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractPeer.class);
+ protected final RIB rib;
+ final String name;
+ final PeerRole peerRole;
+ private final ClusterIdentifier clusterId;
+ private final AsNumber localAs;
+ byte[] rawIdentifier;
+ @GuardedBy("this")
+ PeerId peerId;
+
+ AbstractPeer(
+ final RIB rib,
+ final String peerName,
+ final String groupId,
+ final PeerRole role,
+ @Nullable final ClusterIdentifier clusterId,
+ @Nullable final AsNumber localAs,
+ final IpAddress neighborAddress,
+ final Set<TablesKey> afiSafisAdvertized,
+ final Set<TablesKey> afiSafisGracefulAdvertized) {
+ super(rib.getInstanceIdentifier(), groupId, neighborAddress, afiSafisAdvertized, afiSafisGracefulAdvertized);
+ this.name = peerName;
+ this.peerRole = role;
+ this.clusterId = clusterId;
+ this.localAs = localAs;
+ this.rib = rib;
+ }
+
+ AbstractPeer(
+ final RIB rib,
+ final String peerName,
+ final String groupId,
+ final PeerRole role,
+ final IpAddress neighborAddress,
+ final Set<TablesKey> afiSafisGracefulAdvertized) {
+ this(rib, peerName, groupId, role, null, null, neighborAddress,
+ rib.getLocalTablesKeys(), afiSafisGracefulAdvertized);
+ }
+
+ @SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "Unrecognised NullableDecl")
+ final synchronized ListenableFuture<Void> removePeer(
+ @Nonnull final DOMTransactionChain chain,
+ @Nullable final YangInstanceIdentifier peerPath) {
+ if (peerPath != null) {
+ LOG.info("AdjRibInWriter closed per Peer {} removed", peerPath);
+ final DOMDataWriteTransaction tx = chain.newWriteOnlyTransaction();
+ tx.delete(LogicalDatastoreType.OPERATIONAL, peerPath);
+ final ListenableFuture<Void> future = tx.submit();
+ Futures.addCallback(future, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(final Void result) {
+ LOG.debug("Peer {} removed", peerPath);
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ LOG.error("Failed to remove Peer {}", peerPath, t);
+ }
+ }, MoreExecutors.directExecutor());
+ return future;
+ }
+ return Futures.immediateFuture(null);
+ }
+
+ synchronized YangInstanceIdentifier createPeerPath() {
+ return this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib
+ .rev180329.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(this.peerId));
+ }
+
+ @Override
+ public synchronized final PeerId getPeerId() {
+ return this.peerId;
+ }
+
+ @Override
+ public final PeerRole getRole() {
+ return this.peerRole;
+ }
+
+ @Override
+ public final synchronized byte[] getRawIdentifier() {
+ return Arrays.copyOf(this.rawIdentifier, this.rawIdentifier.length);
+ }
+
+ @Override
+ public final PeerRole getFromPeerRole() {
+ return getRole();
+ }
+
+ @Override
+ public final PeerId getFromPeerId() {
+ return getPeerId();
+ }
+
+ @Override
+ public final ClusterIdentifier getFromClusterId() {
+ return getClusterId();
+ }
+
+ @Override
+ public final void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+ LOG.debug("Transaction chain {} successful.", chain);
+ }
+
+ @Override
+ public final BGPErrorHandlingState getBGPErrorHandlingState() {
+ return this;
+ }
+
+ @Override
+ public final BGPAfiSafiState getBGPAfiSafiState() {
+ return this;
+ }
+
+ @Override
+ public final AsNumber getFromPeerLocalAs() {
+ return getLocalAs();
+ }
+
+ @Override
+ public final String getName() {
+ return this.name;
+ }
+
+ @Override
+ public final ClusterIdentifier getClusterId() {
+ return this.clusterId;
+ }
+
+ @Override
+ public final AsNumber getLocalAs() {
+ return this.localAs;
+ }
+}
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
.withNodeIdentifier(ADJRIBOUT).addChild(ImmutableNodes.mapNodeBuilder(Tables.QNAME).build()).build();
private final Map<TablesKey, TableContext> tables;
- private final YangInstanceIdentifier peerPath;
private final YangInstanceIdentifier ribPath;
private final DOMTransactionChain chain;
private final PeerRole role;
private AdjRibInWriter(final YangInstanceIdentifier ribPath, final DOMTransactionChain chain, final PeerRole role,
- final YangInstanceIdentifier peerPath, final Map<TablesKey, TableContext> tables) {
+ final Map<TablesKey, TableContext> tables) {
this.ribPath = requireNonNull(ribPath);
this.chain = requireNonNull(chain);
this.tables = requireNonNull(tables);
this.role = requireNonNull(role);
- this.peerPath = peerPath;
}
/**
*/
static AdjRibInWriter create(@Nonnull final YangInstanceIdentifier ribId, @Nonnull final PeerRole role,
@Nonnull final DOMTransactionChain chain) {
- return new AdjRibInWriter(ribId, chain, role, null, Collections.emptyMap());
+ return new AdjRibInWriter(ribId, chain, role, Collections.emptyMap());
}
/**
* method returns, the old instance must not be reasonably used.
*
* @param newPeerId new peer BGP identifier
+ * @param peerPath
* @param registry RIB extension registry
* @param tableTypes New tables, must not be null
* @param addPathTablesType
* @return New writer
*/
- AdjRibInWriter transform(final PeerId newPeerId, final RIBSupportContextRegistry registry,
+ AdjRibInWriter transform(final PeerId newPeerId, final YangInstanceIdentifier peerPath,
+ final RIBSupportContextRegistry registry,
final Set<TablesKey> tableTypes, final Map<TablesKey, SendReceive> addPathTablesType) {
- return transform(newPeerId, registry, tableTypes, addPathTablesType, null);
+ return transform(newPeerId, peerPath, registry, tableTypes, addPathTablesType, null);
}
- AdjRibInWriter transform(final PeerId newPeerId, final RIBSupportContextRegistry registry,
- final Set<TablesKey> tableTypes, final Map<TablesKey, SendReceive> addPathTablesType,
+ AdjRibInWriter transform(final PeerId newPeerId, final YangInstanceIdentifier peerPath,
+ final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes,
+ final Map<TablesKey, SendReceive> addPathTablesType,
@Nullable final RegisterAppPeerListener registerAppPeerListener) {
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
- final YangInstanceIdentifier newPeerPath;
- newPeerPath = createEmptyPeerStructure(newPeerId, tx);
- final ImmutableMap<TablesKey, TableContext> tb = createNewTableInstances(newPeerPath, registry, tableTypes,
+ createEmptyPeerStructure(newPeerId, peerPath, tx);
+ final ImmutableMap<TablesKey, TableContext> tb = createNewTableInstances(peerPath, registry, tableTypes,
addPathTablesType, tx);
Futures.addCallback(tx.submit(), new FutureCallback<Void>() {
}
}
}, MoreExecutors.directExecutor());
- return new AdjRibInWriter(this.ribPath, this.chain, this.role, newPeerPath, tb);
+ return new AdjRibInWriter(this.ribPath, this.chain, this.role, tb);
}
/**
.node(TABLES).node(instanceIdentifierKey));
}
- private YangInstanceIdentifier createEmptyPeerStructure(final PeerId newPeerId, final DOMDataWriteTransaction tx) {
+ private void createEmptyPeerStructure(final PeerId newPeerId,
+ final YangInstanceIdentifier peerPath, final DOMDataWriteTransaction tx) {
final NodeIdentifierWithPredicates peerKey = IdentifierUtils.domPeerId(newPeerId);
- final YangInstanceIdentifier newPeerPath = this.ribPath.node(Peer.QNAME).node(peerKey);
- tx.put(LogicalDatastoreType.OPERATIONAL, newPeerPath, peerSkeleton(peerKey, newPeerId.getValue()));
- LOG.debug("New peer {} structure installed.", newPeerPath);
- return newPeerPath;
+ tx.put(LogicalDatastoreType.OPERATIONAL, peerPath, peerSkeleton(peerKey, newPeerId.getValue()));
+ LOG.debug("New peer {} structure installed.", peerPath);
}
@VisibleForTesting
return pb.build();
}
- @SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "Unrecognised NullableDecl")
- synchronized ListenableFuture<Void> removePeer() {
- if (this.peerPath != null) {
-
- LOG.info("AdjRibInWriter closed per Peer {} removed", AdjRibInWriter.this.peerPath);
- final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
- tx.delete(LogicalDatastoreType.OPERATIONAL, this.peerPath);
- final ListenableFuture<Void> future = tx.submit();
- Futures.addCallback(future, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- LOG.debug("Peer {} removed", AdjRibInWriter.this.peerPath);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.warn("Failed to remove Peer {}", AdjRibInWriter.this.peerPath, t);
- }
- }, MoreExecutors.directExecutor());
- return future;
- }
- return Futures.immediateFuture(null);
- }
-
void markTableUptodate(final TablesKey tableTypes) {
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
final TableContext ctx = this.tables.get(tableTypes);
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeListener;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
-import org.opendaylight.protocol.bgp.rib.impl.state.BGPPeerStateImpl;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPSessionStateImpl;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
-import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
-import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
-import org.opendaylight.protocol.bgp.rib.spi.state.BGPErrorHandlingState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPSessionState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPTimersState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPTransportState;
import org.opendaylight.protocol.concepts.AbstractRegistration;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.ApplicationRibId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.PeerKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.peer.AdjRibOut;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
* For purposed of import policies such as Best Path Selection, application
* peer needs to have a BGP-ID that is configurable.
*/
-public class ApplicationPeer extends BGPPeerStateImpl implements org.opendaylight.protocol.bgp.rib.spi.Peer,
- BGPRouteEntryImportParameters, ClusteredDOMDataTreeChangeListener, TransactionChainListener {
+public class ApplicationPeer extends AbstractPeer implements ClusteredDOMDataTreeChangeListener {
private static final Logger LOG = LoggerFactory.getLogger(ApplicationPeer.class);
- private final byte[] rawIdentifier;
- private final String name;
+ private static final String APP_PEER_GROUP = "application-peers";
private final YangInstanceIdentifier adjRibsInId;
- private final RIB rib;
private final InstanceIdentifier<AdjRibOut> peerRibOutIId;
private final KeyedInstanceIdentifier<Peer, PeerKey> peerIId;
private DOMTransactionChain chain;
return ApplicationPeer.this.peerRibOutIId.child(Tables.class, tablesKey);
}
});
- private final PeerId peerId;
private AbstractRegistration trackerRegistration;
+ private YangInstanceIdentifier peerPath;
@FunctionalInterface
interface RegisterAppPeerListener {
}
public ApplicationPeer(final ApplicationRibId applicationRibId, final Ipv4Address ipAddress, final RIB rib) {
- super(rib.getInstanceIdentifier(), "application-peers", new IpAddress(ipAddress),
- rib.getLocalTablesKeys(), Collections.emptySet());
- this.name = applicationRibId.getValue();
+ super(rib, applicationRibId.getValue(), APP_PEER_GROUP, PeerRole.Internal,
+ new IpAddress(ipAddress), Collections.emptySet());
final RIB targetRib = requireNonNull(rib);
this.rawIdentifier = InetAddresses.forString(ipAddress.getValue()).getAddress();
- final NodeIdentifierWithPredicates peerIId = IdentifierUtils.domPeerId(RouterIds.createPeerId(ipAddress));
- this.adjRibsInId = targetRib.getYangRibId().node(Peer.QNAME).node(peerIId)
+ this.adjRibsInId = targetRib.getYangRibId().node(Peer.QNAME)
+ .node(IdentifierUtils.domPeerId(RouterIds.createPeerId(ipAddress)))
.node(AdjRibIn.QNAME).node(Tables.QNAME);
- this.rib = targetRib;
this.peerId = RouterIds.createPeerId(ipAddress);
this.peerIId = getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
.yang.bgp.rib.rev180329.bgp.rib.rib.Peer.class, new PeerKey(this.peerId));
}
}
};
- this.adjRibInWriter = this.adjRibInWriter.transform(this.peerId, context, localTables, Collections.emptyMap(),
- registerAppPeerListener);
+ this.peerPath = createPeerPath();
+ this.adjRibInWriter = this.adjRibInWriter.transform(this.peerId, this.peerPath, context, localTables,
+ Collections.emptyMap(), registerAppPeerListener);
this.effectiveRibInWriter = new EffectiveRibInWriter(this, this.rib,
this.rib.createPeerChain(this), this.peerIId, localTables);
this.effectiveRibInWriter.init();
}
}
- @Override
- public String getName() {
- return this.name;
- }
-
// FIXME ListenableFuture<?> should be used once closeServiceInstance uses wildcard too
@Override
@SuppressFBWarnings(value = "NP_NONNULL_PARAM_VIOLATION", justification = "Unrecognised NullableDecl")
this.effectiveRibInWriter.close();
}
final ListenableFuture<Void> future;
- if (this.adjRibInWriter != null) {
- future = this.adjRibInWriter.removePeer();
- } else {
- future = Futures.immediateFuture(null);
- }
if (this.chain != null) {
+ future = removePeer(this.chain, this.peerPath);
this.chain.close();
this.chain = null;
+ } else {
+ future = Futures.immediateFuture(null);
}
if (this.writerChain != null) {
this.writerChain.close();
return future;
}
- @Override
- public byte[] getRawIdentifier() {
- return Arrays.copyOf(this.rawIdentifier, this.rawIdentifier.length);
- }
-
- @Override
- public PeerId getPeerId() {
- return this.peerId;
- }
-
@Override
public boolean supportsAddPathSupported(final TablesKey tableKey) {
return false;
return this.rib.supportsTable(tableKey);
}
- @Override
- public PeerRole getRole() {
- return PeerRole.Internal;
- }
-
- @Override
- public ClusterIdentifier getClusterId() {
- return null;
- }
-
- @Override
- public AsNumber getLocalAs() {
- return null;
- }
-
@Override
public KeyedInstanceIdentifier<Tables, TablesKey> getRibOutIId(final TablesKey tablesKey) {
return this.tablesIId.getUnchecked(tablesKey);
LOG.error("Transaction chain {} failed.", transaction != null ? transaction.getIdentifier() : null, cause);
}
- @Override
- public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
- LOG.debug("Transaction chain {} successful.", chain);
- }
-
- @Override
- public BGPErrorHandlingState getBGPErrorHandlingState() {
- return this;
- }
-
- @Override
- public BGPAfiSafiState getBGPAfiSafiState() {
- return this;
- }
-
@Override
public BGPSessionState getBGPSessionState() {
return this.bgpSessionState;
public BGPTransportState getBGPTransportState() {
return this.bgpSessionState;
}
-
-
- @Override
- public PeerRole getFromPeerRole() {
- return getRole();
- }
-
- @Override
- public PeerId getFromPeerId() {
- return getPeerId();
- }
-
- @Override
- public ClusterIdentifier getFromClusterId() {
- return getClusterId();
- }
-
- @Override
- public AsNumber getFromPeerLocalAs() {
- return null;
- }
}
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.protocol.bgp.parser.impl.message.update.LocalPreferenceAttributeParser;
import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
-import org.opendaylight.protocol.bgp.rib.impl.state.BGPPeerStateImpl;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPSessionStateProvider;
import org.opendaylight.protocol.bgp.rib.spi.BGPSession;
import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
import org.opendaylight.protocol.bgp.rib.spi.BGPTerminationReason;
-import org.opendaylight.protocol.bgp.rib.spi.Peer;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
-import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
-import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
-import org.opendaylight.protocol.bgp.rib.spi.state.BGPErrorHandlingState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPSessionState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPTimersState;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPTransportState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev180329.BgpPeerRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev180329.PeerContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.PeerKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.peer.AdjRibOut;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* Class representing a peer. We have a single instance for each peer, which provides translation from BGP events into
* RIB actions.
*/
-public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportParameters,
- BGPSessionListener, Peer, TransactionChainListener {
+public class BGPPeer extends AbstractPeer implements BGPSessionListener {
private static final Logger LOG = LoggerFactory.getLogger(BGPPeer.class);
- private final ClusterIdentifier clusterId;
- private final AsNumber localAs;
private Set<TablesKey> tables = Collections.emptySet();
private final RIB rib;
- private final String name;
private final Map<TablesKey, AdjRibOutListener> adjRibOutListenerSet = new HashMap<>();
private final RpcProviderRegistry rpcRegistry;
- private final PeerRole peerRole;
private InstanceIdentifier<AdjRibOut> peerRibOutIId;
@GuardedBy("this")
private AbstractRegistration trackerRegistration;
@GuardedBy("this")
private BGPSession session;
@GuardedBy("this")
- private byte[] rawIdentifier;
- @GuardedBy("this")
private DOMTransactionChain chain;
@GuardedBy("this")
private AdjRibInWriter ribWriter;
private EffectiveRibInWriter effRibInWriter;
private RoutedRpcRegistration<BgpPeerRpcService> rpcRegistration;
private Map<TablesKey, SendReceive> addPathTableMaps = Collections.emptyMap();
- private PeerId peerId;
+ private YangInstanceIdentifier peerPath;
+ private boolean sessionUp;
public BGPPeer(
final IpAddress neighborAddress,
final RpcProviderRegistry rpcRegistry,
final Set<TablesKey> afiSafisAdvertized,
final Set<TablesKey> afiSafisGracefulAdvertized) {
- super(rib.getInstanceIdentifier(), peerGroupName, neighborAddress, afiSafisAdvertized,
- afiSafisGracefulAdvertized);
- this.peerRole = role;
+ super(rib, Ipv4Util.toStringIP(neighborAddress), peerGroupName, role, clusterId,
+ localAs, neighborAddress, afiSafisAdvertized, afiSafisGracefulAdvertized);
this.rib = requireNonNull(rib);
- this.clusterId = clusterId;
- this.localAs = localAs;
- this.name = Ipv4Util.toStringIP(neighborAddress);
this.rpcRegistry = rpcRegistry;
this.chain = rib.createPeerDOMChain(this);
}
@Override
public synchronized void onSessionUp(final BGPSession session) {
this.session = session;
+ this.sessionUp = true;
if (this.session instanceof BGPSessionStateProvider) {
((BGPSessionStateProvider) this.session).registerMessagesCounter(this);
}
addBgp4Support();
- this.ribWriter = this.ribWriter.transform(this.peerId, this.rib.getRibSupportContext(), this.tables,
- this.addPathTableMaps);
+ this.peerPath = createPeerPath();
+ this.ribWriter = this.ribWriter.transform(this.peerId, this.peerPath, this.rib.getRibSupportContext(),
+ this.tables, this.addPathTableMaps);
if (this.rpcRegistry != null) {
this.rpcRegistration = this.rpcRegistry.addRoutedRpcImplementation(BgpPeerRpcService.class,
this.tables = Collections.emptySet();
this.addPathTableMaps = Collections.emptyMap();
if (this.ribWriter != null) {
- return this.ribWriter.removePeer();
+ this.ribWriter = null;
}
- return Futures.immediateFuture(null);
+ return removePeer(this.chain, this.peerPath);
}
@Override
return toStringHelper;
}
- @Override
- public String getName() {
- return this.name;
- }
-
@Override
public synchronized ListenableFuture<Void> releaseConnection() {
+ LOG.info("Closing session with peer");
+ this.sessionUp = false;
+ closeRegistration();
if (this.rpcRegistration != null) {
this.rpcRegistration.close();
}
- closeRegistration();
final ListenableFuture<Void> future = cleanup();
if (this.session != null) {
}
}
- @Override
- public synchronized byte[] getRawIdentifier() {
- return Arrays.copyOf(this.rawIdentifier, this.rawIdentifier.length);
- }
-
- @Override
- public PeerId getPeerId() {
- return this.peerId;
- }
-
@SuppressFBWarnings("IS2_INCONSISTENT_SYNC")
@Override
public SendReceive getSupportedAddPathTables(final TablesKey tableKey) {
@Override
public boolean supportsTable(final TablesKey tableKey) {
- return this.tables.contains(tableKey);
- }
-
- @Override
- public PeerRole getRole() {
- return this.peerRole;
- }
-
- @Override
- public ClusterIdentifier getClusterId() {
- return this.clusterId;
- }
-
- @Override
- public AsNumber getLocalAs() {
- return this.localAs;
- }
-
- @Override
- public AsNumber getFromPeerLocalAs() {
- return getLocalAs();
+ return this.tables.contains(tableKey) && this.sessionUp;
}
@Override
final AsyncTransaction<?, ?> transaction, final Throwable cause) {
LOG.error("Transaction chain failed.", cause);
this.chain.close();
- //FIXME
+ //FIXME BGPCEP-731
/*
this.chain = this.rib.createPeerDOMChain(this);
this.ribWriter = AdjRibInWriter.create(this.rib.getYangRibId(), this.peerRole, this.chain);
releaseConnection();*/
}
- @Override
- public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
- LOG.debug("Transaction chain {} successful.", chain);
- }
-
@Override
public synchronized void markUptodate(final TablesKey tablesKey) {
this.ribWriter.markTableUptodate(tablesKey);
}
- @Override
- public BGPErrorHandlingState getBGPErrorHandlingState() {
- return this;
- }
-
- @Override
- public BGPAfiSafiState getBGPAfiSafiState() {
- return this;
- }
-
@Override
public synchronized BGPSessionState getBGPSessionState() {
if (this.session instanceof BGPSessionStateProvider) {
}
return null;
}
-
- @Override
- public PeerRole getFromPeerRole() {
- return getRole();
- }
-
- @Override
- public PeerId getFromPeerId() {
- return getPeerId();
- }
-
- @Override
- public ClusterIdentifier getFromClusterId() {
- return getClusterId();
- }
}
private final InstanceIdentifier<EffectiveRibIn> effRibTables;
private final DataBroker databroker;
private ListenerRegistration<?> reg;
- private final BindingTransactionChain chain;
+ private BindingTransactionChain chain;
private final Map<TablesKey, LongAdder> prefixesReceived;
private final Map<TablesKey, LongAdder> prefixesInstalled;
private final BGPRibRoutingPolicy ribPolicies;
@Override
@SuppressWarnings("unchecked")
public synchronized void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Tables>> changes) {
+ if (this.chain == null) {
+ LOG.trace("Chain closed. Ignoring Changes : {}", changes);
+ return;
+ }
LOG.trace("Data changed called to effective RIB. Change : {}", changes);
WriteTransaction tx = null;
for (final DataTreeModification<Tables> tc : changes) {
this.reg.close();
this.reg = null;
}
+ if (this.chain != null) {
+ this.chain.close();
+ this.chain = null;
+ }
this.prefixesReceived.values().forEach(LongAdder::reset);
this.prefixesInstalled.values().forEach(LongAdder::reset);
}
this.reg.close();
this.reg = null;
}
- this.chain.close();
+ if (this.chain != null) {
+ this.chain.close();
+ this.chain = null;
+ }
}
@Nonnull
* @param changes on supported table
*/
@Override
- public void onDataTreeChanged(final Collection<DataTreeModification<Tables>> changes) {
+ public synchronized void onDataTreeChanged(final Collection<DataTreeModification<Tables>> changes) {
+ if (this.chain == null) {
+ LOG.trace("Chain closed, ignoring received data change {} to LocRib {}", changes, this);
+ return;
+ }
LOG.trace("Received data change {} to LocRib {}", changes, this);
-
final WriteTransaction tx = this.chain.newWriteOnlyTransaction();
try {
final Map<RouteUpdateKey, RouteEntry> toUpdate = update(tx, changes);
assertNotNull(this.writer);
final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME,
AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
- this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, ADD_PATH_TABLE_MAPS);
+ this.writer.transform(new PeerId(this.peerIp), peerPath, this.registry, this.tableTypes, ADD_PATH_TABLE_MAPS);
verifyPeerSkeletonInsertedCorrectly(peerPath);
// verify supported tables were inserted for ipv4
Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME)
Mockito.verify(this.rib, times(1)).getLocalTablesKeys();
APP_PEER.instantiateServiceInstance();
- Mockito.verify(this.rib, times(2)).getYangRibId();
+ Mockito.verify(this.rib, times(3)).getYangRibId();
Mockito.verify(this.rib, times(2)).getRibSupportContext();
Mockito.verify(this.rib, times(2)).getLocalTablesKeys();
Mockito.verify(this.domTx).newWriteOnlyTransaction();
APP_PEER.restart(this.rib, null, this.peerGroupLoader, this.tableTypeRegistry);
APP_PEER.instantiateServiceInstance();
- Mockito.verify(this.rib, times(4)).getYangRibId();
+ Mockito.verify(this.rib, times(6)).getYangRibId();
Mockito.verify(this.rib, times(2)).getService();
Mockito.verify(this.listener).close();