2 * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.bgpcep.pcep.topology.stats.provider;
11 import static java.util.Objects.requireNonNull;
13 import io.netty.util.concurrent.GlobalEventExecutor;
14 import io.netty.util.concurrent.ScheduledFuture;
15 import java.util.HashMap;
17 import java.util.TimerTask;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.TimeUnit;
20 import javax.annotation.Nonnull;
21 import javax.annotation.concurrent.GuardedBy;
22 import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
23 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
29 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionStateBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev171113.PcepTopologyNodeStatsAug;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev171113.PcepTopologyNodeStatsAugBuilder;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public final class TopologyStatsProviderImpl implements TransactionChainListener,
42 TopologySessionStatsRegistry, AutoCloseable {
44 private static final Logger LOG = LoggerFactory.getLogger(TopologyStatsProviderImpl.class);
46 private final Map<KeyedInstanceIdentifier<Node, NodeKey>, PcepSessionState> statsMap = new HashMap<>();
47 private final DataBroker dataBroker;
48 private final int timeout;
49 private BindingTransactionChain transactionChain;
50 private ScheduledFuture<?> scheduleTask;
52 public TopologyStatsProviderImpl(@Nonnull final DataBroker dataBroker, final int timeout) {
53 this.dataBroker = requireNonNull(dataBroker);
54 this.timeout = timeout;
58 LOG.info("Initializing TopologyStatsProvider service.", this);
59 this.transactionChain = this.dataBroker.createTransactionChain(this);
60 final TimerTask task = new TimerTask() {
63 synchronized (TopologyStatsProviderImpl.this) {
64 final WriteTransaction tx = TopologyStatsProviderImpl
65 .this.transactionChain.newWriteOnlyTransaction();
67 TopologyStatsProviderImpl.this.statsMap
68 .forEach((key, value) -> updatePCEPStats(key, value, tx));
74 this.scheduleTask = GlobalEventExecutor.INSTANCE.scheduleAtFixedRate(task, 0, this.timeout,
78 private synchronized void updatePCEPStats(
79 final KeyedInstanceIdentifier<Node, NodeKey> nodeIId,
80 final PcepSessionState stats,
81 final WriteTransaction tx) {
83 final PcepTopologyNodeStatsAug nodeStatsAug = new PcepTopologyNodeStatsAugBuilder()
84 .setPcepSessionState(new PcepSessionStateBuilder(stats).build()).build();
85 final InstanceIdentifier<PcepTopologyNodeStatsAug> statId =
86 nodeIId.augmentation(PcepTopologyNodeStatsAug.class);
87 tx.put(LogicalDatastoreType.OPERATIONAL, statId, nodeStatsAug);
91 public void close() throws Exception {
92 LOG.info("Closing TopologyStatsProvider service.", this);
93 this.scheduleTask.cancel(true);
94 final WriteTransaction wTx = this.transactionChain.newWriteOnlyTransaction();
95 this.statsMap.keySet().iterator().forEachRemaining(statId ->
96 wTx.delete(LogicalDatastoreType.OPERATIONAL, statId));
98 this.statsMap.clear();
99 this.transactionChain.close();
103 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction,
104 final Throwable cause) {
105 LOG.error("Transaction chain failed {}.", transaction != null ? transaction.getIdentifier() : null, cause);
109 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
110 LOG.debug("Transaction chain {} successful.", chain);
114 public synchronized void bind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId,
115 final PcepSessionState sessionState) {
116 this.statsMap.put(nodeId, sessionState);
120 public synchronized void unbind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId) {
121 this.statsMap.remove(nodeId);
122 final WriteTransaction wTx = this.transactionChain.newWriteOnlyTransaction();
123 wTx.delete(LogicalDatastoreType.OPERATIONAL, nodeId);
126 } catch (final InterruptedException | ExecutionException e) {
127 LOG.warn("Failed to remove Pcep Node stats {}.", nodeId.getKey().getNodeId());