import com.google.common.base.Strings;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Objects;
+import javax.annotation.concurrent.GuardedBy;
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.openconfig.spi.BGPTableTypeRegistryConsumer;
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.protocol.bgp.rib.spi.state.BGPPeerState;
+import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerStateConsumer;
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.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.ApplicationRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.ApplicationRibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
+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;
-public class AppPeer implements PeerBean {
+public final class AppPeer implements PeerBean, BGPPeerStateConsumer {
private static final Logger LOG = LoggerFactory.getLogger(AppPeer.class);
private static final QName APP_ID_QNAME = QName.create(ApplicationRib.QNAME, "id").intern();
+ @GuardedBy("this")
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 (config != null && !Strings.isNullOrEmpty(config.getDescription())) {
+ return new ApplicationRibId(config.getDescription());
+ }
+ return new ApplicationRibId(neighbor.getNeighborAddress().getIpv4Address().getValue());
+ }
@Override
- public void start(final RIB rib, final Neighbor neighbor, final BGPOpenConfigMappingService mappingService, final WriteConfiguration configurationWriter) {
+ public synchronized void start(final RIB rib, final Neighbor neighbor, final InstanceIdentifier<Bgp> bgpIid,
+ final PeerGroupConfigLoader peerGroupLoader, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
+ Preconditions.checkState(this.bgpAppPeerSingletonService == null,
+ "Previous peer instance was not closed.");
this.currentConfiguration = neighbor;
- this.bgpAppPeerSingletonService = new BgpAppPeerSingletonService(rib, createAppRibId(neighbor), neighbor.getNeighborAddress().getIpv4Address());
+ this.bgpAppPeerSingletonService = new BgpAppPeerSingletonService(rib, createAppRibId(neighbor),
+ neighbor.getNeighborAddress().getIpv4Address());
}
@Override
- public void restart(final RIB rib, final BGPOpenConfigMappingService mappingService) {
+ public synchronized void restart(final RIB rib, final InstanceIdentifier<Bgp> bgpIid,
+ final PeerGroupConfigLoader peerGroupLoader, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
Preconditions.checkState(this.currentConfiguration != null);
- start(rib, this.currentConfiguration, mappingService, null);
+ start(rib, this.currentConfiguration, bgpIid, peerGroupLoader, tableTypeRegistry);
}
@Override
- public void close() {
- try {
- this.bgpAppPeerSingletonService.close();
- } catch (final Exception e) {
- LOG.warn("Failed to close application peer instance", e);
+ public synchronized void close() {
+ if (this.bgpAppPeerSingletonService != null) {
+ this.bgpAppPeerSingletonService = null;
+ }
+ if (this.serviceRegistration != null) {
+ this.serviceRegistration.unregister();
+ this.serviceRegistration = null;
}
}
@Override
- public Boolean containsEqualConfiguration(final Neighbor neighbor) {
- return this.currentConfiguration.equals(neighbor);
+ public synchronized void instantiateServiceInstance() {
+ if (this.bgpAppPeerSingletonService != null) {
+ this.bgpAppPeerSingletonService.instantiateServiceInstance();
+ }
}
- private static ApplicationRibId createAppRibId(final Neighbor neighbor) {
- final Config config = neighbor.getConfig();
- if (config != null && !Strings.isNullOrEmpty(config.getDescription())) {
- return new ApplicationRibId(config.getDescription());
+ @Override
+ public synchronized ListenableFuture<Void> closeServiceInstance() {
+ if (this.bgpAppPeerSingletonService != null) {
+ return this.bgpAppPeerSingletonService.closeServiceInstance();
}
- return new ApplicationRibId(neighbor.getNeighborAddress().getIpv4Address().getValue());
+
+ return Futures.immediateFuture(null);
+ }
+
+ @Override
+ public synchronized Boolean containsEqualConfiguration(final Neighbor neighbor) {
+ return Objects.equals(this.currentConfiguration.getKey(), neighbor.getKey())
+ && OpenConfigMappingUtil.isApplicationPeer(neighbor);
+ }
+
+ @Override
+ public synchronized BGPPeerState getPeerState() {
+ return this.bgpAppPeerSingletonService.getPeerState();
+ }
+
+ synchronized void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
+ this.serviceRegistration = serviceRegistration;
}
- private final class BgpAppPeerSingletonService implements ClusterSingletonService, AutoCloseable {
+ private static final class BgpAppPeerSingletonService implements BGPPeerStateConsumer {
private final ApplicationPeer applicationPeer;
private final DOMDataTreeChangeService dataTreeChangeService;
private final ApplicationRibId appRibId;
- private ClusterSingletonServiceRegistration singletonServiceRegistration;
- private ListenerRegistration<ApplicationPeer> registration;
- private final ServiceGroupIdentifier serviceGroupIdentifier;
+ @GuardedBy("this")
+ private boolean isServiceInstantiated;
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 need to be always the last step
- 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());
+ public synchronized void instantiateServiceInstance() {
+ this.isServiceInstantiated = true;
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);
+ .nodeWithKey(ApplicationRib.QNAME, APP_ID_QNAME, this.appRibId.getValue())
+ .node(Tables.QNAME).node(Tables.QNAME).build();
+ this.applicationPeer.instantiateServiceInstance(this.dataTreeChangeService,
+ new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, yangIId));
}
- @Override
- public ListenableFuture<Void> closeServiceInstance() {
- LOG.info("Application Peer Singleton Service {} instance closed", getIdentifier());
- this.registration.close();
- this.applicationPeer.close();
- return Futures.immediateFuture(null);
+ public synchronized ListenableFuture<Void> closeServiceInstance() {
+ if (!this.isServiceInstantiated) {
+ LOG.trace("Application peer already closed {}", this.appRibId.getValue());
+ return Futures.immediateFuture(null);
+ }
+ LOG.info("Application peer instance closed {}", this.appRibId.getValue());
+ this.isServiceInstantiated = false;
+ return this.applicationPeer.close();
}
@Override
- public ServiceGroupIdentifier getIdentifier() {
- return this.serviceGroupIdentifier;
+ public BGPPeerState getPeerState() {
+ return this.applicationPeer.getPeerState();
}
}
-}
\ No newline at end of file
+}