From 60fcf81022ccffc609ee489014b7c89a155a048e Mon Sep 17 00:00:00 2001 From: marekzatko Date: Fri, 6 Aug 2021 13:44:44 +0200 Subject: [PATCH] Migrate bgp-rib-impl to OSGi DS Also split BgpDeployerImpl into: - DefaultBgpDeployer - OSGiBgpDeployer JIRA: BGPCEP-958 Change-Id: I3ff92bedc6f6c7b215fb7dba7ef0eb4df9f59072 Signed-off-by: marekzatko Signed-off-by: Robert Varga --- bgp/rib-impl/pom.xml | 6 - .../protocol/bgp/rib/impl/config/AppPeer.java | 11 -- .../config/BGPClusterSingletonService.java | 116 ++++++-------- .../protocol/bgp/rib/impl/config/BgpPeer.java | 11 -- ...loyerImpl.java => DefaultBgpDeployer.java} | 134 ++++++++++------- .../bgp/rib/impl/config/OSGiBgpDeployer.java | 57 +++++++ .../protocol/bgp/rib/impl/config/RibImpl.java | 13 -- .../bgp/rib/impl/spi/InstanceType.java | 42 ------ .../resources/OSGI-INF/blueprint/bgp-rib.xml | 47 ------ .../bgp/rib/impl/config/AbstractConfig.java | 3 - ...oyerImplTest.java => BgpDeployerTest.java} | 141 ++++++++++-------- .../bgp/rib/impl/config/BgpPeerTest.java | 5 - .../bgp/rib/impl/config/RibImplTest.java | 7 - 13 files changed, 260 insertions(+), 333 deletions(-) rename bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/{BgpDeployerImpl.java => DefaultBgpDeployer.java} (73%) create mode 100644 bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OSGiBgpDeployer.java delete mode 100644 bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java delete mode 100644 bgp/rib-impl/src/main/resources/OSGI-INF/blueprint/bgp-rib.xml rename bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/{BgpDeployerImplTest.java => BgpDeployerTest.java} (65%) diff --git a/bgp/rib-impl/pom.xml b/bgp/rib-impl/pom.xml index ac61fba9c9..991a76494a 100644 --- a/bgp/rib-impl/pom.xml +++ b/bgp/rib-impl/pom.xml @@ -183,12 +183,6 @@ metainf-services - - - org.osgi - osgi.core - - ${project.groupId} diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeer.java index 2dd3dcfc33..31b0205af1 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeer.java @@ -34,7 +34,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; -import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,8 +45,6 @@ public final class AppPeer implements PeerBean, BGPPeerStateConsumer { private Neighbor currentConfiguration; @GuardedBy("this") private BgpAppPeerSingletonService bgpAppPeerSingletonService; - @GuardedBy("this") - private ServiceRegistration serviceRegistration; private static ApplicationRibId createAppRibId(final Neighbor neighbor) { final Config config = neighbor.getConfig(); @@ -80,10 +77,6 @@ public final class AppPeer implements PeerBean, BGPPeerStateConsumer { if (this.bgpAppPeerSingletonService != null) { this.bgpAppPeerSingletonService = null; } - if (this.serviceRegistration != null) { - this.serviceRegistration.unregister(); - this.serviceRegistration = null; - } } @Override @@ -113,10 +106,6 @@ public final class AppPeer implements PeerBean, BGPPeerStateConsumer { return this.bgpAppPeerSingletonService.getPeerState(); } - synchronized void setServiceRegistration(final ServiceRegistration serviceRegistration) { - this.serviceRegistration = serviceRegistration; - } - private static final class BgpAppPeerSingletonService implements BGPPeerStateConsumer { private final ApplicationPeer applicationPeer; private final DOMDataTreeChangeService dataTreeChangeService; diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BGPClusterSingletonService.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BGPClusterSingletonService.java index 50610d68fa..fc65b65ac0 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BGPClusterSingletonService.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BGPClusterSingletonService.java @@ -10,18 +10,16 @@ package org.opendaylight.protocol.bgp.rib.impl.config; import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.APPLICATION_PEER_GROUP_NAME; import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.APPLICATION_PEER_GROUP_NAME_OPT; import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getNeighborInstanceIdentifier; -import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getNeighborInstanceName; import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getRibInstanceName; +import com.google.common.annotations.VisibleForTesting; 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 com.google.common.util.concurrent.SettableFuture; import java.util.ArrayList; -import java.util.Dictionary; import java.util.HashMap; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Optional; @@ -32,14 +30,18 @@ import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.lock.qual.GuardedBy; import org.checkerframework.checker.lock.qual.Holding; import org.eclipse.jdt.annotation.NonNull; -import org.gaul.modernizer_maven_annotations.SuppressModernizer; import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.common.api.CommitInfo; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory; import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer; -import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; import org.opendaylight.protocol.bgp.rib.spi.util.ClusterSingletonServiceRegistrationHelper; import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config; import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor; @@ -49,13 +51,11 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.t import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instance.protocol.NeighborPeerGroupConfig; 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 BGPClusterSingletonService implements ClusterSingletonService, AutoCloseable { +@VisibleForTesting +public class BGPClusterSingletonService implements ClusterSingletonService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(BGPClusterSingletonService.class); @@ -66,11 +66,15 @@ public final class BGPClusterSingletonService implements ClusterSingletonService @GuardedBy("this") private final Map> peersGroups = new HashMap<>(); private final BGPTableTypeRegistryConsumer tableTypeRegistry; - private final BlueprintContainer container; - private final BundleContext bundleContext; private final ServiceGroupIdentifier serviceGroupIdentifier; private final AtomicBoolean instantiated = new AtomicBoolean(false); private final PeerGroupConfigLoader peerGroupLoader; + private final RpcProviderService rpcRegistry; + private final RIBExtensionConsumerContext ribExtensionContext; + private final BGPDispatcher bgpDispatcher; + private final BGPRibRoutingPolicyFactory routingPolicyFactory; + private final CodecsRegistry codecsRegistry; + private final DOMDataBroker domDataBroker; @GuardedBy("this") private RibImpl ribImpl; @@ -79,19 +83,27 @@ public final class BGPClusterSingletonService implements ClusterSingletonService final @NonNull PeerGroupConfigLoader peerGroupLoader, final @NonNull ClusterSingletonServiceProvider provider, final @NonNull BGPTableTypeRegistryConsumer tableTypeRegistry, - final @NonNull BlueprintContainer container, - final @NonNull BundleContext bundleContext, + final @NonNull RpcProviderService rpcRegistry, + final @NonNull RIBExtensionConsumerContext ribExtensionContext, + final @NonNull BGPDispatcher bgpDispatcher, + final @NonNull BGPRibRoutingPolicyFactory routingPolicyFactory, + final @NonNull CodecsRegistry codecsRegistry, + final @NonNull DOMDataBroker domDataBroker, final @NonNull InstanceIdentifier bgpIid) { this.peerGroupLoader = peerGroupLoader; this.tableTypeRegistry = tableTypeRegistry; - this.container = container; - this.bundleContext = bundleContext; + this.rpcRegistry = rpcRegistry; + this.ribExtensionContext = ribExtensionContext; + this.bgpDispatcher = bgpDispatcher; + this.routingPolicyFactory = routingPolicyFactory; + this.codecsRegistry = codecsRegistry; + this.domDataBroker = domDataBroker; this.bgpIid = bgpIid; final String ribInstanceName = getRibInstanceName(bgpIid); this.serviceGroupIdentifier = ServiceGroupIdentifier.create(ribInstanceName + "-service-group"); - LOG.info("BGPClusterSingletonService {} registered", this.serviceGroupIdentifier.getName()); ClusterSingletonServiceRegistrationHelper .registerSingletonService(provider, this); + LOG.info("BGPClusterSingletonService {} registered", this.serviceGroupIdentifier.getName()); } @Override @@ -168,7 +180,8 @@ public final class BGPClusterSingletonService implements ClusterSingletonService private synchronized void onGlobalCreated(final Global global) { LOG.debug("Creating RIB instance with configuration: {}", global); - this.ribImpl = (RibImpl) this.container.getComponentInstance(InstanceType.RIB.getBeanName()); + this.ribImpl = new RibImpl(this.ribExtensionContext, this.bgpDispatcher, this.routingPolicyFactory, + this.codecsRegistry, this.domDataBroker); initiateRibInstance(global); LOG.debug("RIB instance created: {}", this.ribImpl); } @@ -188,8 +201,9 @@ public final class BGPClusterSingletonService implements ClusterSingletonService } @Holding("this") + @VisibleForTesting @SuppressWarnings("checkstyle:illegalCatch") - private void closeRibService() { + void closeRibService() { try { this.ribImpl.closeServiceInstance().get(TIMEOUT_NS, TimeUnit.NANOSECONDS); } catch (final Exception e) { @@ -199,10 +213,10 @@ public final class BGPClusterSingletonService implements ClusterSingletonService } @Holding("this") - private void initiateRibInstance(final Global global) { + @VisibleForTesting + void initiateRibInstance(final Global global) { final String ribInstanceName = getRibInstanceName(this.bgpIid); ribImpl.start(global, ribInstanceName, this.tableTypeRegistry); - registerRibInstance(ribImpl, ribInstanceName); if (this.instantiated.get()) { this.ribImpl.instantiateServiceInstance(); } @@ -223,12 +237,6 @@ public final class BGPClusterSingletonService implements ClusterSingletonService return filtered; } - private synchronized void registerRibInstance(final RibImpl rib, final String ribInstanceName) { - final ServiceRegistration serviceRegistration = this.bundleContext.registerService( - InstanceType.RIB.getServices(), rib, dictionaryOf(InstanceType.RIB.getBeanName(), ribInstanceName)); - rib.setServiceRegistration(serviceRegistration); - } - @Override public synchronized void close() { LOG.info("BGPClusterSingletonService {} close", this.serviceGroupIdentifier.getName()); @@ -265,17 +273,18 @@ public final class BGPClusterSingletonService implements ClusterSingletonService } } - private synchronized void onNeighborCreated(final Neighbor neighbor) { + @VisibleForTesting + synchronized void onNeighborCreated(final Neighbor neighbor) { LOG.debug("Creating Peer instance with configuration: {}", neighbor); final PeerBean bgpPeer; if (OpenConfigMappingUtil.isApplicationPeer(neighbor)) { - bgpPeer = (PeerBean) this.container.getComponentInstance(InstanceType.APP_PEER.getBeanName()); + bgpPeer = new AppPeer(); } else { - bgpPeer = (PeerBean) this.container.getComponentInstance(InstanceType.PEER.getBeanName()); + bgpPeer = new BgpPeer(this.rpcRegistry); } final InstanceIdentifier neighborInstanceIdentifier = getNeighborInstanceIdentifier(this.bgpIid, neighbor.key()); - initiatePeerInstance(neighborInstanceIdentifier, neighbor, bgpPeer); + initiatePeerInstance(neighbor, bgpPeer); this.peers.put(neighborInstanceIdentifier, bgpPeer); final Optional peerGroupName = getPeerGroupName(neighbor.getConfig()); @@ -298,14 +307,12 @@ public final class BGPClusterSingletonService implements ClusterSingletonService return Optional.of(StringUtils.substringBetween(peerGroupName, "=\"", "\"")); } - private synchronized void onNeighborUpdated(final PeerBean bgpPeer, final Neighbor neighbor) { - LOG.debug("Updating Peer instance with configuration: {}", neighbor); + @VisibleForTesting + synchronized void onNeighborUpdated(final PeerBean bgpPeer, final Neighbor neighbor) { + LOG.info("Updating Peer instance with configuration: {}", neighbor); closePeer(bgpPeer); - - final InstanceIdentifier neighborInstanceIdentifier - = getNeighborInstanceIdentifier(this.bgpIid, neighbor.key()); - initiatePeerInstance(neighborInstanceIdentifier, neighbor, bgpPeer); - LOG.debug("Peer instance updated {}", bgpPeer); + initiatePeerInstance(neighbor, bgpPeer); + LOG.info("Peer instance updated {}", bgpPeer); } @SuppressWarnings("checkstyle:illegalCatch") @@ -314,14 +321,15 @@ public final class BGPClusterSingletonService implements ClusterSingletonService try { bgpPeer.closeServiceInstance().get(); bgpPeer.close(); - LOG.debug("Peer instance closed {}", bgpPeer); + LOG.info("Peer instance closed {}", bgpPeer); } catch (final Exception e) { LOG.error("Peer instance failed to close service instance", e); } } } - private synchronized void onNeighborRemoved(final Neighbor neighbor) { + @VisibleForTesting + public synchronized void onNeighborRemoved(final Neighbor neighbor) { LOG.debug("Removing Peer instance: {}", neighbor); final PeerBean bgpPeer = this.peers.remove(getNeighborInstanceIdentifier(this.bgpIid, neighbor.key())); @@ -333,36 +341,10 @@ public final class BGPClusterSingletonService implements ClusterSingletonService closePeer(bgpPeer); } - private synchronized void registerPeerInstance(final BgpPeer bgpPeer, final String peerInstanceName) { - final ServiceRegistration serviceRegistration = this.bundleContext.registerService( - InstanceType.PEER.getServices(), bgpPeer, dictionaryOf(InstanceType.PEER.getBeanName(), peerInstanceName)); - bgpPeer.setServiceRegistration(serviceRegistration); - } - - @SuppressModernizer - private static Dictionary dictionaryOf(final String key, final String value) { - final Dictionary properties = new Hashtable<>(); - properties.put(key, value); - return properties; - } - - private synchronized void registerAppPeerInstance(final AppPeer appPeer, final String peerInstanceName) { - final ServiceRegistration serviceRegistration = this.bundleContext.registerService( - InstanceType.APP_PEER.getServices(), appPeer, - dictionaryOf(InstanceType.PEER.getBeanName(), peerInstanceName)); - appPeer.setServiceRegistration(serviceRegistration); - } - - private synchronized void initiatePeerInstance(final InstanceIdentifier neighborIdentifier, - final Neighbor neighbor, final PeerBean bgpPeer) { - final String peerInstanceName = getNeighborInstanceName(neighborIdentifier); + @VisibleForTesting + synchronized void initiatePeerInstance(final Neighbor neighbor, final PeerBean bgpPeer) { if (this.ribImpl != null) { bgpPeer.start(this.ribImpl, neighbor, this.bgpIid, this.peerGroupLoader, this.tableTypeRegistry); - if (bgpPeer instanceof BgpPeer) { - registerPeerInstance((BgpPeer) bgpPeer, peerInstanceName); - } else if (bgpPeer instanceof AppPeer) { - registerAppPeerInstance((AppPeer) bgpPeer, peerInstanceName); - } } if (this.instantiated.get()) { bgpPeer.instantiateServiceInstance(); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java index 0e36fe81fc..2b8051975d 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java @@ -66,7 +66,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib. 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.ClusterIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,8 +75,6 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer { private final RpcProviderService rpcRegistry; @GuardedBy("this") - private ServiceRegistration serviceRegistration; - @GuardedBy("this") private Neighbor currentConfiguration; @GuardedBy("this") private BgpPeerSingletonService bgpPeerSingletonService; @@ -169,10 +166,6 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer { this.bgpPeerSingletonService.closeServiceInstance(); this.bgpPeerSingletonService = null; } - if (this.serviceRegistration != null) { - this.serviceRegistration.unregister(); - this.serviceRegistration = null; - } } @Override @@ -225,10 +218,6 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer { return this.bgpPeerSingletonService.getPeerState(); } - synchronized void setServiceRegistration(final ServiceRegistration serviceRegistration) { - this.serviceRegistration = serviceRegistration; - } - synchronized void removePeer(final BGPPeerRegistry bgpPeerRegistry) { if (this.currentConfiguration != null) { bgpPeerRegistry.removePeer(OpenConfigMappingUtil.convertIpAddress( diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/DefaultBgpDeployer.java similarity index 73% rename from bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java rename to bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/DefaultBgpDeployer.java index 9364396512..bef7e5e608 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/DefaultBgpDeployer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2021 PANTHEON.tech s.r.o. 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, @@ -24,6 +24,10 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; import org.checkerframework.checker.lock.qual.GuardedBy; import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataBroker; @@ -31,11 +35,17 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.ReadTransaction; +import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.binding.api.WriteTransaction; import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory; import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; 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; @@ -53,22 +63,27 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.open 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.service.blueprint.container.BlueprintContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener, PeerGroupConfigLoader, - AutoCloseable { - private static final Logger LOG = LoggerFactory.getLogger(BgpDeployerImpl.class); +@Singleton +// Non-final because of Mockito.spy() +public class DefaultBgpDeployer implements ClusteredDataTreeChangeListener, PeerGroupConfigLoader, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(DefaultBgpDeployer.class); + private final InstanceIdentifier networkInstanceIId; - private final BlueprintContainer container; - private final BundleContext bundleContext; private final BGPTableTypeRegistryConsumer tableTypeRegistry; private final ClusterSingletonServiceProvider provider; + private final RpcProviderService rpcRegistry; + private final RIBExtensionConsumerContext ribExtensionConsumerContext; + private final BGPDispatcher bgpDispatcher; + private final BGPRibRoutingPolicyFactory routingPolicyFactory; + private final CodecsRegistry codecsRegistry; + private final DOMDataBroker domDataBroker; + private final DataBroker dataBroker; + @GuardedBy("this") private final Map, BGPClusterSingletonService> bgpCss = new HashMap<>(); - private final DataBroker dataBroker; private final LoadingCache, Optional> peerGroups = CacheBuilder.newBuilder().build(new CacheLoader, Optional>() { @Override @@ -78,25 +93,34 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener registration; + private ListenerRegistration registration; @GuardedBy("this") private boolean closed; - public BgpDeployerImpl(final String networkInstanceName, - final ClusterSingletonServiceProvider provider, - final BlueprintContainer container, - final BundleContext bundleContext, - final DataBroker dataBroker, - final BGPTableTypeRegistryConsumer mappingService) { + @Inject + public DefaultBgpDeployer(final String networkInstanceName, + final ClusterSingletonServiceProvider provider, + final RpcProviderService rpcRegistry, + final RIBExtensionConsumerContext ribExtensionContext, + final BGPDispatcher bgpDispatcher, + final BGPRibRoutingPolicyFactory routingPolicyFactory, + final CodecsRegistry codecsRegistry, + final DOMDataBroker domDataBroker, + 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)); - initializeNetworkInstance(dataBroker, this.networkInstanceIId).addCallback(new FutureCallback() { + tableTypeRegistry = requireNonNull(mappingService); + this.rpcRegistry = rpcRegistry; + ribExtensionConsumerContext = ribExtensionContext; + this.bgpDispatcher = bgpDispatcher; + this.routingPolicyFactory = routingPolicyFactory; + this.codecsRegistry = codecsRegistry; + this.domDataBroker = domDataBroker; + networkInstanceIId = InstanceIdentifier.create(NetworkInstances.class) + .child(NetworkInstance.class, new NetworkInstanceKey(this.networkInstanceName)); + initializeNetworkInstance(dataBroker, networkInstanceIId).addCallback(new FutureCallback() { @Override public void onSuccess(final CommitInfo result) { LOG.debug("Network Instance {} initialized successfully.", networkInstanceName); @@ -109,12 +133,14 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener loadPeerGroup(final InstanceIdentifier peerGroupIid) throws ExecutionException, InterruptedException { final FluentFuture> future; - try (ReadTransaction tx = this.dataBroker.newReadOnlyTransaction()) { + try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) { future = tx.read(LogicalDatastoreType.CONFIGURATION, peerGroupIid); } return future.get(); @@ -130,7 +156,7 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener> changes) { - if (this.closed) { + if (closed) { LOG.trace("BGP Deployer was already closed, skipping changes."); return; } @@ -152,7 +178,7 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener> changedConfig, - final InstanceIdentifier rootIdentifier) { + final InstanceIdentifier rootIdentifier) { final List> globalMod = changedConfig.stream() .filter(mod -> mod.getDataType().equals(Global.class)) .collect(Collectors.toList()); @@ -168,7 +194,7 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener> deletedConfig, - final InstanceIdentifier rootIdentifier) { + final InstanceIdentifier rootIdentifier) { final List> globalMod = deletedConfig.stream() .filter(mod -> mod.getDataType().equals(Global.class)) .collect(Collectors.toList()); @@ -212,21 +238,22 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener css.restartNeighbors(peerGroup.getPeerGroupName())); + bgpCss.values().forEach(css -> css.restartNeighbors(peerGroup.getPeerGroupName())); } } @Override + @PreDestroy @SuppressWarnings("checkstyle:illegalCatch") public synchronized void close() { LOG.info("Closing BGP Deployer."); - if (this.registration != null) { - this.registration.close(); - this.registration = null; + if (registration != null) { + registration.close(); + registration = null; } - this.closed = true; + closed = true; - this.bgpCss.values().iterator().forEachRemaining(service -> { + bgpCss.values().iterator().forEachRemaining(service -> { try { service.close(); } catch (Exception e) { @@ -244,39 +271,34 @@ public final class BgpDeployerImpl implements ClusteredDataTreeChangeListener dataObjectModification, - final InstanceIdentifier 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); + final InstanceIdentifier bgpInstanceIdentifier) { + getBgpClusterSingleton(bgpInstanceIdentifier).onGlobalChanged(dataObjectModification); } - @VisibleForTesting synchronized void onNeighborsChanged(final DataObjectModification dataObjectModification, - final InstanceIdentifier 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); + final InstanceIdentifier bgpInstanceIdentifier) { + getBgpClusterSingleton(bgpInstanceIdentifier).onNeighborsChanged(dataObjectModification); } @VisibleForTesting - BGPTableTypeRegistryConsumer getTableTypeRegistry() { - return this.tableTypeRegistry; + synchronized BGPClusterSingletonService getBgpClusterSingleton( + final InstanceIdentifier bgpInstanceIdentifier) { + BGPClusterSingletonService old = bgpCss.get(bgpInstanceIdentifier); + if (old == null) { + old = new BGPClusterSingletonService(this, provider, tableTypeRegistry, + rpcRegistry, ribExtensionConsumerContext, bgpDispatcher, routingPolicyFactory, + codecsRegistry, domDataBroker, bgpInstanceIdentifier); + bgpCss.put(bgpInstanceIdentifier, old); + } + return old; } @Override public PeerGroup getPeerGroup(final InstanceIdentifier bgpIid, final String peerGroupName) { final InstanceIdentifier peerGroupsIid = bgpIid.child(PeerGroups.class) .child(PeerGroup.class, new PeerGroupKey(peerGroupName)); - return this.peerGroups.getUnchecked(peerGroupsIid).orElse(null); + return peerGroups.getUnchecked(peerGroupsIid).orElse(null); } + } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OSGiBgpDeployer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OSGiBgpDeployer.java new file mode 100644 index 0000000000..20b79718ec --- /dev/null +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OSGiBgpDeployer.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 PANTHEON.tech s.r.o. 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.config; + +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory; +import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; +import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry; +import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +@Component(service = { }) +@Designate(ocd = OSGiBgpDeployer.Configuration.class) +public final class OSGiBgpDeployer extends DefaultBgpDeployer { + @ObjectClassDefinition(description = "Configuration of the OSGiBgpDeployer") + public @interface Configuration { + @AttributeDefinition(description = "Instance name of deployed BGP") + String networkInstanceName() default "global-bgp"; + } + + @Activate + public OSGiBgpDeployer(@Reference final ClusterSingletonServiceProvider provider, + @Reference final RpcProviderService rpcRegistry, + @Reference final RIBExtensionConsumerContext ribExtensionContext, + @Reference final BGPDispatcher bgpDispatcher, + @Reference final BGPRibRoutingPolicyFactory routingPolicyFactory, + @Reference final CodecsRegistry codecsRegistry, + @Reference final DOMDataBroker domDataBroker, + @Reference final DataBroker dataBroker, + @Reference final BGPTableTypeRegistryConsumer mappingService, + final Configuration configuration) { + super(configuration.networkInstanceName(), provider, rpcRegistry, ribExtensionContext, bgpDispatcher, + routingPolicyFactory, codecsRegistry, domDataBroker, dataBroker, mappingService); + init(); + } + + @Override + @Deactivate + public void close() { + super.close(); + } +} diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java index 279db3ab44..18d9e1552d 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java @@ -52,7 +52,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +65,6 @@ public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable { private final DOMDataBroker domBroker; private final BGPRibRoutingPolicyFactory policyProvider; private RIBImpl ribImpl; - private ServiceRegistration serviceRegistration; private Collection afiSafi; private AsNumber asNumber; private Ipv4AddressNoZone routerId; @@ -173,19 +171,8 @@ public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable { this.ribImpl.close(); this.ribImpl = null; } - if (this.serviceRegistration != null) { - try { - this.serviceRegistration.unregister(); - } catch (final IllegalStateException e) { - LOG.warn("Failed to unregister {} service instance", this, e); - } - this.serviceRegistration = null; - } } - void setServiceRegistration(final ServiceRegistration serviceRegistration) { - this.serviceRegistration = serviceRegistration; - } @Override public Set getLocalTablesKeys() { diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java deleted file mode 100644 index 97c391240a..0000000000 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/InstanceType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. 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.spi; - -import com.google.common.collect.ImmutableList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import org.opendaylight.protocol.bgp.rib.RibReference; -import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerStateConsumer; -import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibStateConsumer; - -public enum InstanceType { - - RIB("ribImpl", ImmutableList.of(RIB.class, RibReference.class, BGPRibStateConsumer.class)), - - PEER("bgpPeer", ImmutableList.of(BGPPeerStateConsumer.class)), - - APP_PEER("appPeer", Collections.singletonList(BGPPeerStateConsumer.class)); - - private final String beanName; - private final List services; - - InstanceType(final String beanName, final List> services) { - this.beanName = beanName; - this.services = ImmutableList.copyOf(services.stream().map(Class::getName).collect(Collectors.toList())); - } - - public String getBeanName() { - return this.beanName; - } - - public String[] getServices() { - return this.services.toArray(new String[0]); - } -} diff --git a/bgp/rib-impl/src/main/resources/OSGI-INF/blueprint/bgp-rib.xml b/bgp/rib-impl/src/main/resources/OSGI-INF/blueprint/bgp-rib.xml deleted file mode 100644 index 73216c8f2d..0000000000 --- a/bgp/rib-impl/src/main/resources/OSGI-INF/blueprint/bgp-rib.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AbstractConfig.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AbstractConfig.java index d97d17d776..a376754e9b 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AbstractConfig.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AbstractConfig.java @@ -53,7 +53,6 @@ import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.osgi.framework.ServiceRegistration; class AbstractConfig extends DefaultRibPoliciesMockTest { protected static final AsNumber AS = new AsNumber(Uint32.valueOf(72)); @@ -69,8 +68,6 @@ class AbstractConfig extends DefaultRibPoliciesMockTest { @Mock protected BGPDispatcher dispatcher; @Mock - protected ServiceRegistration serviceRegistration; - @Mock protected BGPPeerRegistry bgpPeerRegistry; @Mock protected ListenerRegistration listener; diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImplTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerTest.java similarity index 65% rename from bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImplTest.java rename to bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerTest.java index 7ae7cb8012..e6086e9fb4 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerImplTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpDeployerTest.java @@ -8,12 +8,14 @@ package org.opendaylight.protocol.bgp.rib.impl.config; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.opendaylight.protocol.bgp.rib.impl.config.AbstractConfig.TABLES_KEY; import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createGlobalIpv4; @@ -22,23 +24,26 @@ import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createN import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createNeighborsNoRR; import static org.opendaylight.protocol.util.CheckUtil.checkPresentConfiguration; -import java.util.Dictionary; +import io.netty.util.concurrent.Future; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.binding.api.WriteTransaction; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.protocol.bgp.openconfig.routing.policy.impl.DefaultBGPRibRoutingPolicyFactory; +import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry.StatementRegistry; import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer; import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl; import org.opendaylight.protocol.bgp.rib.impl.DefaultRibPoliciesMockTest; +import org.opendaylight.protocol.bgp.rib.impl.protocol.BGPReconnectPromise; import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry; -import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType; import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; 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; @@ -56,11 +61,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; -import org.osgi.service.blueprint.container.BlueprintContainer; -public class BgpDeployerImplTest extends DefaultRibPoliciesMockTest { +public class BgpDeployerTest extends DefaultRibPoliciesMockTest { + private static final BgpTableType TABLE_TYPE = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); private static final String NETWORK_INSTANCE_NAME = "network-test"; @@ -76,18 +79,22 @@ public class BgpDeployerImplTest extends DefaultRibPoliciesMockTest { private static final int VERIFY_TIMEOUT_MILIS = 5000; @Mock - private BlueprintContainer blueprintContainer; + private BGPTableTypeRegistryConsumer tableTypeRegistry; @Mock - private BundleContext bundleContext; + private BGPDispatcher dispatcher; @Mock - private BGPTableTypeRegistryConsumer tableTypeRegistry; + private CodecsRegistry codecsRegistry; @Mock - private DataTreeModification modification; + private RpcProviderService rpcRegistry; @Mock - private ServiceRegistration registration; + private RIBExtensionConsumerContext extensionContext; + @Mock private ClusterSingletonServiceProvider singletonServiceProvider; - private BgpDeployerImpl deployer; + + private DefaultBgpDeployer deployer; + private BGPClusterSingletonService spiedBgpSingletonService; + private CountDownLatch bgpSingletonObtainedLatch; @Override @Before @@ -97,95 +104,98 @@ public class BgpDeployerImplTest extends DefaultRibPoliciesMockTest { doReturn("mapping").when(this.tableTypeRegistry).toString(); doReturn(TABLE_TYPE).when(this.tableTypeRegistry).getTableType(any()); doReturn(TABLES_KEY).when(this.tableTypeRegistry).getTableKey(any()); - doNothing().when(this.registration).unregister(); - doReturn(this.registration).when(this.bundleContext).registerService(eq(InstanceType.RIB.getServices()), - any(), any(Dictionary.class)); - doReturn(this.registration).when(this.bundleContext).registerService(eq(InstanceType.PEER.getServices()), - any(), any(Dictionary.class)); - - doReturn("bgpPeer").when(this.modification).toString(); - final RIBExtensionConsumerContext extension = mock(RIBExtensionConsumerContext.class); final ClusterSingletonServiceRegistration serviceRegistration = mock(ClusterSingletonServiceRegistration.class); doReturn(serviceRegistration).when(this.singletonServiceProvider).registerClusterSingletonService(any()); doNothing().when(serviceRegistration).close(); - final RibImpl ribImpl = new RibImpl(extension, mock(BGPDispatcher.class), this.policyProvider, - mock(CodecsRegistry.class), getDomBroker()); - doReturn(ribImpl).when(this.blueprintContainer).getComponentInstance(eq("ribImpl")); - - doReturn(new BgpPeer(mock(RpcProviderService.class))).when(this.blueprintContainer) - .getComponentInstance(eq("bgpPeer")); - - this.deployer = new BgpDeployerImpl(NETWORK_INSTANCE_NAME, this.singletonServiceProvider, - this.blueprintContainer, this.bundleContext, getDataBroker(), this.tableTypeRegistry); + final Future future = mock(BGPReconnectPromise.class); + doReturn(true).when(future).cancel(true); + doReturn(future).when(this.dispatcher).createReconnectingClient(any(), any(), anyInt(), any()); + + this.deployer = spy(new DefaultBgpDeployer(NETWORK_INSTANCE_NAME, this.singletonServiceProvider, + this.rpcRegistry, this.extensionContext, this.dispatcher, + new DefaultBGPRibRoutingPolicyFactory(getDataBroker(), new StatementRegistry()), + this.codecsRegistry, getDomBroker(), getDataBroker(), this.tableTypeRegistry)); + this.bgpSingletonObtainedLatch = new CountDownLatch(1); + doAnswer(invocationOnMock -> { + final BGPClusterSingletonService real = + (BGPClusterSingletonService) invocationOnMock.callRealMethod(); + if (this.spiedBgpSingletonService == null) { + this.spiedBgpSingletonService = spy(real); + } + this.bgpSingletonObtainedLatch.countDown(); + return this.spiedBgpSingletonService; + } + ).when(this.deployer).getBgpClusterSingleton(any()); } @Test public void testDeployerRib() throws Exception { - deployer.init(); + this.deployer.init(); checkPresentConfiguration(getDataBroker(), NETWORK_II); createRib(createGlobalIpv4()); - - verify(this.blueprintContainer, timeout(VERIFY_TIMEOUT_MILIS)).getComponentInstance(eq("ribImpl")); - verify(this.bundleContext, timeout(VERIFY_TIMEOUT_MILIS)).registerService(eq(InstanceType.RIB.getServices()), - any(), any(Dictionary.class)); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)) + .initiateRibInstance(any()); //change with same rib already existing createRib(createGlobalIpv4()); - verify(this.blueprintContainer).getComponentInstance(eq("ribImpl")); - verify(this.bundleContext).registerService(eq(InstanceType.RIB.getServices()), any(), any(Dictionary.class)); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)) + .initiateRibInstance(any()); //Update for existing rib createRib(createGlobalIpv6()); - - verify(this.blueprintContainer).getComponentInstance(eq("ribImpl")); - verify(this.bundleContext, timeout(VERIFY_TIMEOUT_MILIS).times(2)).registerService( - eq(InstanceType.RIB.getServices()), any(), any(Dictionary.class)); - verify(this.registration).unregister(); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)) + .initiateRibInstance(any()); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)) + .closeRibService(); //Delete for existing rib deleteRib(); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)) + .initiateRibInstance(any()); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)) + .closeRibService(); - verify(this.blueprintContainer).getComponentInstance(eq("ribImpl")); - verify(this.bundleContext, timeout(VERIFY_TIMEOUT_MILIS).times(2)) - .registerService(eq(InstanceType.RIB.getServices()), any(), any(Dictionary.class)); - verify(this.registration, timeout(VERIFY_TIMEOUT_MILIS).times(2)).unregister(); - - deployer.close(); + this.deployer.close(); } @Test public void testDeployerCreateNeighbor() throws Exception { - deployer.init(); + this.deployer.init(); checkPresentConfiguration(getDataBroker(), NETWORK_II); createRib(createGlobalIpv4()); createNeighbor(createNeighbors()); - verify(this.blueprintContainer, timeout(VERIFY_TIMEOUT_MILIS)).getComponentInstance(eq("bgpPeer")); - verify(this.bundleContext, timeout(VERIFY_TIMEOUT_MILIS)).registerService(eq(InstanceType.PEER.getServices()), - any(BgpPeer.class), any(Dictionary.class)); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS)).onNeighborCreated(any()); //change with same peer already existing createNeighbor(createNeighbors()); - verify(this.blueprintContainer).getComponentInstance(eq("bgpPeer")); - verify(this.bundleContext).registerService(eq(InstanceType.PEER.getServices()), - any(BgpPeer.class), any(Dictionary.class)); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS)).onNeighborCreated(any()); + verify(this.spiedBgpSingletonService, never()).onNeighborRemoved(any()); + verify(this.spiedBgpSingletonService, never()).onNeighborUpdated(any(), any()); //Update for peer createNeighbor(createNeighborsNoRR()); - verify(this.blueprintContainer).getComponentInstance(eq("bgpPeer")); - verify(this.bundleContext, timeout(VERIFY_TIMEOUT_MILIS).times(2)) - .registerService(eq(InstanceType.PEER.getServices()), any(BgpPeer.class), any(Dictionary.class)); - verify(this.registration).unregister(); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborUpdated(any(), any()); deleteNeighbors(); //Delete existing Peer - verify(this.bundleContext, times(2)) - .registerService(eq(InstanceType.PEER.getServices()), any(BgpPeer.class), any(Dictionary.class)); - verify(this.registration, timeout(VERIFY_TIMEOUT_MILIS).times(2)).unregister(); + awaitForObtainedSingleton(); + verify(this.spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborRemoved(any()); + this.deployer.close(); + } - deployer.close(); + private void awaitForObtainedSingleton() throws InterruptedException { + this.bgpSingletonObtainedLatch = new CountDownLatch(1); + this.bgpSingletonObtainedLatch.await(VERIFY_TIMEOUT_MILIS, TimeUnit.MILLISECONDS); } private void createRib(final Global global) throws ExecutionException, InterruptedException { @@ -211,4 +221,5 @@ public class BgpDeployerImplTest extends DefaultRibPoliciesMockTest { wr.delete(LogicalDatastoreType.CONFIGURATION, NEIGHBORS_II); wr.commit().get(); } + } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeerTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeerTest.java index 3364fdd77f..9182c78bc4 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeerTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeerTest.java @@ -13,7 +13,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -129,7 +128,6 @@ public class BgpPeerTest extends AbstractConfig { public void setUp() throws Exception { super.setUp(); this.bgpPeer = new BgpPeer(mock(RpcProviderService.class)); - doNothing().when(this.serviceRegistration).unregister(); } @Test @@ -154,12 +152,10 @@ public class BgpPeerTest extends AbstractConfig { } catch (final IllegalStateException expected) { assertEquals("Previous peer instance was not closed.", expected.getMessage()); } - this.bgpPeer.setServiceRegistration(this.serviceRegistration); this.bgpPeer.closeServiceInstance(); verify(this.bgpPeerRegistry).removePeer(any()); verify(this.future).cancel(true); this.bgpPeer.close(); - verify(this.serviceRegistration).unregister(); this.bgpPeer.restart(this.rib, null, this.peerGroupLoader, this.tableTypeRegistry); verify(this.rib, times(2)).createPeerDOMChain(any()); @@ -201,7 +197,6 @@ public class BgpPeerTest extends AbstractConfig { verify(this.bgpPeerRegistry, times(4)).removePeer(any()); verify(this.future, times(4)).cancel(true); this.bgpPeer.close(); - verify(this.serviceRegistration).unregister(); final Neighbor neighborDiffConfig = new NeighborBuilder().setNeighborAddress(NEIGHBOR_ADDRESS) .setAfiSafis(createAfiSafi()).build(); diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java index f9ca35ac58..a04bcd408e 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java @@ -10,7 +10,6 @@ package org.opendaylight.protocol.bgp.rib.impl.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -50,7 +49,6 @@ import org.opendaylight.yangtools.yang.common.Uint8; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; -import org.osgi.framework.ServiceRegistration; public class RibImplTest extends AbstractConfig { private static final Map AFISAFIS = BindingMap.of(new AfiSafiBuilder() @@ -69,8 +67,6 @@ public class RibImplTest extends AbstractConfig { private DOMDataBroker domDataBroker; @Mock private RIBSupport ribSupport; - @Mock - private ServiceRegistration serviceRegistration; @Override @Before @@ -92,7 +88,6 @@ public class RibImplTest extends AbstractConfig { .when(this.domDataBroker).getExtensions(); doReturn(mock(ListenerRegistration.class)).when(dOMDataTreeChangeService) .registerDataTreeChangeListener(any(), any()); - doNothing().when(this.serviceRegistration).unregister(); } @Test @@ -103,7 +98,6 @@ public class RibImplTest extends AbstractConfig { this.policyProvider, this.codecsRegistry, this.domDataBroker); - ribImpl.setServiceRegistration(this.serviceRegistration); ribImpl.start(createGlobal(), "rib-test", this.tableTypeRegistry); verify(this.domDataBroker).getExtensions(); assertEquals("RIBImpl{bgpId=Ipv4Address{_value=127.0.0.1}, localTables=[BgpTableTypeImpl [" @@ -124,7 +118,6 @@ public class RibImplTest extends AbstractConfig { assertNotNull(ribImpl.getCodecsRegistry()); ribImpl.close(); - verify(this.serviceRegistration).unregister(); } private static Global createGlobal() { -- 2.36.6