+ synchronized void removePeer(final BGPPeerRegistry bgpPeerRegistry) {
+ if (BgpPeer.this.currentConfiguration != null) {
+ bgpPeerRegistry.removePeer(BgpPeer.this.currentConfiguration.getNeighborAddress());
+ }
+ }
+
+ private final class BgpPeerSingletonService implements BGPPeerStateConsumer {
+ private boolean activeConnection;
+ private final BGPDispatcher dispatcher;
+ private final InetSocketAddress inetAddress;
+ private final int retryTimer;
+ private final KeyMapping keys;
+ private final InetSocketAddress localAddress;
+ private final BGPPeer bgpPeer;
+ private final IpAddress neighborAddress;
+ private final BGPSessionPreferences prefs;
+ private Future<Void> connection;
+ private boolean isServiceInstantiated;
+
+ private BgpPeerSingletonService(final RIB rib, final Neighbor neighbor, final InstanceIdentifier<Bgp> bgpIid,
+ final PeerGroupConfigLoader peerGroupLoader, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
+ this.neighborAddress = neighbor.getNeighborAddress();
+
+ PeerGroup peerGroup = null;
+ String peerGroupName = null;
+ final Config neighborConfig = neighbor.getConfig();
+ if (neighborConfig != null) {
+ final NeighborPeerGroupConfig pgConfig = neighborConfig.getAugmentation(NeighborPeerGroupConfig.class);
+ if (pgConfig != null) {
+ peerGroupName = StringUtils.substringBetween(pgConfig.getPeerGroup(), "=\"", "\"");
+ peerGroup = peerGroupLoader.getPeerGroup(bgpIid, peerGroupName);
+ }
+ }
+ final AfiSafis afisSAfis;
+ if (peerGroup != null && peerGroup.getAfiSafis() != null) {
+ afisSAfis = peerGroup.getAfiSafis();
+ } else {
+ afisSAfis = requireNonNull(neighbor.getAfiSafis(), "Missing mandatory AFIs/SAFIs");
+ }
+
+ final Set<TablesKey> afiSafisAdvertized = OpenConfigMappingUtil
+ .toTableKey(afisSAfis.getAfiSafi(), tableTypeRegistry);
+
+ final PeerRole role = OpenConfigMappingUtil.toPeerRole(neighbor, peerGroup);
+ final ClusterIdentifier clusterId = OpenConfigMappingUtil
+ .getNeighborClusterIdentifier(neighbor.getConfig());
+
+ this.bgpPeer = new BGPPeer(this.neighborAddress, peerGroupName, rib, role, clusterId,
+ BgpPeer.this.rpcRegistry, afiSafisAdvertized, Collections.emptySet());
+
+ final List<BgpParameters> bgpParameters = getBgpParameters(afisSAfis, rib, tableTypeRegistry);
+ final KeyMapping keyMapping = OpenConfigMappingUtil.getNeighborKey(neighbor);
+ final IpAddress neighborLocalAddress = OpenConfigMappingUtil.getLocalAddress(neighbor.getTransport());
+ int hold = OpenConfigMappingUtil.getHoldTimer(neighbor, peerGroup);
+ final AsNumber ribAs = rib.getLocalAs();
+ final AsNumber neighborAs = OpenConfigMappingUtil.getPeerAs(neighbor, peerGroup, ribAs);
+
+ this.prefs = new BGPSessionPreferences(ribAs, hold, rib.getBgpIdentifier(),
+ neighborAs, bgpParameters, getPassword(keyMapping));
+ this.activeConnection = OpenConfigMappingUtil.isActive(neighbor, peerGroup);
+ this.retryTimer = OpenConfigMappingUtil.getRetryTimer(neighbor, peerGroup);
+ this.dispatcher = rib.getDispatcher();
+
+ final PortNumber port = OpenConfigMappingUtil.getPort(neighbor, peerGroup);
+ this.inetAddress = Ipv4Util.toInetSocketAddress(this.neighborAddress, port);
+ if (neighborLocalAddress != null) {
+ this.localAddress = Ipv4Util.toInetSocketAddress(neighborLocalAddress, port);
+ } else {
+ this.localAddress = null;
+ }
+ this.keys = keyMapping;
+ }
+
+ private synchronized void instantiateServiceInstance() {
+ this.isServiceInstantiated = true;
+ LOG.info("Peer instantiated {}", this.neighborAddress);
+ this.bgpPeer.instantiateServiceInstance();
+ this.dispatcher.getBGPPeerRegistry().addPeer(this.neighborAddress, this.bgpPeer, this.prefs);
+ if (this.activeConnection) {
+ this.connection = this.dispatcher.createReconnectingClient(this.inetAddress, this.localAddress,
+ this.retryTimer, this.keys);
+ }
+ }
+
+ private synchronized ListenableFuture<Void> closeServiceInstance() {
+ if (!this.isServiceInstantiated) {
+ LOG.info("Peer {} already closed", this.neighborAddress);
+ return Futures.immediateFuture(null);
+ }
+ LOG.info("Close Peer {}", this.neighborAddress);
+ this.isServiceInstantiated = false;
+ if (this.connection != null) {
+ this.connection.cancel(true);
+ this.connection = null;
+ }
+ final ListenableFuture<Void> future = this.bgpPeer.close();
+ removePeer(this.dispatcher.getBGPPeerRegistry());
+ return future;
+ }
+
+ @Override
+ public BGPPeerState getPeerState() {
+ return this.bgpPeer.getPeerState();
+ }
+ }