package org.opendaylight.protocol.bgp.rib.impl.config;
-import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getNeighborInstanceIdentifier;
-import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getRibInstanceName;
+import static java.util.Objects.requireNonNull;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+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 com.google.common.util.concurrent.MoreExecutors;
import java.util.Collection;
-import java.util.Dictionary;
import java.util.HashMap;
-import java.util.Hashtable;
+import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
-import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
-import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType;
-import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroupKey;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.PeerGroups;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceBuilder;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.ProtocolsBuilder;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NetworkInstanceProtocol;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.blueprint.container.BlueprintContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class BgpDeployerImpl implements BgpDeployer, DataTreeChangeListener<Bgp>, AutoCloseable {
-
+public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener<Bgp>, PeerGroupConfigLoader,
+ AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(BgpDeployerImpl.class);
-
private final InstanceIdentifier<NetworkInstance> networkInstanceIId;
private final BlueprintContainer container;
private final BundleContext bundleContext;
- private final BGPOpenConfigMappingService mappingService;
- private final ListenerRegistration<BgpDeployerImpl> registration;
+ private final BGPTableTypeRegistryConsumer tableTypeRegistry;
+ private final ClusterSingletonServiceProvider provider;
@GuardedBy("this")
- private final Map<InstanceIdentifier<Bgp>, RibImpl> ribs = new HashMap<>();
- @GuardedBy("this")
- private final Map<InstanceIdentifier<Neighbor>, BgpPeer> peers = new HashMap<>();
+ private final Map<InstanceIdentifier<Bgp>, BGPClusterSingletonService> bgpCss = new HashMap<>();
+ private final DataBroker dataBroker;
+ private final LoadingCache<InstanceIdentifier<PeerGroup>, Optional<PeerGroup>> peerGroups
+ = CacheBuilder.newBuilder()
+ .build(new CacheLoader<InstanceIdentifier<PeerGroup>, Optional<PeerGroup>>() {
+ @Override
+ public Optional<PeerGroup> load(final InstanceIdentifier<PeerGroup> key)
+ throws ExecutionException, InterruptedException {
+ return loadPeerGroup(key);
+ }
+ });
+ private final String networkInstanceName;
+ private ListenerRegistration<BgpDeployerImpl> registration;
@GuardedBy("this")
private boolean closed;
- private final DataBroker dataBroker;
-
- public BgpDeployerImpl(final String networkInstanceName, final BlueprintContainer container, final BundleContext bundleContext, final DataBroker dataBroker,
- final BGPOpenConfigMappingService mappingService) {
- this.dataBroker = Preconditions.checkNotNull(dataBroker);
- this.container = Preconditions.checkNotNull(container);
- this.bundleContext = Preconditions.checkNotNull(bundleContext);
- this.mappingService = Preconditions.checkNotNull(mappingService);
- this.networkInstanceIId = InstanceIdentifier
- .create(NetworkInstances.class)
+ public BgpDeployerImpl(final String networkInstanceName, final ClusterSingletonServiceProvider provider,
+ final BlueprintContainer container,
+ final BundleContext bundleContext, final DataBroker dataBroker,
+ final BGPTableTypeRegistryConsumer mappingService) {
+ this.dataBroker = requireNonNull(dataBroker);
+ this.provider = requireNonNull(provider);
+ this.networkInstanceName = requireNonNull(networkInstanceName);
+ this.container = requireNonNull(container);
+ this.bundleContext = requireNonNull(bundleContext);
+ this.tableTypeRegistry = requireNonNull(mappingService);
+ this.networkInstanceIId = InstanceIdentifier.create(NetworkInstances.class)
.child(NetworkInstance.class, new NetworkInstanceKey(networkInstanceName));
- Futures.addCallback(initializeNetworkInstance(dataBroker, this.networkInstanceIId), new FutureCallback<Void>() {
+ initializeNetworkInstance(dataBroker, this.networkInstanceIId).addCallback(new FutureCallback<CommitInfo>() {
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
LOG.debug("Network Instance {} initialized successfully.", networkInstanceName);
}
+
@Override
- public void onFailure(final Throwable t) {
- LOG.error("Failed to initialize Network Instance {}.", networkInstanceName, t);
+ public void onFailure(final Throwable throwable) {
+ LOG.error("Failed to initialize Network Instance {}.", networkInstanceName, throwable);
}
- });
- this.registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, this.networkInstanceIId.child(Protocols.class)
- .child(Protocol.class)
- .augmentation(Protocol1.class)
- .child(Bgp.class)), this);
- LOG.info("BGP Deployer {} started.", networkInstanceName);
+ }, MoreExecutors.directExecutor());
+ }
+
+ public synchronized void init() {
+ this.registration = this.dataBroker.registerDataTreeChangeListener(
+ new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ this.networkInstanceIId.child(Protocols.class).child(Protocol.class)
+ .augmentation(NetworkInstanceProtocol.class).child(Bgp.class)), this);
+ LOG.info("BGP Deployer {} started.", this.networkInstanceName);
+ }
+
+ private Optional<PeerGroup> loadPeerGroup(final InstanceIdentifier<PeerGroup> peerGroupIid)
+ throws ExecutionException, InterruptedException {
+ final ReadOnlyTransaction tr = this.dataBroker.newReadOnlyTransaction();
+ return tr.read(LogicalDatastoreType.CONFIGURATION, peerGroupIid).get().toJavaUtil();
}
@Override
LOG.trace("BGP Deployer was already closed, skipping changes.");
return;
}
+
for (final DataTreeModification<Bgp> dataTreeModification : changes) {
final InstanceIdentifier<Bgp> rootIdentifier = dataTreeModification.getRootPath().getRootIdentifier();
final DataObjectModification<Bgp> rootNode = dataTreeModification.getRootNode();
- LOG.trace("BGP configuration has changed: {}", rootNode);
- for (final DataObjectModification<? extends DataObject> dataObjectModification : rootNode.getModifiedChildren()) {
- if (dataObjectModification.getDataType().equals(Global.class)) {
- onGlobalChanged((DataObjectModification<Global>) dataObjectModification, rootIdentifier);
- } else if (dataObjectModification.getDataType().equals(Neighbors.class)) {
- onNeighborsChanged((DataObjectModification<Neighbors>) dataObjectModification, rootIdentifier);
- }
- }
+ final List<DataObjectModification<? extends DataObject>> deletedConfig
+ = rootNode.getModifiedChildren().stream()
+ .filter(mod -> mod.getModificationType() == DataObjectModification.ModificationType.DELETE)
+ .collect(Collectors.toList());
+ final List<DataObjectModification<? extends DataObject>> changedConfig
+ = rootNode.getModifiedChildren().stream()
+ .filter(mod -> mod.getModificationType() != DataObjectModification.ModificationType.DELETE)
+ .collect(Collectors.toList());
+ handleDeletions(deletedConfig, rootIdentifier);
+ handleModifications(changedConfig, rootIdentifier);
}
}
- @Override
- public InstanceIdentifier<NetworkInstance> getInstanceIdentifier() {
- return this.networkInstanceIId;
- }
-
- @Override
- public synchronized void close() throws Exception {
- this.registration.close();
- this.peers.values().forEach(bgpPeer -> bgpPeer.close());
- this.peers.clear();
- this.ribs.values().forEach(rib -> rib.close());
- this.ribs.clear();
- this.closed = true;
- }
-
- private static CheckedFuture<Void, TransactionCommitFailedException> initializeNetworkInstance(final DataBroker dataBroker,
- final InstanceIdentifier<NetworkInstance> networkInstance) {
- final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
- wTx.merge(LogicalDatastoreType.CONFIGURATION, networkInstance,
- new NetworkInstanceBuilder().setName(networkInstance.firstKeyOf(NetworkInstance.class).getName()).setProtocols(new ProtocolsBuilder().build()).build());
- return wTx.submit();
- }
-
- private void onGlobalChanged(final DataObjectModification<Global> dataObjectModification,
+ private void handleModifications(final List<DataObjectModification<? extends DataObject>> changedConfig,
final InstanceIdentifier<Bgp> rootIdentifier) {
- switch (dataObjectModification.getModificationType()) {
- case DELETE:
- onGlobalRemoved(rootIdentifier);
- break;
- case SUBTREE_MODIFIED:
- case WRITE:
- onGlobalModified(rootIdentifier, dataObjectModification.getDataAfter());
- break;
- default:
- break;
+ final List<DataObjectModification<? extends DataObject>> globalMod = changedConfig.stream()
+ .filter(mod -> mod.getDataType().equals(Global.class))
+ .collect(Collectors.toList());
+ final List<DataObjectModification<? extends DataObject>> peerMod = changedConfig.stream()
+ .filter(mod -> !mod.getDataType().equals(Global.class))
+ .collect(Collectors.toList());
+ if (!globalMod.isEmpty()) {
+ handleGlobalChange(globalMod, rootIdentifier);
+ }
+ if (!peerMod.isEmpty()) {
+ handlePeersChange(peerMod, rootIdentifier);
}
}
- private void onGlobalModified(final InstanceIdentifier<Bgp> rootIdentifier, final Global global) {
- LOG.debug("Modifing RIB instance with configuration: {}", global);
- //restart existing rib instance with a new configuration
- final RibImpl ribImpl = this.ribs.get(rootIdentifier);
- if (ribImpl != null) {
- ribImpl.close();
- initiateRibInstance(rootIdentifier, global, ribImpl);
- } else {
- //if not exists, create a new instance
- onGlobalCreated(rootIdentifier, global);
+ private void handleDeletions(final List<DataObjectModification<? extends DataObject>> deletedConfig,
+ final InstanceIdentifier<Bgp> rootIdentifier) {
+ final List<DataObjectModification<? extends DataObject>> globalMod = deletedConfig.stream()
+ .filter(mod -> mod.getDataType().equals(Global.class))
+ .collect(Collectors.toList());
+ final List<DataObjectModification<? extends DataObject>> peerMod = deletedConfig.stream()
+ .filter(mod -> !mod.getDataType().equals(Global.class))
+ .collect(Collectors.toList());
+ if (!globalMod.isEmpty()) {
+ handleGlobalChange(globalMod, rootIdentifier);
+ }
+ if (!peerMod.isEmpty()) {
+ handlePeersChange(peerMod, rootIdentifier);
}
- LOG.debug("RIB instance modified {}", ribImpl);
}
- private void onGlobalCreated(final InstanceIdentifier<Bgp> rootIdentifier, final Global global) {
- //create, start and register rib instance
- LOG.debug("Creating RIB instance with configuration: {}", global);
- final RibImpl ribImpl = (RibImpl) this.container.getComponentInstance(InstanceType.RIB.getBeanName());
- initiateRibInstance(rootIdentifier, global, ribImpl);
- this.ribs.put(rootIdentifier, ribImpl);
- LOG.debug("RIB instance created {}", ribImpl);
+ private void handleGlobalChange(
+ final List<DataObjectModification<? extends DataObject>> config,
+ final InstanceIdentifier<Bgp> rootIdentifier) {
+ for (final DataObjectModification<? extends DataObject> dataObjectModification : config) {
+ onGlobalChanged((DataObjectModification<Global>) dataObjectModification, rootIdentifier);
+ }
}
- private void onGlobalRemoved(final InstanceIdentifier<Bgp> rootIdentifier) {
- //destroy rib instance
- LOG.debug("Removing RIB instance: {}", rootIdentifier);
- final RibImpl ribImpl = this.ribs.remove(rootIdentifier);
- if (ribImpl != null) {
- ribImpl.close();
- LOG.debug("RIB instance removed {}", ribImpl);
+ private void handlePeersChange(
+ final List<DataObjectModification<? extends DataObject>> config,
+ final InstanceIdentifier<Bgp> rootIdentifier) {
+ for (final DataObjectModification<? extends DataObject> dataObjectModification : config) {
+ if (dataObjectModification.getDataType().equals(Neighbors.class)) {
+ onNeighborsChanged((DataObjectModification<Neighbors>) dataObjectModification, rootIdentifier);
+ } else if (dataObjectModification.getDataType().equals(PeerGroups.class)) {
+ rebootNeighbors((DataObjectModification<PeerGroups>) dataObjectModification);
+ }
}
}
- private void registerRibInstance(final RibImpl ribImpl, final String ribInstanceName) {
- final Dictionary<String, String> properties = new Hashtable<>();
- properties.put(InstanceType.RIB.getBeanName(), ribInstanceName);
- final ServiceRegistration<?> serviceRegistration = this.bundleContext.registerService(InstanceType.RIB.getServices(), ribImpl, properties);
- ribImpl.setServiceRegistration(serviceRegistration);
+ private synchronized void rebootNeighbors(final DataObjectModification<PeerGroups> dataObjectModification) {
+ PeerGroups peerGroups = dataObjectModification.getDataAfter();
+ if (peerGroups == null) {
+ peerGroups = dataObjectModification.getDataBefore();
+ }
+ if (peerGroups == null) {
+ return;
+ }
+ for (final PeerGroup peerGroup: peerGroups.getPeerGroup()) {
+ this.bgpCss.values().forEach(css->css.restartNeighbors(peerGroup.getPeerGroupName()));
+ }
}
- private void initiateRibInstance(final InstanceIdentifier<Bgp> rootIdentifier, final Global global,
- final RibImpl ribImpl) {
- final String ribInstanceName = getRibInstanceName(rootIdentifier);
- ribImpl.start(global, ribInstanceName, this.mappingService);
- registerRibInstance(ribImpl, ribInstanceName);
- }
+ @Override
+ public synchronized void close() {
+ LOG.info("Closing BGP Deployer.");
+ if (this.registration != null) {
+ this.registration.close();
+ this.registration = null;
+ }
+ this.closed = true;
- private void onNeighborsChanged(final DataObjectModification<Neighbors> dataObjectModification,
- final InstanceIdentifier<Bgp> rootIdentifier) {
- for (final DataObjectModification<? extends DataObject> neighborModification : dataObjectModification.getModifiedChildren()) {
- switch (neighborModification.getModificationType()) {
- case DELETE:
- onNeighborRemoved(rootIdentifier, (Neighbor) neighborModification.getDataBefore());
- break;
- case SUBTREE_MODIFIED:
- case WRITE:
- onNeighborModified(rootIdentifier, (Neighbor) neighborModification.getDataAfter());
- break;
- default:
- break;
+ this.bgpCss.values().iterator().forEachRemaining(service -> {
+ try {
+ service.close();
+ } catch (Exception e) {
+ LOG.warn("Failed to close BGP Cluster Singleton Service.");
}
- }
- }
+ });
- private void onNeighborModified(final InstanceIdentifier<Bgp> rootIdentifier, final Neighbor neighbor) {
- LOG.debug("Modifing Peer instance with configuration: {}", neighbor);
- //restart peer instance with a new configuration
- final BgpPeer bgpPeer = this.peers.get(getNeighborInstanceIdentifier(rootIdentifier, neighbor.getKey()));
- if (bgpPeer != null) {
- bgpPeer.close();
- bgpPeer.start(this.ribs.get(rootIdentifier), neighbor, this.mappingService);
- } else {
- //create new instance, if none is present
- onNeighborCreated(rootIdentifier, neighbor);
- }
- LOG.debug("Peer instance modified {}", bgpPeer);
}
- private void onNeighborCreated(final InstanceIdentifier<Bgp> rootIdentifier, final Neighbor neighbor) {
- //create, start and register peer instance
- LOG.debug("Creating Peer instance with configuration: {}", neighbor);
- final BgpPeer bgpPeer = (BgpPeer) this.container.getComponentInstance(InstanceType.PEER.getBeanName());
- bgpPeer.start(this.ribs.get(rootIdentifier), neighbor, this.mappingService);
- this.peers.put(getNeighborInstanceIdentifier(rootIdentifier, neighbor.getKey()), bgpPeer);
- LOG.debug("Peer instance created {}", bgpPeer);
+ private static FluentFuture<? extends CommitInfo> initializeNetworkInstance(
+ final DataBroker dataBroker, final InstanceIdentifier<NetworkInstance> networkInstance) {
+ final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
+ wTx.merge(LogicalDatastoreType.CONFIGURATION, networkInstance,
+ new NetworkInstanceBuilder().setName(networkInstance.firstKeyOf(NetworkInstance.class).getName())
+ .setProtocols(new ProtocolsBuilder().build()).build());
+ return wTx.commit();
}
- private void onNeighborRemoved(final InstanceIdentifier<Bgp> rootIdentifier, final Neighbor neighbor) {
- //destroy peer instance
- LOG.debug("Removing Peer instance: {}", rootIdentifier);
- final BgpPeer bgpPeer = this.peers.remove(getNeighborInstanceIdentifier(rootIdentifier, neighbor.getKey()));
- if (bgpPeer != null) {
- bgpPeer.close();
- LOG.debug("Peer instance removed {}", bgpPeer);
+ @VisibleForTesting
+ synchronized void onGlobalChanged(final DataObjectModification<Global> dataObjectModification,
+ final InstanceIdentifier<Bgp> bgpInstanceIdentifier) {
+ BGPClusterSingletonService old = this.bgpCss.get(bgpInstanceIdentifier);
+ if (old == null) {
+ old = new BGPClusterSingletonService(this, this.provider, this.tableTypeRegistry,
+ this.container, this.bundleContext, bgpInstanceIdentifier);
+ this.bgpCss.put(bgpInstanceIdentifier, old);
}
+ old.onGlobalChanged(dataObjectModification);
}
- @Override
- public <T extends DataObject> ListenableFuture<Void> writeConfiguration(final T data,
- final InstanceIdentifier<T> identifier) {
- final ReadWriteTransaction wTx = this.dataBroker.newReadWriteTransaction();
- final CheckedFuture<Optional<T>, ReadFailedException> readFuture = wTx.read(LogicalDatastoreType.CONFIGURATION, identifier);
- Futures.addCallback(readFuture, new FutureCallback<Optional<T>>() {
- @Override
- public void onSuccess(final Optional<T> result) {
- if (!result.isPresent()) {
- wTx.put(LogicalDatastoreType.CONFIGURATION, identifier, data);
- }
- }
- @Override
- public void onFailure(final Throwable t) {
- LOG.debug("Failed to ensure presence of {}, try to write configuration.", identifier, t);
- wTx.put(LogicalDatastoreType.CONFIGURATION, identifier, data);
- }
- });
- return wTx.submit();
-
+ @VisibleForTesting
+ synchronized void onNeighborsChanged(final DataObjectModification<Neighbors> dataObjectModification,
+ final InstanceIdentifier<Bgp> bgpInstanceIdentifier) {
+ BGPClusterSingletonService old = this.bgpCss.get(bgpInstanceIdentifier);
+ if (old == null) {
+ old = new BGPClusterSingletonService(this, this.provider, this.tableTypeRegistry,
+ this.container, this.bundleContext, bgpInstanceIdentifier);
+ this.bgpCss.put(bgpInstanceIdentifier, old);
+ }
+ old.onNeighborsChanged(dataObjectModification);
}
- @Override
- public <T extends DataObject> ListenableFuture<Void> removeConfiguration(
- final InstanceIdentifier<T> identifier) {
- final WriteTransaction wTx = this.dataBroker.newWriteOnlyTransaction();
- wTx.delete(LogicalDatastoreType.CONFIGURATION, identifier);
- return wTx.submit();
+ @VisibleForTesting
+ BGPTableTypeRegistryConsumer getTableTypeRegistry() {
+ return this.tableTypeRegistry;
}
@Override
- public BGPOpenConfigMappingService getMappingService() {
- return this.mappingService;
+ public PeerGroup getPeerGroup(final InstanceIdentifier<Bgp> bgpIid, final String peerGroupName) {
+ final InstanceIdentifier<PeerGroup> peerGroupsIid =
+ bgpIid.child(PeerGroups.class).child(PeerGroup.class, new PeerGroupKey(peerGroupName));
+ return this.peerGroups.getUnchecked(peerGroupsIid).orElse(null);
}
-
}