import java.util.stream.Collectors;
import org.opendaylight.controller.config.api.JmxAttributeValidationException;
import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPBestPathSelection;
import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
import org.opendaylight.protocol.bgp.rib.impl.spi.InstanceType;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+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.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.osgi.framework.BundleContext;
WaitingServiceTracker.create(BgpDeployer.class, this.bundleContext);
final BgpDeployer bgpDeployer = bgpDeployerTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
//map configuration to OpenConfig BGP
- final Protocol protocol = bgpDeployer.getMappingService().fromRib(getBgpRibId(), getClusterId(), getRibId(), new AsNumber(getLocalAs()), getLocalTableDependency(),
+ final Protocol protocol = bgpDeployer.getMappingService().fromRib(getBgpRibId(), getClusterId(), getRibId(),
+ new AsNumber(getLocalAs()), getLocalTableDependency(),
mapBestPathSelectionStrategyByFamily(getRibPathSelectionModeDependency()));
- //write to configuration DS
- final KeyedInstanceIdentifier<Protocol, ProtocolKey> protocolIId = bgpDeployer.getInstanceIdentifier().child(Protocols.class).child(Protocol.class,
- protocol.getKey());
- bgpDeployer.writeConfiguration(protocol, protocolIId);
+ final Global global = protocol.getAugmentation(Protocol1.class).getBgp().getGlobal();
+ final KeyedInstanceIdentifier<Protocol, ProtocolKey> protocolIId = bgpDeployer.getInstanceIdentifier().child(Protocols.class)
+ .child(Protocol.class, protocol.getKey());
+ final InstanceIdentifier<Bgp> bgpIID = protocolIId.augmentation(Protocol1.class).child(Bgp.class);
+ bgpDeployer.onGlobalCreated(bgpIID, global, () -> bgpDeployer.writeConfiguration(protocol, protocolIId));
+
//get rib instance service, use filter
final WaitingServiceTracker<RIB> ribTracker = WaitingServiceTracker.create(RIB.class,
- this.bundleContext, "(" + InstanceType.RIB.getBeanName() + "=" + getRibId().getValue() + ")");
+ this.bundleContext, "(" + InstanceType.RIB.getBeanName() + "=" + getRibId().getValue() + ")");
final RIB rib = ribTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
final RIBImplRuntimeRegistration register = getRootRuntimeBeanRegistratorWrapper().register(rib.getRenderStats());
+
return Reflection.newProxy(AutoCloseableRIB.class, new AbstractInvocationHandler() {
@Override
protected Object handleInvocation(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (method.getName().equals("close")) {
+ bgpDeployer.onGlobalRemoved(bgpIID);
register.close();
bgpDeployerTracker.close();
ribTracker.close();
private Map<TablesKey, PathSelectionMode> mapBestPathSelectionStrategyByFamily(final List<BGPBestPathSelection> bestPathSelectionDependency) {
return Collections.unmodifiableMap(bestPathSelectionDependency.stream().collect(
- Collectors.<BGPBestPathSelection, TablesKey, PathSelectionMode>toMap(st -> new TablesKey(st.getAfi(), st.getSafi()), st -> st.getStrategy())));
+ Collectors.toMap(st -> new TablesKey(st.getAfi(), st.getSafi()), st -> st.getStrategy())));
}
private static interface AutoCloseableRIB extends RIB, AutoCloseable {
*/
package org.opendaylight.protocol.bgp.rib.impl;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
+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.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPConfigModuleTracker;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
import org.opendaylight.protocol.bgp.rib.DefaultRibReference;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.slf4j.LoggerFactory;
@ThreadSafe
-public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener, SchemaContextListener {
+public final class RIBImpl extends DefaultRibReference implements ClusterSingletonService, AutoCloseable, RIB, TransactionChainListener, SchemaContextListener {
private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
- @VisibleForTesting
- public static final QName RIB_ID_QNAME = QName.create(Rib.QNAME, "id").intern();
- @VisibleForTesting
- public static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes.QNAME);
+ private static final QName RIB_ID_QNAME = QName.create(Rib.QNAME, "id").intern();
+ private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes.QNAME);
private final BGPDispatcher dispatcher;
private final DOMTransactionChain domChain;
private final YangInstanceIdentifier yangRibId;
private final RIBSupportContextRegistryImpl ribContextRegistry;
private final CodecsRegistryImpl codecsRegistry;
+ private final ServiceGroupIdentifier serviceGroupIdentifier;
+ private final ClusterSingletonServiceProvider provider;
+ private final PolicyDatabase policyDatabase;
+ private final BgpDeployer.WriteConfiguration configurationWriter;
+ private ClusterSingletonServiceRegistration registration;
private final DOMDataBrokerExtension service;
private final List<LocRibWriter> locRibs = new ArrayList<>();
private final BGPConfigModuleTracker configModuleTracker;
private final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies;
private final ImportPolicyPeerTracker importPolicyPeerTracker;
private final RIBImplRuntimeMXBeanImpl renderStats;
- private RIBImplRuntimeRegistrator registrator = null;
- private RIBImplRuntimeRegistration runtimeReg = null;
-
- public RIBImpl(final RibId ribId, final AsNumber localAs, final BgpId localBgpId, final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions,
- final BGPDispatcher dispatcher, final BindingCodecTreeFactory codecFactory,
- final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
- @Nonnull final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies, final GeneratedClassLoadingStrategy classStrategy,
- final BGPConfigModuleTracker moduleTracker, final BGPOpenConfigProvider openConfigProvider) {
+ private final RibId ribId;
+
+ public RIBImpl(final ClusterSingletonServiceProvider provider, final RibId ribId, final AsNumber localAs, final BgpId localBgpId,
+ final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions, final BGPDispatcher dispatcher,
+ final BindingCodecTreeFactory codecFactory, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
+ @Nonnull final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies, final GeneratedClassLoadingStrategy classStrategy,
+ final BGPConfigModuleTracker moduleTracker, final BGPOpenConfigProvider openConfigProvider, final BgpDeployer.WriteConfiguration configurationWriter) {
+
super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
this.domChain = domDataBroker.createTransactionChain(this);
this.localAs = Preconditions.checkNotNull(localAs);
this.localTables = ImmutableSet.copyOf(localTables);
this.localTablesKeys = new HashSet<>();
this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
+ this.service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
this.extensions = Preconditions.checkNotNull(extensions);
this.codecsRegistry = CodecsRegistryImpl.create(codecFactory, classStrategy);
this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, this.codecsRegistry);
this.bestPathSelectionStrategies = Preconditions.checkNotNull(bestPathSelectionStrategies);
final ClusterIdentifier cId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : clusterId;
this.renderStats = new RIBImplRuntimeMXBeanImpl(localBgpId, ribId, localAs, cId);
-
- LOG.debug("Instantiating RIB table {} at {}", ribId, this.yangRibId);
-
- final ContainerNode bgpRib = Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(BgpRib.QNAME))
- .addChild(ImmutableNodes.mapNodeBuilder(Rib.QNAME).build()).build();
-
- final MapEntryNode ribInstance = Builders.mapEntryBuilder().withNodeIdentifier(
- new NodeIdentifierWithPredicates(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()))
- .addChild(ImmutableNodes.leafNode(RIB_ID_QNAME, ribId.getValue()))
- .addChild(ImmutableNodes.mapNodeBuilder(Peer.QNAME).build())
- .addChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(LocRib.QNAME))
- .addChild(ImmutableNodes.mapNodeBuilder(Tables.QNAME).build())
- .build()).build();
-
-
- final DOMDataWriteTransaction trans = this.domChain.newWriteOnlyTransaction();
-
- // merge empty BgpRib + Rib, to make sure the top-level parent structure is present
- trans.merge(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.builder().node(BgpRib.QNAME).build(), bgpRib);
- trans.put(LogicalDatastoreType.OPERATIONAL, yangRibIdBuilder.build(), ribInstance);
-
- try {
- trans.submit().checkedGet();
- } catch (final TransactionCommitFailedException e) {
- LOG.error("Failed to initiate RIB {}", this.yangRibId, e);
- }
- final PolicyDatabase policyDatabase = new PolicyDatabase(localAs.getValue(), localBgpId, cId);
- this.importPolicyPeerTracker = new ImportPolicyPeerTrackerImpl(policyDatabase);
-
- final DOMDataBrokerExtension domDatatreeChangeService = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
- this.service = domDatatreeChangeService;
- LOG.debug("Effective RIB created.");
-
- for (final BgpTableType t : this.localTables) {
- final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
- this.localTablesKeys.add(key);
- startLocRib(key, policyDatabase);
- }
-
- if (this.configModuleTracker != null) {
- this.configModuleTracker.onInstanceCreate();
- }
- }
-
- public RIBImpl(final RibId ribId, final AsNumber localAs, final BgpId localBgpId, @Nullable final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions,
- final BGPDispatcher dispatcher, final BindingCodecTreeFactory codecFactory,
- final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
- final Map<TablesKey, PathSelectionMode> bestPathSelectionstrategies, final GeneratedClassLoadingStrategy classStrategy) {
- this(ribId, localAs, localBgpId, clusterId, extensions, dispatcher, codecFactory,
- domDataBroker, localTables, bestPathSelectionstrategies, classStrategy, null, null);
- }
-
- public synchronized void registerRootRuntimeBean(final RIBImplRuntimeRegistrator registrator) {
- this.registrator = registrator;
-
- initStatsRuntimeBean();
+ this.ribId = ribId;
+ this.policyDatabase = new PolicyDatabase(this.localAs.getValue(), localBgpId, cId);
+ this.importPolicyPeerTracker = new ImportPolicyPeerTrackerImpl( this.policyDatabase);
+ this.serviceGroupIdentifier = ServiceGroupIdentifier.create(this.ribId + "-service-group");
+ Preconditions.checkNotNull(provider, "ClusterSingletonServiceProvider is null");
+ this.provider = provider;
+ LOG.info("RIB Singleton Service {} registered", this.getIdentifier());
+ this.registration = registerClusterSingletonService(this);
+ this.configurationWriter = configurationWriter;
}
- /**
- * Register the statistic runtime bean
- */
- private void initStatsRuntimeBean() {
- if (this.registrator != null) {
- LOG.debug("Initializing Render Status runtime bean..");
- this.runtimeReg = this.registrator.register(this.renderStats);
- }
- }
-
- private void stopStatsRuntimeBean() {
- if (this.runtimeReg != null) {
- LOG.debug("Destroying Render Status runtime bean..");
- this.runtimeReg.close();
- this.runtimeReg = null;
- }
- // reset all the stats
- this.renderStats.getLocRibRouteCounter().resetAll();
+ public RIBImpl(final ClusterSingletonServiceProvider provider, final RibId ribId, final AsNumber localAs, final BgpId localBgpId, @Nullable final ClusterIdentifier clusterId,
+ final RIBExtensionConsumerContext extensions, final BGPDispatcher dispatcher, final BindingCodecTreeFactory codecFactory,
+ final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final Map<TablesKey, PathSelectionMode> bestPathSelectionstrategies,
+ final GeneratedClassLoadingStrategy classStrategy, final BgpDeployer.WriteConfiguration configurationWriter) {
+ this(provider, ribId, localAs, localBgpId, clusterId, extensions, dispatcher, codecFactory,
+ domDataBroker, localTables, bestPathSelectionstrategies, classStrategy, null, null, configurationWriter);
}
private void startLocRib(final TablesKey key, final PolicyDatabase pd) {
}
@Override
- public synchronized void close() {
- try {
- final DOMDataWriteTransaction t = this.domChain.newWriteOnlyTransaction();
- t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
- t.submit().checkedGet();
- } catch (final TransactionCommitFailedException e) {
- LOG.warn("Failed to remove RIB instance {} from DS.", getYangRibId(), e);
- }
- this.domChain.close();
- for (final LocRibWriter locRib : this.locRibs) {
- try {
- locRib.close();
- } catch (final Exception e) {
- LOG.warn("Could not close LocalRib reference: {}", locRib, e);
- }
- }
-
- stopStatsRuntimeBean();
-
- if (this.configModuleTracker != null) {
- this.configModuleTracker.onInstanceClose();
+ public synchronized void close() throws Exception {
+ if (registration != null) {
+ registration.close();
+ registration = null;
}
}
public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
return this.importPolicyPeerTracker;
}
+
+ @Override
+ public void instantiateServiceInstance() {
+ if(this.configurationWriter != null) {
+ this.configurationWriter.apply();
+ }
+ LOG.info("RIB Singleton Service {} instantiated", this.getIdentifier());
+ LOG.debug("Instantiating RIB table {} at {}", this.ribId , this.yangRibId);
+
+ final ContainerNode bgpRib = Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(BgpRib.QNAME))
+ .addChild(ImmutableNodes.mapNodeBuilder(Rib.QNAME).build()).build();
+
+ final MapEntryNode ribInstance = Builders.mapEntryBuilder().withNodeIdentifier(
+ new NodeIdentifierWithPredicates(Rib.QNAME, RIB_ID_QNAME, this.ribId .getValue()))
+ .addChild(ImmutableNodes.leafNode(RIB_ID_QNAME, this.ribId .getValue()))
+ .addChild(ImmutableNodes.mapNodeBuilder(Peer.QNAME).build())
+ .addChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(LocRib.QNAME))
+ .addChild(ImmutableNodes.mapNodeBuilder(Tables.QNAME).build())
+ .build()).build();
+
+
+ final DOMDataWriteTransaction trans = this.domChain.newWriteOnlyTransaction();
+
+ // merge empty BgpRib + Rib, to make sure the top-level parent structure is present
+ trans.merge(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.builder().node(BgpRib.QNAME).build(), bgpRib);
+ trans.put(LogicalDatastoreType.OPERATIONAL, this.yangRibId, ribInstance);
+
+ try {
+ trans.submit().checkedGet();
+ } catch (final TransactionCommitFailedException e) {
+ LOG.error("Failed to initiate RIB {}", this.yangRibId, e);
+ }
+
+ LOG.debug("Effective RIB created.");
+
+ for (final BgpTableType t : this.localTables) {
+ final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
+ this.localTablesKeys.add(key);
+ startLocRib(key, policyDatabase);
+ }
+
+ if (this.configModuleTracker != null) {
+ this.configModuleTracker.onInstanceCreate();
+ }
+ }
+
+ @Override
+ public ListenableFuture<Void> closeServiceInstance() {
+ try {
+ final DOMDataWriteTransaction t = this.domChain.newWriteOnlyTransaction();
+ t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
+ t.submit().checkedGet();
+ } catch (final TransactionCommitFailedException e) {
+ LOG.warn("Failed to remove RIB instance {} from DS.", getYangRibId(), e);
+ }
+ this.domChain.close();
+ for (final LocRibWriter locRib : this.locRibs) {
+ try {
+ locRib.close();
+ } catch (final Exception e) {
+ LOG.warn("Could not close LocalRib reference: {}", locRib, e);
+ }
+ }
+
+ this.renderStats.getLocRibRouteCounter().resetAll();
+
+ if (this.configModuleTracker != null) {
+ this.configModuleTracker.onInstanceClose();
+ }
+ return Futures.immediateFuture(null);
+ }
+
+ @Override
+ public ServiceGroupIdentifier getIdentifier() {
+ return this.serviceGroupIdentifier;
+ }
+
+ @Override
+ public ClusterSingletonServiceRegistration registerClusterSingletonService(final ClusterSingletonService clusterSingletonService) {
+ return this.provider.registerClusterSingletonService(clusterSingletonService);
+ }
+
+ @Override
+ public ServiceGroupIdentifier getRibIServiceGroupIdentifier() {
+ return getIdentifier();
+ }
}
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.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import java.util.Hashtable;
import java.util.Map;
import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class BgpDeployerImpl implements BgpDeployer, DataTreeChangeListener<Bgp>, AutoCloseable {
-
+public final class BgpDeployerImpl implements BgpDeployer, ClusteredDataTreeChangeListener<Bgp>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(BgpDeployerImpl.class);
-
private final InstanceIdentifier<NetworkInstance> networkInstanceIId;
private final BlueprintContainer container;
private final BundleContext bundleContext;
private final BGPOpenConfigMappingService mappingService;
- private final ListenerRegistration<BgpDeployerImpl> registration;
+ private final ListenerRegistration<BgpDeployerImpl> registration;
@GuardedBy("this")
private final Map<InstanceIdentifier<Bgp>, RibImpl> ribs = new HashMap<>();
@GuardedBy("this")
private final Map<InstanceIdentifier<Neighbor>, BgpPeer> peers = new HashMap<>();
+ private final DataBroker dataBroker;
@GuardedBy("this")
private boolean closed;
- private final DataBroker dataBroker;
-
public BgpDeployerImpl(final String networkInstanceName, final BlueprintContainer container, final BundleContext bundleContext, final DataBroker dataBroker,
- final BGPOpenConfigMappingService mappingService) {
+ final BGPOpenConfigMappingService mappingService) {
this.dataBroker = Preconditions.checkNotNull(dataBroker);
this.container = Preconditions.checkNotNull(container);
this.bundleContext = Preconditions.checkNotNull(bundleContext);
this.mappingService = Preconditions.checkNotNull(mappingService);
this.networkInstanceIId = InstanceIdentifier
- .create(NetworkInstances.class)
- .child(NetworkInstance.class, new NetworkInstanceKey(networkInstanceName));
+ .create(NetworkInstances.class)
+ .child(NetworkInstance.class, new NetworkInstanceKey(networkInstanceName));
Futures.addCallback(initializeNetworkInstance(dataBroker, this.networkInstanceIId), new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
LOG.debug("Network Instance {} initialized successfully.", networkInstanceName);
}
+
@Override
public void onFailure(final Throwable t) {
LOG.error("Failed to initialize Network Instance {}.", networkInstanceName, t);
}
});
- this.registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, this.networkInstanceIId.child(Protocols.class)
+ this.registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ this.networkInstanceIId.child(Protocols.class)
.child(Protocol.class)
.augmentation(Protocol1.class)
.child(Bgp.class)), this);
@Override
public synchronized void close() throws Exception {
this.registration.close();
- this.peers.values().forEach(bgpPeer -> bgpPeer.close());
+ this.peers.values().forEach(BgpPeer::close);
this.peers.clear();
- this.ribs.values().forEach(rib -> rib.close());
+ this.ribs.values().forEach(RibImpl::close);
this.ribs.clear();
this.closed = true;
}
private static CheckedFuture<Void, TransactionCommitFailedException> initializeNetworkInstance(final DataBroker dataBroker,
- final InstanceIdentifier<NetworkInstance> networkInstance) {
+ final InstanceIdentifier<NetworkInstance> networkInstance) {
final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
wTx.merge(LogicalDatastoreType.CONFIGURATION, networkInstance,
- new NetworkInstanceBuilder().setName(networkInstance.firstKeyOf(NetworkInstance.class).getName()).setProtocols(new ProtocolsBuilder().build()).build());
+ new NetworkInstanceBuilder().setName(networkInstance.firstKeyOf(NetworkInstance.class).getName()).setProtocols(new ProtocolsBuilder().build()).build());
return wTx.submit();
}
private void onGlobalChanged(final DataObjectModification<Global> dataObjectModification,
- final InstanceIdentifier<Bgp> rootIdentifier) {
+ final InstanceIdentifier<Bgp> rootIdentifier) {
switch (dataObjectModification.getModificationType()) {
case DELETE:
onGlobalRemoved(rootIdentifier);
LOG.debug("Modifing RIB instance with configuration: {}", global);
//restart existing rib instance with a new configuration
final RibImpl ribImpl = this.ribs.get(rootIdentifier);
- if (ribImpl != null) {
- ribImpl.close();
- initiateRibInstance(rootIdentifier, global, ribImpl);
- } else {
+ if(ribImpl == null ) {
//if not exists, create a new instance
- onGlobalCreated(rootIdentifier, global);
+ onGlobalCreated(rootIdentifier, global, null);
+ } else if (!ribImpl.isGlobalEqual(global)) {
+ ribImpl.close();
+ initiateRibInstance(rootIdentifier, global, ribImpl, null);
}
LOG.debug("RIB instance modified {}", ribImpl);
}
- private void onGlobalCreated(final InstanceIdentifier<Bgp> rootIdentifier, final Global global) {
- //create, start and register rib instance
+ @Override
+ public synchronized void onGlobalCreated(final InstanceIdentifier<Bgp> rootIdentifier, final Global global, final WriteConfiguration
+ configurationWriter) {
LOG.debug("Creating RIB instance with configuration: {}", global);
final RibImpl ribImpl = (RibImpl) this.container.getComponentInstance(InstanceType.RIB.getBeanName());
- initiateRibInstance(rootIdentifier, global, ribImpl);
+ initiateRibInstance(rootIdentifier, global, ribImpl, configurationWriter);
this.ribs.put(rootIdentifier, ribImpl);
LOG.debug("RIB instance created {}", ribImpl);
}
- private void onGlobalRemoved(final InstanceIdentifier<Bgp> rootIdentifier) {
- //destroy rib instance
+ @Override
+ public synchronized void onGlobalRemoved(final InstanceIdentifier<Bgp> rootIdentifier) {
LOG.debug("Removing RIB instance: {}", rootIdentifier);
final RibImpl ribImpl = this.ribs.remove(rootIdentifier);
if (ribImpl != null) {
}
private void initiateRibInstance(final InstanceIdentifier<Bgp> rootIdentifier, final Global global,
- final RibImpl ribImpl) {
+ final RibImpl ribImpl, final WriteConfiguration configurationWriter) {
final String ribInstanceName = getRibInstanceName(rootIdentifier);
- ribImpl.start(global, ribInstanceName, this.mappingService);
+ ribImpl.start(global, ribInstanceName, this.mappingService, configurationWriter);
registerRibInstance(ribImpl, ribInstanceName);
}
private void onNeighborsChanged(final DataObjectModification<Neighbors> dataObjectModification,
- final InstanceIdentifier<Bgp> rootIdentifier) {
+ final InstanceIdentifier<Bgp> rootIdentifier) {
for (final DataObjectModification<? extends DataObject> neighborModification : dataObjectModification.getModifiedChildren()) {
switch (neighborModification.getModificationType()) {
case DELETE:
}
private void initiatePeerInstance(final InstanceIdentifier<Bgp> rootIdentifier, final InstanceIdentifier<Neighbor> neighborIdentifier, final Neighbor neighbor,
- final BgpPeer bgpPeer) {
+ final BgpPeer bgpPeer) {
final String peerInstanceName = getNeighborInstanceName(neighborIdentifier);
final RibImpl rib = this.ribs.get(rootIdentifier);
if (rib != null) {
}
@Override
- public <T extends DataObject> ListenableFuture<Void> writeConfiguration(final T data,
- final InstanceIdentifier<T> identifier) {
+ public BGPOpenConfigMappingService getMappingService() {
+ return this.mappingService;
+ }
+
+ @Override
+ public <T extends DataObject> ListenableFuture<Void> writeConfiguration(final T data, final InstanceIdentifier<T> identifier) {
final ReadWriteTransaction wTx = this.dataBroker.newReadWriteTransaction();
- final CheckedFuture<Optional<T>, ReadFailedException> readFuture = wTx.read(LogicalDatastoreType.CONFIGURATION, identifier);
- Futures.addCallback(readFuture, new FutureCallback<Optional<T>>() {
- @Override
- public void onSuccess(final Optional<T> result) {
- if (!result.isPresent()) {
- wTx.put(LogicalDatastoreType.CONFIGURATION, identifier, data);
- }
- }
- @Override
- public void onFailure(final Throwable t) {
- LOG.debug("Failed to ensure presence of {}, try to write configuration.", identifier, t);
- wTx.put(LogicalDatastoreType.CONFIGURATION, identifier, data);
- }
- });
+ wTx.put(LogicalDatastoreType.CONFIGURATION, identifier, data);
return wTx.submit();
-
}
@Override
public <T extends DataObject> ListenableFuture<Void> removeConfiguration(
- final InstanceIdentifier<T> identifier) {
+ final InstanceIdentifier<T> identifier) {
final WriteTransaction wTx = this.dataBroker.newWriteOnlyTransaction();
wTx.delete(LogicalDatastoreType.CONFIGURATION, identifier);
return wTx.submit();
}
-
- @Override
- public BGPOpenConfigMappingService getMappingService() {
- return this.mappingService;
- }
-
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
+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.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer;
import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
private RIBImpl ribImpl;
private ServiceRegistration<?> serviceRegistration;
private ListenerRegistration<SchemaContextListener> schemaContextRegistration;
+ private final ClusterSingletonServiceProvider provider;
+ private List<AfiSafi> afiSafi;
+ private AsNumber asNumber;
+ private Ipv4Address routerId;
@SuppressWarnings("deprecation")
- public RibImpl(final RIBExtensionConsumerContext contextProvider, final BGPDispatcher dispatcher,
+ public RibImpl(final ClusterSingletonServiceProvider provider, final RIBExtensionConsumerContext contextProvider, final BGPDispatcher dispatcher,
final BindingCodecTreeFactory codecTreeFactory, final DOMDataBroker domBroker, final SchemaService schemaService) {
+ this.provider = Preconditions.checkNotNull(provider);
this.extensions = contextProvider;
this.dispatcher = dispatcher;
this.codecTreeFactory = codecTreeFactory;
this.schemaService = schemaService;
}
- void start(final Global global, final String instanceName, final BGPOpenConfigMappingService mappingService) {
+ void start(final Global global, final String instanceName, final BGPOpenConfigMappingService mappingService,
+ final BgpDeployer.WriteConfiguration configurationWriter) {
Preconditions.checkState(this.ribImpl == null, "Previous instance %s was not closed.", this);
- this.ribImpl = createRib(global, instanceName, mappingService);
+ this.ribImpl = createRib(provider, global, instanceName, mappingService, configurationWriter);
this.schemaContextRegistration = this.schemaService.registerSchemaContextListener(this.ribImpl);
}
+ Boolean isGlobalEqual(final Global global) {
+ final List<AfiSafi> globalAfiSafi = global.getAfiSafis().getAfiSafi();
+ final AsNumber globalAs = global.getConfig().getAs();
+ final Ipv4Address globalRouterId = global.getConfig().getRouterId();
+ return this.afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(this.afiSafi)
+ && globalAs.equals(this.asNumber) && globalRouterId.equals(this.routerId);
+ }
+
@Override
public KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
return this.ribImpl.getInstanceIdentifier();
@Override
public void close() {
if (this.ribImpl != null) {
- this.ribImpl.close();
+ try {
+ this.ribImpl.close();
+ } catch (Exception e) {
+ LOG.warn("Failed to close {} rib instance", this, e);
+ }
this.ribImpl = null;
}
if (this.schemaContextRegistration != null) {
}
}
- public void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
+ void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
this.serviceRegistration = serviceRegistration;
}
return this.ribImpl.getLocalTablesKeys();
}
+ @Override
+ public ServiceGroupIdentifier getRibIServiceGroupIdentifier() {
+ return this.ribImpl.getRibIServiceGroupIdentifier();
+ }
+
@Override
public String toString() {
return this.ribImpl.toString();
}
- private RIBImpl createRib(final Global global, final String bgpInstanceName, final BGPOpenConfigMappingService mappingService) {
- final Map<TablesKey, PathSelectionMode> pathSelectionModes = mappingService.toPathSelectionMode(global.getAfiSafis().getAfiSafi()).entrySet()
- .stream().collect(Collectors.toMap(entry -> new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), entry -> entry.getValue()));
- return new RIBImpl(new RibId(bgpInstanceName), new AsNumber(global.getConfig().getAs().getValue()),
- new BgpId(global.getConfig().getRouterId().getValue()), new ClusterIdentifier(global.getConfig().getRouterId().getValue()),
- this.extensions, this.dispatcher, this.codecTreeFactory, this.domBroker,
- mappingService.toTableTypes(global.getAfiSafis().getAfiSafi()), pathSelectionModes,
- this.extensions.getClassLoadingStrategy());
+ private RIBImpl createRib(final ClusterSingletonServiceProvider provider, final Global global, final String bgpInstanceName,
+ final BGPOpenConfigMappingService mappingService, final BgpDeployer.WriteConfiguration configurationWriter) {
+ this.afiSafi = global.getAfiSafis().getAfiSafi();
+ this.asNumber = global.getConfig().getAs();
+ this.routerId = global.getConfig().getRouterId();
+ final Map<TablesKey, PathSelectionMode> pathSelectionModes = mappingService.toPathSelectionMode(this.afiSafi).entrySet()
+ .stream().collect(Collectors.toMap(entry -> new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
+ return new RIBImpl(provider, new RibId(bgpInstanceName), this.asNumber, new BgpId(this.routerId), new ClusterIdentifier(this.routerId),
+ this.extensions, this.dispatcher, this.codecTreeFactory, this.domBroker, mappingService.toTableTypes(this.afiSafi), pathSelectionModes,
+ this.extensions.getClassLoadingStrategy(), configurationWriter);
}
+ @Override
+ public ClusterSingletonServiceRegistration registerClusterSingletonService(final ClusterSingletonService clusterSingletonService) {
+ return this.provider.registerClusterSingletonService(clusterSingletonService);
+ }
}
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
+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.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
* The BgpDeployer service is managing RIB, Peer, Application Peer instances based on the OpenConfig BGP
* configuration status.
* BGP configuration is held under the specific OpenConfig's NetworkInstance subtree.
- *
*/
public interface BgpDeployer {
+ interface WriteConfiguration {
+ void apply();
+ }
+
/**
* Get pointer to NetworkInstance instance where this particular BGP deployer is binded.
+ *
* @return InstanceIdentifier
*/
InstanceIdentifier<NetworkInstance> getInstanceIdentifier();
<T extends DataObject> ListenableFuture<Void> writeConfiguration(T data, InstanceIdentifier<T> identifier);
<T extends DataObject> ListenableFuture<Void> removeConfiguration(InstanceIdentifier<T> identifier);
+
+ /**
+ * Create, start and register rib instance
+ * @param rootIdentifier
+ * @param global
+ * @param configurationWriter
+ */
+ void onGlobalCreated(InstanceIdentifier<Bgp> rootIdentifier, Global global, WriteConfiguration configurationWriter);
+
+ /**
+ * Destroy rib instance
+ * @param rootIdentifier
+ */
+ void onGlobalRemoved(InstanceIdentifier<Bgp> rootIdentifier);
}
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
import org.opendaylight.protocol.bgp.rib.RibReference;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
/**
* Internal reference to a RIB instance.
*/
-public interface RIB extends RibReference {
+public interface RIB extends RibReference, ClusterSingletonServiceProvider {
AsNumber getLocalAs();
BgpId getBgpIdentifier();
ImportPolicyPeerTracker getImportPolicyPeerTracker();
Set<TablesKey> getLocalTablesKeys();
+
+ /**
+ * Return common ServiceGroupIdentifier to be used between same group cluster service
+ * @return ServiceGroupIdentifier
+ */
+ ServiceGroupIdentifier getRibIServiceGroupIdentifier();
}
<reference id="BGPExtensionContext" interface="org.opendaylight.protocol.bgp.parser.spi.BGPExtensionConsumerContext"/>
<reference id="globalBossGroup" interface="io.netty.channel.EventLoopGroup" odl:type="global-boss-group"/>
<reference id="globalWorkerGroup" interface="io.netty.channel.EventLoopGroup" odl:type="global-worker-group"/>
+ <reference id="clusterSingletonServiceProvider" interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
<bean id="BGPDispatcher" class="org.opendaylight.protocol.bgp.rib.impl.BGPDispatcherImpl">
<argument>
<service ref="bgpDeployer" interface="org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer"/>
<bean id="ribImpl" class="org.opendaylight.protocol.bgp.rib.impl.config.RibImpl" scope="prototype">
+ <argument ref="clusterSingletonServiceProvider"/>
<argument ref="globalBgpExtensions"/>
<argument ref="BGPDispatcher"/>
<argument ref="codecTreeFactory"/>
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
+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.network.instance.rev151018.network.instance.top.NetworkInstances;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
any(InetSocketAddress.class), any(BGPPeerRegistry.class), anyInt(), any(Optional.class));
setupMockService(BgpDeployer.class, this.bgpDeployer);
- doReturn(new ProtocolBuilder().setKey(new ProtocolKey(BGP.class, "bgp")).build()).when(this.bgpMappingService).fromRib(any(), any(), any(), any(), any(), any());
+ final Global global = mock(Global.class);
+ final Bgp globalBgp = mock(Bgp.class);
+ doReturn(global).when(globalBgp).getGlobal();
+ doReturn("global").when(global).toString();
+ doReturn(new ProtocolBuilder().setKey(new ProtocolKey(BGP.class, "bgp"))
+ .addAugmentation(Protocol1.class, new Protocol1Builder().setBgp(globalBgp).build()).build())
+ .when(this.bgpMappingService).fromRib(any(), any(), any(), any(), any(), any());
+ doNothing().when(this.bgpDeployer).onGlobalCreated(any(),any(),any());
doReturn(NEIGHBOR).when(this.bgpMappingService).fromBgpPeer(any(), any(),
any(), any(), any(), any(), any(), any(), any(), any(), any());
doReturn(this.mockedFuture).when(this.bgpDeployer).writeConfiguration(any(), any());
doReturn(new ServiceReference[]{mockServiceRef}).when(this.mockedContext).
getServiceReferences(serviceInterface.getName(), null);
doReturn(instance).when(this.mockedContext).getService(mockServiceRef);
+ doReturn("test").when(mockServiceRef).toString();
}
private static SchemaContext parseYangStreams(final Collection<ByteSource> streams) {
*/
package org.opendaylight.protocol.bgp.rib.impl;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.CheckedFuture;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
+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.inet.RIBActivator;
import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
protected static final TablesKey KEY = new TablesKey(AFI, SAFI);
private BindingCodecTreeFactory codecFactory;
private RIBActivator a1;
- RIBSupport ribSupport;
+ private RIBSupport ribSupport;
protected static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, "prefix").intern();
@Mock
@Mock
private DOMDataTreeChangeService service;
+ @Mock
+ private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+
@Before
public void setUp() throws Exception {
mockRib();
this.a1 = new RIBActivator();
this.a1.startRIBExtensionProvider(context);
mockedMethods();
- this.rib = new RIBImpl(new RibId("test"), new AsNumber(5L), this.RIB_ID,
- this.CLUSTER_ID, context, this.dispatcher, this.codecFactory, this.dom,
- localTables, Collections.singletonMap(new TablesKey(AFI, SAFI), BasePathSelectionModeFactory.createBestPathSelectionStrategy()),
- GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+ doReturn(Mockito.mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider)
+ .registerClusterSingletonService(any(ClusterSingletonService.class));
+ this.rib = new RIBImpl(this.clusterSingletonServiceProvider, new RibId("test"), new AsNumber(5L), RIB_ID, CLUSTER_ID, context,
+ this.dispatcher, this.codecFactory, this.dom, localTables, Collections.singletonMap(new TablesKey(AFI, SAFI),
+ BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), null);
this.rib.onGlobalContextUpdated(schemaContext);
this.ribSupport = getRib().getRibSupportContext().getRIBSupportContext(KEY).getRibSupport();
}
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.opendaylight.controller.md.sal.binding.test.DataBrokerTestCustomizer;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
+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.mdsal.binding.dom.codec.api.BindingCodecTreeFactory;
import org.opendaylight.protocol.bgp.inet.RIBActivator;
import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
public class ParserToSalTest extends AbstractDataBrokerTest {
private static final String TEST_RIB_ID = "testRib";
-
- private final String hex_messages = "/bgp_hex.txt";
-
private BGPMock mock;
private AbstractRIBExtensionProviderActivator baseact, lsact;
private RIBExtensionProviderContext ext1, ext2;
-
+ private static final TablesKey TABLE_KEY = new TablesKey(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class);
@Mock
BGPDispatcher dispatcher;
-
- BindingCodecTreeFactory codecFactory;
+ @Mock
+ private ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+ private BindingCodecTreeFactory codecFactory;
private SchemaService schemaService;
+ @Before
+ public void setUp() throws Exception {
+ super.setup();
+ doReturn(Mockito.mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider).
+ registerClusterSingletonService(any(ClusterSingletonService.class));
+ }
+
@Override
protected java.lang.Iterable<org.opendaylight.yangtools.yang.binding.YangModuleInfo> getModuleInfos() throws Exception {
return ImmutableList.of(BindingReflections.getModuleInfo(Ipv4Route.class), BindingReflections.getModuleInfo(Ipv6Route.class), BindingReflections.getModuleInfo(LinkstateRoute.class));
MockitoAnnotations.initMocks(this);
final List<byte[]> bgpMessages;
try {
- bgpMessages = HexDumpBGPFileParser.parseMessages(ParserToSalTest.class.getResourceAsStream(this.hex_messages));
+ final String hexMessages = "/bgp_hex.txt";
+ bgpMessages = HexDumpBGPFileParser.parseMessages(ParserToSalTest.class.getResourceAsStream(hexMessages));
} catch (final IOException e) {
throw Throwables.propagate(e);
}
@Test
public void testWithLinkstate() throws InterruptedException, ExecutionException {
final List<BgpTableType> tables = ImmutableList.of(
- (BgpTableType) new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class));
- final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID), new AsNumber(72L), new BgpId("127.0.0.1"), null, this.ext2, this.dispatcher,
- this.codecFactory, getDomBroker(), tables,
- Collections.singletonMap(new TablesKey(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class),
- BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+ new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class));
+ final RIBImpl rib = new RIBImpl(this.clusterSingletonServiceProvider, new RibId(TEST_RIB_ID), new AsNumber(72L), new BgpId("127.0.0.1"),
+ null, this.ext2, this.dispatcher, this.codecFactory, getDomBroker(), tables, Collections.singletonMap(TABLE_KEY,
+ BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), null);
+ rib.instantiateServiceInstance();
assertTablesExists(tables, true);
rib.onGlobalContextUpdated(this.schemaService.getGlobalContext());
final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib, PeerRole.Ibgp, null);
@Test
public void testWithoutLinkstate() throws InterruptedException, ExecutionException {
- final List<BgpTableType> tables = ImmutableList.of((BgpTableType) new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
- final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID), new AsNumber(72L), new BgpId("127.0.0.1"), null, this.ext1, this.dispatcher,
- this.codecFactory, getDomBroker(), tables,
- Collections.singletonMap(new TablesKey(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class),
- BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+ final List<BgpTableType> tables = ImmutableList.of(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ final RIBImpl rib = new RIBImpl(this.clusterSingletonServiceProvider, new RibId(TEST_RIB_ID), new AsNumber(72L), new BgpId("127.0.0.1"), null,
+ this.ext1, this.dispatcher, this.codecFactory, getDomBroker(), tables, Collections.singletonMap(TABLE_KEY,
+ BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), null);
+ rib.instantiateServiceInstance();
rib.onGlobalContextUpdated(this.schemaService.getGlobalContext());
assertTablesExists(tables, true);
final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib, PeerRole.Ibgp, null);
final byte[] ret = new byte[input.length + 1];
// ff
ret[0] = -1;
- for (int i = 0; i < input.length; i++) {
- ret[i + 1] = input[i];
- }
+ System.arraycopy(input, 0, ret, 1, input.length);
return ret;
});
}