Convert yangtools binding APIs to mdsal bindings
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / RIBImpl.java
index 2de279beee199d5794d3f23c39ce68e06310548b..d4e31e56244d062ae33fe13811b3f95e8754054c 100755 (executable)
@@ -19,14 +19,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.RIBImplRuntimeRegistration;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.RIBImplRuntimeRegistrator;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 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.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -35,6 +34,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
 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.protocol.bgp.mode.api.PathSelectionMode;
 import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPConfigModuleTracker;
@@ -42,15 +42,15 @@ 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.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.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
+import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.RIBImplRuntimeMXBeanImpl;
 import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
 import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
 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.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase;
 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.BgpRib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
@@ -60,9 +60,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
-import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -92,10 +91,9 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     private final BGPDispatcher dispatcher;
     private final DOMTransactionChain domChain;
     private final AsNumber localAs;
-    private final Ipv4Address bgpIdentifier;
+    private final BgpId bgpIdentifier;
     private final Set<BgpTableType> localTables;
     private final Set<TablesKey> localTablesKeys;
-    private final DataBroker dataBroker;
     private final DOMDataBroker domDataBroker;
     private final RIBExtensionConsumerContext extensions;
     private final YangInstanceIdentifier yangRibId;
@@ -108,12 +106,15 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     private final CacheDisconnectedPeers cacheDisconnectedPeers;
     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 Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
-        final BGPDispatcher dispatcher, final BindingCodecTreeFactory codecFactory,
-        final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
-        @Nonnull final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies, final GeneratedClassLoadingStrategy classStrategy,
-        final BGPConfigModuleTracker moduleTracker, final BGPOpenConfigProvider openConfigProvider) {
+    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) {
         super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
         this.domChain = domDataBroker.createTransactionChain(this);
         this.localAs = Preconditions.checkNotNull(localAs);
@@ -121,7 +122,6 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
         this.localTables = ImmutableSet.copyOf(localTables);
         this.localTablesKeys = new HashSet<>();
-        this.dataBroker = dps;
         this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
         this.extensions = Preconditions.checkNotNull(extensions);
         this.codecsRegistry = CodecsRegistryImpl.create(codecFactory, classStrategy);
@@ -132,20 +132,22 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         this.openConfigProvider = openConfigProvider;
         this.cacheDisconnectedPeers = new CacheDisconnectedPeersImpl();
         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))
+                .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();
+                .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();
@@ -159,9 +161,8 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         } catch (final TransactionCommitFailedException e) {
             LOG.error("Failed to initiate RIB {}", this.yangRibId, e);
         }
-        final ClusterIdentifier cId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
         final PolicyDatabase policyDatabase  = new PolicyDatabase(localAs.getValue(), localBgpId, cId);
-        this.importPolicyPeerTracker = new ImportPolicyPeerTracker(policyDatabase);
+        this.importPolicyPeerTracker = new ImportPolicyPeerTrackerImpl(policyDatabase);
 
         final DOMDataBrokerExtension domDatatreeChangeService = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
         this.service = domDatatreeChangeService;
@@ -178,12 +179,38 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         }
     }
 
-    public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
+    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 DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
+            final DOMDataBroker domDataBroker, final List<BgpTableType> localTables,
             final Map<TablesKey, PathSelectionMode> bestPathSelectionstrategies, final GeneratedClassLoadingStrategy classStrategy) {
         this(ribId, localAs, localBgpId, clusterId, extensions, dispatcher, codecFactory,
-                dps, domDataBroker, localTables, bestPathSelectionstrategies, classStrategy, null, null);
+                domDataBroker, localTables, bestPathSelectionstrategies, classStrategy, null, null);
+    }
+
+    public synchronized void registerRootRuntimeBean(final RIBImplRuntimeRegistrator registrator) {
+        this.registrator = registrator;
+
+        initStatsRuntimeBean();
+    }
+
+    /**
+     * 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();
     }
 
     private void startLocRib(final TablesKey key, final PolicyDatabase pd) {
@@ -216,8 +243,9 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         if (pathSelectionStrategy == null) {
             pathSelectionStrategy = BasePathSelectionModeFactory.createBestPathSelectionStrategy();
         }
+
         this.locRibs.add(LocRibWriter.create(this.ribContextRegistry, key, createPeerChain(this), getYangRibId(), this.localAs, getService(), pd,
-            this.cacheDisconnectedPeers, pathSelectionStrategy));
+                this.cacheDisconnectedPeers, pathSelectionStrategy, this.renderStats.getLocRibRouteCounter().init(key)));
     }
 
     @Override
@@ -230,10 +258,14 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     }
 
     @Override
-    public synchronized void close() throws InterruptedException, ExecutionException {
-        final DOMDataWriteTransaction t = this.domChain.newWriteOnlyTransaction();
-        t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
-        t.submit().get();
+    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 {
@@ -242,6 +274,9 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
                 LOG.warn("Could not close LocalRib reference: {}", locRib, e);
             }
         }
+
+        stopStatsRuntimeBean();
+
         if (this.configModuleTracker != null) {
             this.configModuleTracker.onInstanceClose();
         }
@@ -253,7 +288,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     }
 
     @Override
-    public Ipv4Address getBgpIdentifier() {
+    public BgpId getBgpIdentifier() {
         return this.bgpIdentifier;
     }
 
@@ -278,35 +313,6 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     }
 
     @Override
-    public long getRoutesCount(final TablesKey key) {
-        try (final ReadOnlyTransaction tx = this.dataBroker.newReadOnlyTransaction()) {
-            final Optional<Tables> tableMaybe = tx.read(LogicalDatastoreType.OPERATIONAL,
-                    getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
-            if (tableMaybe.isPresent()) {
-                final Tables table = tableMaybe.get();
-                return countIpRoutes(table.getRoutes());
-            }
-        } catch (final ReadFailedException e) {
-            LOG.debug("Failed to read tables", e);
-        }
-        return 0;
-    }
-
-    private int countIpRoutes(final Routes routes) {
-        if (routes instanceof Ipv4RoutesCase) {
-            final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) routes;
-            if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
-                return routesCase.getIpv4Routes().getIpv4Route().size();
-            }
-        } else if (routes instanceof Ipv6RoutesCase) {
-            final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) routes;
-            if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
-                return routesCase.getIpv6Routes().getIpv6Route().size();
-            }
-        }
-        return 0;
-    }
-
     public Set<TablesKey> getLocalTablesKeys() {
         return this.localTablesKeys;
     }
@@ -316,6 +322,11 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         return (DOMDataTreeChangeService) this.service;
     }
 
+    @Override
+    public BGPRenderStats getRenderStats() {
+        return this.renderStats;
+    }
+
     @Override
     public YangInstanceIdentifier getYangRibId() {
         return this.yangRibId;
@@ -356,6 +367,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         return this.cacheDisconnectedPeers;
     }
 
+    @Override
     public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
         return this.importPolicyPeerTracker;
     }