<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-yang-types-20130715</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- test scope dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>yang-ext</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- test scope dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>ietf-inet-types-2013-07-15</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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();
if (this.bgpAppPeerSingletonService != null) {
this.bgpAppPeerSingletonService = null;
}
+ if (this.serviceRegistration != null) {
+ this.serviceRegistration.unregister();
+ this.serviceRegistration = null;
+ }
}
@Override
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;
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.util.concurrent.FutureCallback;
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;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.GuardedBy;
import org.apache.commons.lang3.StringUtils;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
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.BGPDispatcher;
-import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
+import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.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;
@GuardedBy("this")
private final Map<String, List<PeerBean>> 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 RibImpl ribImpl;
- private final RIBExtensionConsumerContext ribExtensionContext;
- private final BGPDispatcher dispatcher;
- private final BGPRibRoutingPolicyFactory policyFactory;
- private final BindingCodecTreeFactory codecFactory;
- private final DOMDataBroker domBroker;
- private final DataBroker dataBroker;
- private final DOMSchemaService schemaService;
- private final RpcProviderRegistry rpcRegistry;
BGPClusterSingletonService(
@Nonnull final PeerGroupConfigLoader peerGroupLoader,
@Nonnull final ClusterSingletonServiceProvider provider,
@Nonnull final BGPTableTypeRegistryConsumer tableTypeRegistry,
- @Nonnull final InstanceIdentifier<Bgp> bgpIid,
- @Nonnull final RIBExtensionConsumerContext ribExtensionContext,
- @Nonnull final BGPDispatcher dispatcher,
- @Nonnull final BGPRibRoutingPolicyFactory policyFactory,
- @Nonnull final BindingCodecTreeFactory codecFactory,
- @Nonnull final DOMDataBroker domBroker,
- @Nonnull final DataBroker dataBroker,
- @Nonnull final DOMSchemaService schemaService,
- @Nonnull final RpcProviderRegistry rpcRegistry) {
+ @Nonnull final BlueprintContainer container,
+ @Nonnull final BundleContext bundleContext,
+ @Nonnull final InstanceIdentifier<Bgp> bgpIid) {
this.peerGroupLoader = peerGroupLoader;
this.tableTypeRegistry = tableTypeRegistry;
+ this.container = container;
+ this.bundleContext = bundleContext;
this.bgpIid = bgpIid;
- this.ribExtensionContext = ribExtensionContext;
- this.dispatcher = dispatcher;
- this.policyFactory = policyFactory;
- this.codecFactory = codecFactory;
- this.domBroker = domBroker;
- this.dataBroker = dataBroker;
- this.schemaService = schemaService;
- this.rpcRegistry = rpcRegistry;
final String ribInstanceName = getRibInstanceName(bgpIid);
this.serviceGroupIdentifier = ServiceGroupIdentifier.create(ribInstanceName + "-service-group");
LOG.info("BGPClusterSingletonService {} registered", this.serviceGroupIdentifier.getValue());
private synchronized void onGlobalCreated(final Global global) {
LOG.debug("Creating RIB instance with configuration: {}", global);
- this.ribImpl = new RibImpl(ribExtensionContext, dispatcher, policyFactory, codecFactory, domBroker, dataBroker,
- schemaService);
+ this.ribImpl = (RibImpl) this.container.getComponentInstance(InstanceType.RIB.getBeanName());
initiateRibInstance(global, this.ribImpl);
LOG.debug("RIB instance created: {}", this.ribImpl);
}
private synchronized void initiateRibInstance(final Global global, final RibImpl ribImpl) {
final String ribInstanceName = getRibInstanceName(this.bgpIid);
ribImpl.start(global, ribInstanceName, this.tableTypeRegistry);
+ registerRibInstance(ribImpl, ribInstanceName);
if (this.instantiated.get()) {
this.ribImpl.instantiateServiceInstance();
}
return filtered;
}
+ private synchronized 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);
+ }
+
@Override
public void close() {
LOG.info("BGPClusterSingletonService {} close", this.serviceGroupIdentifier.getValue());
LOG.debug("Creating Peer instance with configuration: {}", neighbor);
final PeerBean bgpPeer;
if (OpenConfigMappingUtil.isApplicationPeer(neighbor)) {
- bgpPeer = new AppPeer();
+ bgpPeer = (PeerBean) this.container.getComponentInstance(InstanceType.APP_PEER.getBeanName());
} else {
- bgpPeer = new BgpPeer(this.rpcRegistry);
+ bgpPeer = (PeerBean) this.container.getComponentInstance(InstanceType.PEER.getBeanName());
}
final InstanceIdentifier<Neighbor> neighborInstanceIdentifier =
getNeighborInstanceIdentifier(this.bgpIid, neighbor.key());
closePeer(bgpPeer);
}
+ private synchronized void registerPeerInstance(final BgpPeer bgpPeer, final String peerInstanceName) {
+ final Dictionary<String, String> properties = new Hashtable<>();
+ properties.put(InstanceType.PEER.getBeanName(), peerInstanceName);
+ final ServiceRegistration<?> serviceRegistration = this.bundleContext
+ .registerService(InstanceType.PEER.getServices(), bgpPeer, properties);
+ bgpPeer.setServiceRegistration(serviceRegistration);
+ }
+
+ private synchronized void registerAppPeerInstance(final AppPeer appPeer, final String peerInstanceName) {
+ final Dictionary<String, String> properties = new Hashtable<>();
+ properties.put(InstanceType.PEER.getBeanName(), peerInstanceName);
+ final ServiceRegistration<?> serviceRegistration = this.bundleContext
+ .registerService(InstanceType.APP_PEER.getServices(), appPeer, properties);
+ appPeer.setServiceRegistration(serviceRegistration);
+ }
+
private synchronized void initiatePeerInstance(final InstanceIdentifier<Neighbor> neighborIdentifier,
final Neighbor neighbor, final PeerBean bgpPeer) {
+ final String peerInstanceName = getNeighborInstanceName(neighborIdentifier);
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();
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.dom.api.DOMDataBroker;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
import org.opendaylight.mdsal.common.api.CommitInfo;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
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.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;
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;
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 BGPTableTypeRegistryConsumer tableTypeRegistry;
private final ClusterSingletonServiceProvider provider;
@GuardedBy("this")
private ListenerRegistration<BgpDeployerImpl> registration;
@GuardedBy("this")
private boolean closed;
- private final RIBExtensionConsumerContext ribExtensionContext;
- private final BGPDispatcher dispatcher;
- private final BGPRibRoutingPolicyFactory policyFactory;
- private final BindingCodecTreeFactory codecFactory;
- private final DOMDataBroker domBroker;
- private final DOMSchemaService schemaService;
- private final RpcProviderRegistry rpcRegistry;
- public BgpDeployerImpl(final String networkInstanceName,
- final ClusterSingletonServiceProvider provider,
- final DataBroker dataBroker,
- final BGPTableTypeRegistryConsumer mappingService,
- final RIBExtensionConsumerContext ribExtensionContext,
- final BGPDispatcher dispatcher,
- final BGPRibRoutingPolicyFactory policyFactory,
- final BindingCodecTreeFactory codecFactory,
- final DOMDataBroker domBroker,
- final DOMSchemaService schemaService,
- final RpcProviderRegistry rpcRegistry) {
+ 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.ribExtensionContext = requireNonNull(ribExtensionContext);
- this.dispatcher = requireNonNull(dispatcher);
- this.policyFactory = requireNonNull(policyFactory);
- this.codecFactory = requireNonNull(codecFactory);
- this.domBroker = requireNonNull(domBroker);
- this.schemaService = requireNonNull(schemaService);
- this.rpcRegistry = rpcRegistry;
this.networkInstanceIId = InstanceIdentifier.create(NetworkInstances.class)
.child(NetworkInstance.class, new NetworkInstanceKey(networkInstanceName));
initializeNetworkInstance(dataBroker, this.networkInstanceIId).addCallback(new FutureCallback<CommitInfo>() {
BGPClusterSingletonService old = this.bgpCss.get(bgpInstanceIdentifier);
if (old == null) {
old = new BGPClusterSingletonService(this, this.provider, this.tableTypeRegistry,
- bgpInstanceIdentifier, this.ribExtensionContext, this.dispatcher, this.policyFactory,
- this.codecFactory, this.domBroker, this.dataBroker, this.schemaService, this.rpcRegistry);
+ this.container, this.bundleContext, bgpInstanceIdentifier);
this.bgpCss.put(bgpInstanceIdentifier, old);
}
old.onGlobalChanged(dataObjectModification);
BGPClusterSingletonService old = this.bgpCss.get(bgpInstanceIdentifier);
if (old == null) {
old = new BGPClusterSingletonService(this, this.provider, this.tableTypeRegistry,
- bgpInstanceIdentifier, this.ribExtensionContext, this.dispatcher, this.policyFactory,
- this.codecFactory, this.domBroker, this.dataBroker, this.schemaService, this.rpcRegistry);
+ this.container, this.bundleContext, bgpInstanceIdentifier);
this.bgpCss.put(bgpInstanceIdentifier, old);
}
old.onNeighborsChanged(dataObjectModification);
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.rev180329.ClusterIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final RpcProviderRegistry rpcRegistry;
@GuardedBy("this")
+ private ServiceRegistration<?> serviceRegistration;
+ @GuardedBy("this")
private Neighbor currentConfiguration;
@GuardedBy("this")
private BgpPeerSingletonService bgpPeerSingletonService;
}
@Override
- public synchronized void close() {}
+ public synchronized void close() {
+ if (this.serviceRegistration != null) {
+ this.serviceRegistration.unregister();
+ this.serviceRegistration = null;
+ }
+ }
@Override
public synchronized void instantiateServiceInstance() {
return this.bgpPeerSingletonService.getPeerState();
}
+ synchronized void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
+ this.serviceRegistration = serviceRegistration;
+ }
+
synchronized void removePeer(final BGPPeerRegistry bgpPeerRegistry) {
if (BgpPeer.this.currentConfiguration != null) {
bgpPeerRegistry.removePeer(BgpPeer.this.currentConfiguration.getNeighborAddress());
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final DOMSchemaService domSchemaService;
private final BGPRibRoutingPolicyFactory policyProvider;
private RIBImpl ribImpl;
+ private ServiceRegistration<?> serviceRegistration;
private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
private List<AfiSafi> afiSafi;
private AsNumber asNumber;
this.schemaContextRegistration.close();
this.schemaContextRegistration = 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
destroy-method="close">
<argument value="global-bgp"/>
<argument ref="clusterSingletonServiceProvider"/>
+ <argument ref="blueprintContainer"/>
+ <argument ref="blueprintBundleContext"/>
<argument ref="dataBroker"/>
<argument ref="bgpTableTypeRegistry"/>
+ </bean>
+
+ <reference id="policiesProvider" interface="org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory"/>
+ <bean id="ribImpl" class="org.opendaylight.protocol.bgp.rib.impl.config.RibImpl" scope="prototype">
<argument ref="globalBgpExtensions"/>
<argument ref="BGPDispatcher"/>
<argument ref="policiesProvider"/>
<argument ref="codecTreeFactory"/>
<argument ref="domDataBroker"/>
+ <argument ref="dataBroker"/>
<argument ref="domSchemaService"/>
+ </bean>
+
+ <bean id="bgpPeer" class="org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer" scope="prototype">
<argument ref="rpcRegistry"/>
</bean>
- <reference id="policiesProvider" interface="org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory"/>
+ <bean id="appPeer" class="org.opendaylight.protocol.bgp.rib.impl.config.AppPeer" scope="prototype"/>
<bean id="bgpStateCollector" class="org.opendaylight.protocol.bgp.rib.impl.state.BGPStateCollectorImpl"/>
<service ref="bgpStateCollector" interface="org.opendaylight.protocol.bgp.rib.spi.state.BGPStateConsumer"/>
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(72L);
@Mock
protected BGPDispatcher dispatcher;
@Mock
+ protected ServiceRegistration<?> serviceRegistration;
+ @Mock
protected BGPPeerRegistry bgpPeerRegistry;
@Mock
protected ListenerRegistration<?> listener;
package org.opendaylight.protocol.bgp.rib.impl.config;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
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;
import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createNeighborsNoRR;
import static org.opendaylight.protocol.util.CheckUtil.checkPresentConfiguration;
-import io.netty.util.concurrent.Future;
+import java.util.Dictionary;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Matchers;
import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
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.dom.api.DOMDataBroker;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
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.BGPRibRoutingPolicyFactoryImpl;
-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.spi.BGPDispatcher;
-import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
-import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
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.yangtools.concepts.ListenerRegistration;
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 {
private static final BgpTableType TABLE_TYPE = new BgpTableTypeImpl(Ipv4AddressFamily.class,
private static final InstanceIdentifier<Neighbors> NEIGHBORS_II = BGP_II.child(Neighbors.class);
private static final int VERIFY_TIMEOUT_MILIS = 5000;
+ @Mock
+ private BlueprintContainer blueprintContainer;
+ @Mock
+ private BundleContext bundleContext;
@Mock
private BGPTableTypeRegistryConsumer tableTypeRegistry;
@Mock
@Mock
private ListenerRegistration<?> dataTreeRegistration;
@Mock
- private ClusterSingletonServiceProvider singletonServiceProvider;
- @Mock
- private BGPDispatcher dispatcher;
+ private ServiceRegistration<?> registration;
@Mock
- private BindingCodecTreeFactory codecFactory;
- @Mock
- private DOMSchemaService schemaService;
- @Mock
- private RpcProviderRegistry rpcRegistry;
- @Mock
- private BGPPeerRegistry peerRegistry;
+ private ClusterSingletonServiceProvider singletonServiceProvider;
private BgpDeployerImpl deployer;
-
@Before
public void setUp() throws Exception {
super.setUp();
doReturn("mapping").when(this.tableTypeRegistry).toString();
doReturn(Optional.of(TABLE_TYPE)).when(this.tableTypeRegistry).getTableType(any());
doReturn(Optional.of(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));
doNothing().when(this.dataTreeRegistration).close();
doReturn("bgpPeer").when(this.modification).toString();
doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(extension).getClassLoadingStrategy();
final ClusterSingletonServiceRegistration serviceRegistration = mock(ClusterSingletonServiceRegistration.class);
- doAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
- final ClusterSingletonService service = invocationOnMock.getArgumentAt(0, ClusterSingletonService.class);
- service.instantiateServiceInstance();
- return serviceRegistration;
- }
- }).when(this.singletonServiceProvider).registerClusterSingletonService(any(ClusterSingletonService.class));
+ doReturn(serviceRegistration).when(this.singletonServiceProvider).registerClusterSingletonService(any());
doNothing().when(serviceRegistration).close();
- schemaService = mock(DOMSchemaService.class);
+ final DOMSchemaService schemaService = mock(DOMSchemaService.class);
doNothing().when(this.dataTreeRegistration).close();
doReturn(this.dataTreeRegistration).when(schemaService).registerSchemaContextListener(any());
- final DataBroker dataBroker = getDataBroker();
- final DOMDataBroker domBroker = getDomBroker();
- final SimpleRIBExtensionProviderContext ribExtensionContext = new SimpleRIBExtensionProviderContext();
- final BGPRibRoutingPolicyFactoryImpl policyFactory = new BGPRibRoutingPolicyFactoryImpl(dataBroker, new StatementRegistry());
- doReturn(this.peerRegistry).when(this.dispatcher).getBGPPeerRegistry();
- final Future future = Mockito.mock(Future.class);
- doReturn(true).when(future).cancel(true);
- doReturn(future).when(this.dispatcher).createReconnectingClient(any(), any(), Matchers.anyInt(), any());
- doNothing().when(this.peerRegistry).addPeer(any(), any(), any());
- doNothing().when(this.peerRegistry).removePeer(any());
- this.deployer = new BgpDeployerImpl(NETWORK_INSTANCE_NAME, this.singletonServiceProvider, dataBroker,
- this.tableTypeRegistry, ribExtensionContext, dispatcher, policyFactory, codecFactory, domBroker, schemaService, rpcRegistry);
+ final RibImpl ribImpl = new RibImpl(extension, mock(BGPDispatcher.class), this.policyProvider,
+ mock(BindingCodecTreeFactory.class), getDomBroker(), getDataBroker(), schemaService);
+ doReturn(ribImpl).when(this.blueprintContainer).getComponentInstance(eq("ribImpl"));
+
+ doReturn(new BgpPeer(mock(RpcProviderRegistry.class)))
+ .when(this.blueprintContainer).getComponentInstance(eq("bgpPeer"));
+
+ this.deployer = new BgpDeployerImpl(NETWORK_INSTANCE_NAME, this.singletonServiceProvider,
+ this.blueprintContainer, this.bundleContext, getDataBroker(), this.tableTypeRegistry);
}
@Test
deployer.init();
checkPresentConfiguration(getDataBroker(), NETWORK_II);
createRib(createGlobalIpv4());
- verify(this.schemaService, timeout(VERIFY_TIMEOUT_MILIS)).registerSchemaContextListener(any());
+
+ 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));
//change with same rib already existing
createRib(createGlobalIpv4());
- verify(this.schemaService, timeout(VERIFY_TIMEOUT_MILIS)).registerSchemaContextListener(any());
+ verify(this.blueprintContainer).getComponentInstance(eq("ribImpl"));
+ verify(this.bundleContext).registerService(eq(InstanceType.RIB.getServices()), any(), any(Dictionary.class));
//Update for existing rib
createRib(createGlobalIpv6());
- verify(this.dataTreeRegistration, timeout(VERIFY_TIMEOUT_MILIS)).close();
+
+ 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.dataTreeRegistration).close();
+ verify(this.registration).unregister();
//Delete for existing rib
deleteRib();
+
+ 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.dataTreeRegistration, timeout(VERIFY_TIMEOUT_MILIS).times(2)).close();
+ verify(this.registration, timeout(VERIFY_TIMEOUT_MILIS).times(2)).unregister();
deployer.close();
}
createRib(createGlobalIpv4());
createNeighbor(createNeighbors());
- verify(this.peerRegistry, timeout(VERIFY_TIMEOUT_MILIS).times(1)).addPeer(any(), any(), any());
+ 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));
//change with same peer already existing
createNeighbor(createNeighbors());
- verify(this.peerRegistry, timeout(VERIFY_TIMEOUT_MILIS).times(1)).addPeer(any(), any(), any());
+ verify(this.blueprintContainer).getComponentInstance(eq("bgpPeer"));
+ verify(this.bundleContext).registerService(eq(InstanceType.PEER.getServices()),
+ any(BgpPeer.class), any(Dictionary.class));
+
//Update for peer
createNeighbor(createNeighborsNoRR());
- verify(this.peerRegistry, timeout(VERIFY_TIMEOUT_MILIS).times(2)).addPeer(any(), any(), any());
- verify(this.peerRegistry, timeout(VERIFY_TIMEOUT_MILIS).times(1)).removePeer(any());
+
+ 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();
deleteNeighbors();
- verify(this.peerRegistry, timeout(VERIFY_TIMEOUT_MILIS).times(2)).removePeer(any());
+ //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();
deployer.close();
}
public void setUp() throws Exception {
super.setUp();
this.bgpPeer = new BgpPeer(Mockito.mock(RpcProviderRegistry.class));
+ Mockito.doNothing().when(this.serviceRegistration).unregister();
}
@Test
} catch (final IllegalStateException expected) {
assertEquals("Previous peer instance was not closed.", expected.getMessage());
}
+ this.bgpPeer.setServiceRegistration(this.serviceRegistration);
this.bgpPeer.closeServiceInstance();
this.bgpPeer.close();
verify(this.future).cancel(true);
this.bgpPeer.closeServiceInstance();
this.bgpPeer.close();
+ verify(this.serviceRegistration).unregister();
verify(this.future, times(2)).cancel(true);
final Neighbor neighborDiffConfig = new NeighborBuilder().setNeighborAddress(NEIGHBOR_ADDRESS)
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 List<AfiSafi> AFISAFIS = new ArrayList<>();
private ListenerRegistration<?> dataTreeRegistration;
@Mock
private RIBSupport<?, ?, ?, ?> ribSupport;
+ @Mock
+ private ServiceRegistration<?> serviceRegistration;
@Override
@Before
doNothing().when(this.dataTreeRegistration).close();
doReturn(mock(ListenerRegistration.class)).when(dOMDataTreeChangeService)
.registerDataTreeChangeListener(any(), any());
+ doNothing().when(this.serviceRegistration).unregister();
}
@Test
this.domDataBroker,
getDataBroker(),
this.domSchemaService);
+ ribImpl.setServiceRegistration(this.serviceRegistration);
ribImpl.start(createGlobal(), "rib-test", this.tableTypeRegistry);
verify(this.extension).getClassLoadingStrategy();
verify(this.domDataBroker).getSupportedExtensions();
ribImpl.close();
verify(this.dataTreeRegistration).close();
verify(this.dataTreeRegistration).close();
+ verify(this.serviceRegistration).unregister();
}
private static Global createGlobal() {
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-singleton-common-api</artifactId>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- Test dependencies -->
<dependency>
import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyProvider;
import org.opendaylight.bgpcep.bgp.topology.provider.spi.TopologyReferenceSingletonService;
+import org.opendaylight.bgpcep.topology.TopologyReference;
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.yangtools.concepts.AbstractRegistration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@GuardedBy("this")
private final Set<Topology> topologies = new HashSet<>();
private final DataBroker dataBroker;
+ private final BundleContext context;
private final ClusterSingletonServiceProvider singletonProvider;
private ListenerRegistration<BgpTopologyDeployerImpl> registration;
@GuardedBy("this")
private boolean closed;
- public BgpTopologyDeployerImpl(final DataBroker dataBroker,
+ public BgpTopologyDeployerImpl(final BundleContext context, final DataBroker dataBroker,
final ClusterSingletonServiceProvider singletonProvider) {
+ this.context = requireNonNull(context);
this.dataBroker = requireNonNull(dataBroker);
this.singletonProvider = requireNonNull(singletonProvider);
}
final Dictionary<String, String> properties = new Hashtable<>();
properties.put("topology-id", topologyProviderService.getInstanceIdentifier()
.firstKeyOf(Topology.class).getTopologyId().getValue());
+ final ServiceRegistration<?> registerService = this.context
+ .registerService(new String[]{TopologyReference.class.getName()},
+ topologyProviderService, properties);
final ClusterSingletonServiceRegistration registerClusterSingletonService =
registerSingletonService(topologyProviderService);
return new AbstractRegistration() {
} catch (final Exception e) {
LOG.warn("Failed to close ClusterSingletonServiceRegistration {} for TopologyBuilder {}",
registerClusterSingletonService, topologyProviderService.getInstanceIdentifier(), e);
+ } finally {
+ registerService.unregister();
}
}
};
<bean id="bgpTopologyDeployer" class="org.opendaylight.bgpcep.bgp.topology.provider.config.BgpTopologyDeployerImpl"
init-method="init"
destroy-method="close">
+ <argument ref="blueprintBundleContext"/>
<argument ref="dataBroker"/>
<argument ref="clusterSingletonServiceProvider"/>
</bean>