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.http.openconfig.net.yang.policy.types.rev151009.BGP;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.osgi.framework.BundleContext;
@Override
public java.lang.AutoCloseable createInstance() {
final RIB rib = getTargetRibDependency();
- final WaitingServiceTracker<BgpDeployer> bgpDeployerTracker =
- WaitingServiceTracker.create(BgpDeployer.class, this.bundleContext);
+ final WaitingServiceTracker<BgpDeployer> bgpDeployerTracker = WaitingServiceTracker.create(BgpDeployer.class, this.bundleContext);
final BgpDeployer bgpDeployer = bgpDeployerTracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
//map configuration to OpenConfig BGP
final Neighbor neighbor = bgpDeployer.getMappingService().fromApplicationPeer(getApplicationRibId(), getBgpPeerId());
//write to configuration DS
- final KeyedInstanceIdentifier<Neighbor, NeighborKey> neighborIId = bgpDeployer.getInstanceIdentifier().child(Protocols.class).child(Protocol.class,
- new ProtocolKey(BGP.class, rib.getInstanceIdentifier().getKey().getId().getValue()))
- .augmentation(Protocol1.class).child(Bgp.class).child(Neighbors.class).child(Neighbor.class, neighbor.getKey());
- bgpDeployer.writeConfiguration(neighbor, neighborIId);
+ final KeyedInstanceIdentifier<Protocol, ProtocolKey> protocolIId = bgpDeployer.getInstanceIdentifier().child(Protocols.class)
+ .child(Protocol.class, new ProtocolKey(BGP.class, rib.getInstanceIdentifier().getKey().getId().getValue()));
+ final InstanceIdentifier<Bgp> bgpIID = protocolIId.augmentation(Protocol1.class).child(Bgp.class);
+ final KeyedInstanceIdentifier<Neighbor, NeighborKey> neighborIId = protocolIId.augmentation(Protocol1.class).child(Bgp.class)
+ .child(Neighbors.class).child(Neighbor.class, neighbor.getKey());
+ bgpDeployer.onNeighborModified(bgpIID, neighbor, () -> bgpDeployer.writeConfiguration(neighbor, neighborIId));
- return () -> {
- bgpDeployerTracker.close();
- };
+ return bgpDeployerTracker::close;
}
public void setBundleContext(final BundleContext bundleContext) {
private final byte[] rawIdentifier;
private final String name;
private final YangInstanceIdentifier adjRibsInId;
- private final DOMTransactionChain chain;
- private final DOMTransactionChain writerChain;
+ private final Ipv4Address ipAddress;
private final BGPConfigModuleTracker moduleTracker;
- private final EffectiveRibInWriter effectiveRibInWriter;
+ private final RIB rib;
+ private final YangInstanceIdentifier peerIId;
+ private DOMTransactionChain chain;
+ private DOMTransactionChain writerChain;
+ private EffectiveRibInWriter effectiveRibInWriter;
private AdjRibInWriter writer;
public ApplicationPeer(final ApplicationRibId applicationRibId, final Ipv4Address ipAddress, final RIB rib,
- final BGPConfigModuleTracker moduleTracker) {
- this.name = applicationRibId.getValue().toString();
+ final BGPConfigModuleTracker moduleTracker) {
+ this.name = applicationRibId.getValue();
final RIB targetRib = Preconditions.checkNotNull(rib);
this.rawIdentifier = InetAddresses.forString(ipAddress.getValue()).getAddress();
final NodeIdentifierWithPredicates peerId = IdentifierUtils.domPeerId(RouterIds.createPeerId(ipAddress));
- final YangInstanceIdentifier peerIId = targetRib.getYangRibId().node(Peer.QNAME).node(peerId);
- this.adjRibsInId = peerIId.node(AdjRibIn.QNAME).node(Tables.QNAME);
- this.chain = targetRib.createPeerChain(this);
- this.writerChain = targetRib.createPeerChain(this);
- this.writer = AdjRibInWriter.create(targetRib.getYangRibId(), PeerRole.Internal, Optional.of(SimpleRoutingPolicy.AnnounceNone), this.writerChain);
- this.writer = this.writer.transform(RouterIds.createPeerId(ipAddress), targetRib.getRibSupportContext(), targetRib.getLocalTablesKeys(),
- Collections.emptyList());
- //TODO need to create effective rib in writer with route counter here
- this.effectiveRibInWriter = EffectiveRibInWriter.create(targetRib.getService(), targetRib.createPeerChain(this), peerIId,
- targetRib.getImportPolicyPeerTracker(), targetRib.getRibSupportContext(), PeerRole.Internal);
+ this.peerIId = targetRib.getYangRibId().node(Peer.QNAME).node(peerId);
+ this.adjRibsInId = this.peerIId.node(AdjRibIn.QNAME).node(Tables.QNAME);
+ this.rib = targetRib;
+ this.ipAddress = ipAddress;
this.moduleTracker = moduleTracker;
- if (moduleTracker != null) {
- moduleTracker.onInstanceCreate();
- }
}
public ApplicationPeer(final ApplicationRibId applicationRibId, final Ipv4Address bgpPeerId, final RIB targetRibDependency) {
this(applicationRibId, bgpPeerId, targetRibDependency, null);
}
+ public void instantiateServiceInstance() {
+ this.chain = this.rib.createPeerChain(this);
+ this.writerChain = this.rib.createPeerChain(this);
+ this.writer = AdjRibInWriter.create(this.rib.getYangRibId(), PeerRole.Internal, Optional.of(SimpleRoutingPolicy.AnnounceNone), this.writerChain);
+ this.writer = this.writer.transform(RouterIds.createPeerId(this.ipAddress), this.rib.getRibSupportContext(), this.rib.getLocalTablesKeys(),
+ Collections.emptyList());
+ //TODO need to create effective rib in writer with route counter here
+ this.effectiveRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), this.peerIId,
+ this.rib.getImportPolicyPeerTracker(), this.rib.getRibSupportContext(), PeerRole.Internal);
+ if (moduleTracker != null) {
+ moduleTracker.onInstanceCreate();
+ }
+ }
+
/**
* Routes come from application RIB that is identified by (configurable) name.
* Each route is pushed into AdjRibsInWriter with it's whole context. In this
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
import org.opendaylight.protocol.bgp.rib.impl.ApplicationPeer;
import org.opendaylight.protocol.bgp.rib.impl.spi.BgpDeployer.WriteConfiguration;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AppPeer implements PeerBean {
-
+ private static final Logger LOG = LoggerFactory.getLogger(AppPeer.class);
private static final QName APP_ID_QNAME = QName.create(ApplicationRib.QNAME, "id").intern();
-
- private ApplicationPeer applicationPeer;
- private ListenerRegistration<ApplicationPeer> registration;
private Neighbor currentConfiguration;
+ private BgpAppPeerSingletonService bgpAppPeerSingletonService;
@Override
public void start(final RIB rib, final Neighbor neighbor, final BGPOpenConfigMappingService mappingService, final WriteConfiguration configurationWriter) {
- this.currentConfiguration = Preconditions.checkNotNull(neighbor);
- final ApplicationRibId appRibId = createAppRibId(neighbor);
- this.applicationPeer = new ApplicationPeer(appRibId, neighbor.getNeighborAddress().getIpv4Address(), rib);
- final YangInstanceIdentifier yangIId = YangInstanceIdentifier.builder().node(ApplicationRib.QNAME)
- .nodeWithKey(ApplicationRib.QNAME, APP_ID_QNAME, appRibId.getValue()).node(Tables.QNAME).node(Tables.QNAME).build();
- this.registration = rib.getService().registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, yangIId),
- this.applicationPeer);
+ this.currentConfiguration = neighbor;
+ this.bgpAppPeerSingletonService = new BgpAppPeerSingletonService(rib, createAppRibId(neighbor), neighbor.getNeighborAddress().getIpv4Address());
}
@Override
@Override
public void close() {
- if (this.applicationPeer != null) {
- this.registration.close();
- this.applicationPeer.close();
+ try {
+ this.bgpAppPeerSingletonService.close();
+ } catch (final Exception e) {
+ LOG.warn("Failed to close application peer instance", e);
}
}
return new ApplicationRibId(neighbor.getNeighborAddress().getIpv4Address().getValue());
}
-}
+ private final class BgpAppPeerSingletonService implements ClusterSingletonService, AutoCloseable {
+ private final ApplicationPeer applicationPeer;
+ private final DOMDataTreeChangeService dataTreeChangeService;
+ private final ApplicationRibId appRibId;
+ private ClusterSingletonServiceRegistration singletonServiceRegistration;
+ private ListenerRegistration<ApplicationPeer> registration;
+ private final ServiceGroupIdentifier serviceGroupIdentifier;
+
+ BgpAppPeerSingletonService(final RIB rib, final ApplicationRibId appRibId, final Ipv4Address neighborAddress) {
+ this.applicationPeer = new ApplicationPeer(appRibId, neighborAddress, rib);
+ this.appRibId = appRibId;
+ this.dataTreeChangeService = rib.getService();
+ this.serviceGroupIdentifier = rib.getRibIServiceGroupIdentifier();
+ LOG.info("Application Peer Singleton Service {} registered", getIdentifier());
+ this.singletonServiceRegistration = rib.registerClusterSingletonService(this);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (this.singletonServiceRegistration != null) {
+ this.singletonServiceRegistration.close();
+ this.singletonServiceRegistration = null;
+ }
+ }
+
+ @Override
+ public void instantiateServiceInstance() {
+ LOG.info("Application Peer Singleton Service {} instantiated", getIdentifier());
+ final YangInstanceIdentifier yangIId = YangInstanceIdentifier.builder().node(ApplicationRib.QNAME)
+ .nodeWithKey(ApplicationRib.QNAME, APP_ID_QNAME, appRibId.getValue()).node(Tables.QNAME).node(Tables.QNAME).build();
+ this.applicationPeer.instantiateServiceInstance();
+ this.registration = this.dataTreeChangeService
+ .registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, yangIId), this.applicationPeer);
+ }
+
+ @Override
+ public ListenableFuture<Void> closeServiceInstance() {
+ LOG.info("Application Peer Singleton Service {} instance closed", getIdentifier());
+ this.registration.close();
+ this.applicationPeer.close();
+ return Futures.immediateFuture(null);
+ }
+
+ @Override
+ public ServiceGroupIdentifier getIdentifier() {
+ return this.serviceGroupIdentifier;
+ }
+ }
+}
\ No newline at end of file
final Ipv4Prefix second = new Ipv4Prefix("127.0.0.1/32");
final Ipv4Prefix third = new Ipv4Prefix("127.0.0.3/32");
this.peer = new ApplicationPeer(new ApplicationRibId("t"), new Ipv4Address("127.0.0.1"), getRib());
+ this.peer.instantiateServiceInstance();
final YangInstanceIdentifier base = getRib().getYangRibId().node(LocRib.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(KEY));
this.peer.onDataTreeChanged(ipv4Input(base, ModificationType.WRITE, first, second, third));
assertEquals(3, this.routes.size());