import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.api.RpcProviderService;
import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
-import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
import org.opendaylight.protocol.bgp.parser.BGPError;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.GracefulRestartCapability;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.add.path.capability.AddressFamilies;
-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.ResetSession;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev180329.RestartGracefully;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev180329.RouteRefreshRequest;
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.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteTarget;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.SubsequentAddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
-import org.opendaylight.yangtools.concepts.ObjectRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.slf4j.Logger;
*/
public class BGPPeer extends AbstractPeer implements BGPSessionListener {
private static final Logger LOG = LoggerFactory.getLogger(BGPPeer.class);
- private static final TablesKey IPV4_UCAST_TABLE_KEY = new TablesKey(Ipv4AddressFamily.class,
- UnicastSubsequentAddressFamily.class);
+ private static final TablesKey IPV4_UCAST_TABLE_KEY =
+ new TablesKey(Ipv4AddressFamily.VALUE, UnicastSubsequentAddressFamily.VALUE);
private final RIB rib;
private AdjRibInWriter ribWriter;
@GuardedBy("this")
private EffectiveRibInWriter effRibInWriter;
- private ObjectRegistration<BgpPeerRpcService> rpcRegistration;
- private Map<TablesKey, SendReceive> addPathTableMaps = Collections.emptyMap();
+ private Registration rpcRegistration;
+ private ImmutableMap<TablesKey, SendReceive> addPathTableMaps = ImmutableMap.of();
// FIXME: This should be a constant co-located with ApplicationPeer.peerId
private YangInstanceIdentifier peerPath;
// FIXME: This is for supportsTable() -- a trivial behavior thing, where 'peer-down' type states always return false
final Set<TablesKey> afiSafisGracefulAdvertized,
final Map<TablesKey, Integer> llGracefulTablesAdvertised,
final BgpPeer bgpPeer) {
- super(rib, Ipv4Util.toStringIP(neighborAddress), peerGroupName, role, clusterId,
- localAs, neighborAddress, afiSafisAdvertized, afiSafisGracefulAdvertized, llGracefulTablesAdvertised);
+ super(rib, Ipv4Util.toStringIP(neighborAddress), peerGroupName, role, clusterId, localAs, neighborAddress,
+ afiSafisAdvertized, afiSafisGracefulAdvertized, llGracefulTablesAdvertised);
this.tableTypeRegistry = requireNonNull(tableTypeRegistry);
this.rib = requireNonNull(rib);
this.rpcRegistry = rpcRegistry;
this.bgpPeer = bgpPeer;
+
+ createDomChain();
}
private static Attributes nextHopToAttribute(final Attributes attrs, final MpReachNlri mpReach) {
final List<Ipv4Prefixes> prefixes = message.getNlri().stream()
.map(n -> new Ipv4PrefixesBuilder().setPrefix(n.getPrefix()).setPathId(n.getPathId()).build())
.collect(Collectors.toList());
- final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
- UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
- new AdvertizedRoutesBuilder().setDestinationType(
- new DestinationIpv4CaseBuilder().setDestinationIpv4(
- new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
+ final MpReachNlriBuilder b = new MpReachNlriBuilder()
+ .setAfi(Ipv4AddressFamily.VALUE)
+ .setSafi(UnicastSubsequentAddressFamily.VALUE)
+ .setAdvertizedRoutes(new AdvertizedRoutesBuilder()
+ .setDestinationType(new DestinationIpv4CaseBuilder()
+ .setDestinationIpv4(new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build())
+ .build())
+ .build());
if (message.getAttributes() != null) {
b.setCNextHop(message.getAttributes().getCNextHop());
}
prefixes.add(new Ipv4PrefixesBuilder().setPrefix(w.getPrefix()).setPathId(w.getPathId()).build());
}
});
- return new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class)
+ return new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.VALUE).setSafi(UnicastSubsequentAddressFamily.VALUE)
.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1
.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.unreach.nlri
.withdrawn.routes.destination.type.DestinationIpv4CaseBuilder().setDestinationIpv4(
new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build();
}
- private static Map<TablesKey, SendReceive> mapTableTypesFamilies(final List<AddressFamilies> addPathTablesType) {
+ private static ImmutableMap<TablesKey, SendReceive> mapTableTypesFamilies(
+ final List<AddressFamilies> addPathTablesType) {
return addPathTablesType.stream().collect(ImmutableMap.toImmutableMap(
af -> new TablesKey(af.getAfi(), af.getSafi()), BgpAddPathTableType::getSendReceive));
}
@Override
public void onMessage(final BGPSession session, final Notification<?> msg) throws BGPDocumentedException {
- if (msg instanceof Update) {
- onUpdateMessage((Update) msg);
- } else if (msg instanceof RouteRefresh) {
- onRouteRefreshMessage((RouteRefresh) msg);
+ if (msg instanceof Update update) {
+ onUpdateMessage(update);
+ } else if (msg instanceof RouteRefresh routeRefresh) {
+ onRouteRefreshMessage(routeRefresh);
} else {
LOG.info("Ignoring unhandled message class {}", msg.getClass());
}
}
private void onRouteRefreshMessage(final RouteRefresh message) {
- final Class<? extends AddressFamily> rrAfi = message.getAfi();
- final Class<? extends SubsequentAddressFamily> rrSafi = message.getSafi();
+ final var rrAfi = message.getAfi();
+ final var rrSafi = message.getSafi();
final TablesKey key = new TablesKey(rrAfi, rrSafi);
synchronized (this) {
currentSession = session;
sessionUp = true;
- ribOutChain = rib.createPeerDOMChain(new DOMTransactionChainListener() {
+ final var chain = rib.createPeerDOMChain();
+ ribOutChain = chain;
+ chain.addCallback(new FutureCallback<Empty>() {
@Override
- public void onTransactionChainSuccessful(final DOMTransactionChain chain) {
+ public void onSuccess(final Empty result) {
LOG.debug("RibOut transaction chain {} successful.", chain);
}
@Override
- public void onTransactionChainFailed(final DOMTransactionChain chain,
- final DOMDataTreeTransaction transaction, final Throwable cause) {
+ public void onFailure(final Throwable cause) {
onRibOutChainFailed(cause);
}
});
- if (currentSession instanceof BGPSessionStateProvider) {
- ((BGPSessionStateProvider) currentSession).registerMessagesCounter(this);
+ if (currentSession instanceof BGPSessionStateProvider stateProvider) {
+ stateProvider.registerMessagesCounter(this);
}
final GracefulRestartCapability advertisedGracefulRestartCapability =
session.getAdvertisedGracefulRestartCapability();
tables, addPathTableMaps);
if (rpcRegistry != null) {
- rpcRegistration = rpcRegistry.registerRpcImplementation(BgpPeerRpcService.class,
- new BgpPeerRpc(this, session, tables), ImmutableSet.of(rib.getInstanceIdentifier().child(
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib
- .Peer.class, new PeerKey(peerId))));
+ final var bgpPeerHandler = new BgpPeerRpc(this, session, tables);
+ rpcRegistration = rpcRegistry.registerRpcImplementations(List.of(
+ (ResetSession) bgpPeerHandler::resetSession,
+ (RestartGracefully) bgpPeerHandler::restartGracefully,
+ (RouteRefreshRequest) bgpPeerHandler::routeRefreshRequest), ImmutableSet.of(
+ rib.getInstanceIdentifier().child(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib
+ .rib.Peer.class, new PeerKey(peerId))));
}
} else {
final Set<TablesKey> forwardingTables;
// SpotBugs does not grok Optional.ifPresent() and thinks we are using unsynchronized access
final Optional<RevisedErrorHandlingSupport> errorHandling = bgpPeer.getErrorHandling();
if (errorHandling.isPresent()) {
- currentSession.addDecoderConstraint(RevisedErrorHandlingSupport.class, errorHandling.get());
+ currentSession.addDecoderConstraint(RevisedErrorHandlingSupport.class, errorHandling.orElseThrow());
}
}
}
private synchronized void createEffRibInWriter() {
- effRibInWriter = new EffectiveRibInWriter(this, rib,
- rib.createPeerDOMChain(this),
- peerPath, tables, tableTypeRegistry,
- rtMemberships,
+ final var chain = rib.createPeerDOMChain();
+ chain.addCallback(this);
+
+ effRibInWriter = new EffectiveRibInWriter(this, rib, chain, peerPath, tables, tableTypeRegistry, rtMemberships,
rtCache);
}
final RIBSupport<?, ?> ribSupport = rib.getRibSupportContext().getRIBSupport(key);
// not particularly nice
- if (ribSupport != null && currentSession instanceof BGPSessionImpl) {
- final ChannelOutputLimiter limiter = ((BGPSessionImpl) currentSession).getLimiter();
- final AdjRibOutListener adjRibOut = AdjRibOutListener.create(peerId, key,
- rib.getYangRibId(), rib.getCodecsRegistry(), ribSupport,
- rib.getService(), limiter, mpSupport);
+ if (ribSupport != null && currentSession instanceof BGPSessionImpl bgpSession) {
+ final AdjRibOutListener adjRibOut = AdjRibOutListener.create(peerId, rib.getYangRibId(),
+ rib.getCodecsRegistry(), ribSupport, rib.getService(), bgpSession.getLimiter(), mpSupport);
adjRibOutListenerSet.put(key, adjRibOut);
registerPrefixesSentCounter(key, adjRibOut);
}
}
private synchronized FluentFuture<? extends CommitInfo> terminateConnection() {
- final FluentFuture<? extends CommitInfo> future;
if (trackerRegistration != null) {
trackerRegistration.close();
trackerRegistration = null;
effRibInWriter.close();
}
tables = ImmutableSet.of();
- addPathTableMaps = Collections.emptyMap();
- future = removePeer(peerPath);
+ addPathTableMaps = ImmutableMap.of();
+ final var future = removePeer(peerPath);
resetState();
return future;
}
@Override
- public synchronized void onTransactionChainFailed(final DOMTransactionChain chain,
- final DOMDataTreeTransaction transaction, final Throwable cause) {
+ public synchronized void onFailure(final Throwable cause) {
LOG.error("Transaction domChain failed.", cause);
releaseConnection(true);
}
@Override
public synchronized BGPSessionState getBGPSessionState() {
- if (currentSession instanceof BGPSessionStateProvider) {
- return ((BGPSessionStateProvider) currentSession).getBGPSessionState();
+ if (currentSession instanceof BGPSessionStateProvider stateProvider) {
+ return stateProvider.getBGPSessionState();
}
return null;
}
@Override
public synchronized BGPTimersState getBGPTimersState() {
- if (currentSession instanceof BGPSessionStateProvider) {
- return ((BGPSessionStateProvider) currentSession).getBGPTimersState();
+ if (currentSession instanceof BGPSessionStateProvider stateProvider) {
+ return stateProvider.getBGPTimersState();
}
return null;
}
@Override
public synchronized BGPTransportState getBGPTransportState() {
- if (currentSession instanceof BGPSessionStateProvider) {
- return ((BGPSessionStateProvider) currentSession).getBGPTransportState();
+ if (currentSession instanceof BGPSessionStateProvider stateProvider) {
+ return stateProvider.getBGPTransportState();
}
return null;
}