2 * Copyright (c) 2019 Lumina Networks, Inc. and others. 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
8 package org.opendaylight.bgpcep.pcep.topology.provider;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.ConcurrentMap;
17 import java.util.stream.Collectors;
18 import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
21 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
22 import org.opendaylight.mdsal.binding.api.DataTreeModification;
23 import org.opendaylight.mdsal.binding.api.RpcProviderService;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.PcepEntityIdRpcAugBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.PcepEntityIdStatsAug;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesRpcAugBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulCapabilitiesStatsAug;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesRpcAugBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev181109.StatefulMessagesStatsAug;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPrefBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.MessagesBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilities;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilitiesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionState;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionStateBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStats;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc.rev190321.GetStatsOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev181109.PcepTopologyNodeStatsAug;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
51 import org.opendaylight.yangtools.concepts.Registration;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
58 final class TopologyStatsRpc implements DataTreeChangeListener<PcepSessionState>, AutoCloseable {
59 private static final Logger LOG = LoggerFactory.getLogger(TopologyStatsRpc.class);
61 private final ConcurrentMap<InstanceIdentifier<PcepSessionState>, PcepSessionState> sessionStateMap =
62 new ConcurrentHashMap<>();
63 private Registration listenerRegistration;
64 private Registration rpcRegistration;
66 TopologyStatsRpc(final DataBroker dataBroker, final RpcProviderService rpcProviderService) {
67 LOG.info("Initializing PCEP Topology Stats RPC service.");
68 listenerRegistration = dataBroker.registerTreeChangeListener(
69 DataTreeIdentifier.of(LogicalDatastoreType.OPERATIONAL,
70 InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(Node.class)
71 .augmentation(PcepTopologyNodeStatsAug.class).child(PcepSessionState.class).build()),
73 rpcRegistration = rpcProviderService.registerRpcImplementation((GetStats) this::getStats);
77 public void onDataTreeChanged(final List<DataTreeModification<PcepSessionState>> changes) {
78 changes.forEach(change -> {
79 final var iid = change.getRootPath().path();
80 final var mod = change.getRootNode();
81 switch (mod.modificationType()) {
82 case SUBTREE_MODIFIED, WRITE:
83 sessionStateMap.put(iid, mod.dataAfter());
86 sessionStateMap.remove(iid);
94 public synchronized void close() {
95 if (rpcRegistration != null) {
96 rpcRegistration.close();
97 rpcRegistration = null;
99 if (listenerRegistration != null) {
100 LOG.info("Closing PCEP Topology Stats RPC service.");
101 listenerRegistration.close();
102 listenerRegistration = null;
107 ListenableFuture<RpcResult<GetStatsOutput>> getStats(final GetStatsInput input) {
108 final var iTopologies = input.getTopology();
109 final List<TopologyId> iTopologyIds;
110 if (iTopologies != null) {
111 iTopologyIds = iTopologies.values().stream()
112 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc
113 .rev190321.get.stats.input.Topology::getTopologyId)
114 .collect(Collectors.toList());
116 iTopologyIds = getAvailableTopologyIds();
119 return Futures.immediateFuture(SuccessfulRpcResult.create(new GetStatsOutputBuilder()
120 .setTopology(iTopologyIds.stream()
121 .map(iTopologyId -> {
122 final Collection<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology
123 .stats.rpc.rev190321.get.stats.input.topology.Node> iNodes;
124 if (iTopologies != null) {
125 final var nodes = iTopologies.values().stream()
126 .filter(t -> iTopologyId.equals(t.getTopologyId()))
128 .orElseThrow().getNode();
129 iNodes = nodes != null ? nodes.values() : null;
134 final List<NodeId> iNodeIds;
135 if (iNodes != null) {
136 iNodeIds = iNodes.stream()
137 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats
138 .rpc.rev190321.get.stats.input.topology.Node::getNodeId)
139 .collect(Collectors.toList());
141 iNodeIds = getAvailableNodeIds(iTopologyId);
144 return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.topology.stats.rpc
145 .rev190321.get.stats.output.TopologyBuilder()
146 .setTopologyId(iTopologyId)
147 .setNode(iNodeIds.stream()
149 final PcepSessionState state = sessionStateMap.get(
150 InstanceIdentifier.builder(NetworkTopology.class)
151 .child(Topology.class, new TopologyKey(iTopologyId))
152 .child(Node.class, new NodeKey(iNodeId))
153 .augmentation(PcepTopologyNodeStatsAug.class)
154 .child(PcepSessionState.class)
157 LOG.debug("Pcep session stats not available for node {} in topology {}",
158 iNodeId.getValue(), iTopologyId.getValue());
160 return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep
161 .topology.stats.rpc.rev190321.get.stats.output.topology.NodeBuilder()
163 .setPcepSessionState(transformStatefulAugmentation(state))
166 .collect(BindingMap.toOrderedMap()))
169 .collect(BindingMap.toOrderedMap()))
174 * Replace stateful topology augmentations with ones for rpc in PCEP session
177 private static PcepSessionState transformStatefulAugmentation(final PcepSessionState pcepSessionState) {
178 if (pcepSessionState == null) {
182 final PcepSessionStateBuilder sb = new PcepSessionStateBuilder(pcepSessionState);
184 final Messages topoMessage = pcepSessionState.getMessages();
185 if (topoMessage != null) {
186 final StatefulMessagesStatsAug messageStatsAug = topoMessage.augmentation(StatefulMessagesStatsAug.class);
187 if (messageStatsAug != null) {
188 sb.setMessages(new MessagesBuilder(topoMessage)
189 .removeAugmentation(StatefulMessagesStatsAug.class)
190 .addAugmentation(new StatefulMessagesRpcAugBuilder()
191 .setLastReceivedRptMsgTimestamp(messageStatsAug.getLastReceivedRptMsgTimestamp())
192 .setReceivedRptMsgCount(messageStatsAug.getReceivedRptMsgCount())
193 .setSentInitMsgCount(messageStatsAug.getSentInitMsgCount())
194 .setSentUpdMsgCount(messageStatsAug.getSentUpdMsgCount())
200 final PeerCapabilities topoPeerCapability = pcepSessionState.getPeerCapabilities();
201 if (topoPeerCapability != null) {
202 final StatefulCapabilitiesStatsAug capabilityStatsAug =
203 topoPeerCapability.augmentation(StatefulCapabilitiesStatsAug.class);
204 if (capabilityStatsAug != null) {
205 sb.setPeerCapabilities(new PeerCapabilitiesBuilder(topoPeerCapability)
206 .removeAugmentation(StatefulCapabilitiesStatsAug.class)
207 .addAugmentation(new StatefulCapabilitiesRpcAugBuilder()
208 .setActive(capabilityStatsAug.getActive())
209 .setInstantiation(capabilityStatsAug.getInstantiation())
210 .setStateful(capabilityStatsAug.getStateful())
216 final LocalPref topoLocalPref = pcepSessionState.getLocalPref();
217 if (topoLocalPref != null) {
218 final PcepEntityIdStatsAug entityStatsAug = topoLocalPref.augmentation(PcepEntityIdStatsAug.class);
219 if (entityStatsAug != null) {
220 sb.setLocalPref(new LocalPrefBuilder(topoLocalPref)
221 .removeAugmentation(PcepEntityIdStatsAug.class)
222 .addAugmentation(new PcepEntityIdRpcAugBuilder()
223 .setSpeakerEntityIdValue(entityStatsAug.getSpeakerEntityIdValue())
232 private List<TopologyId> getAvailableTopologyIds() {
233 return sessionStateMap.keySet().stream().map(iid -> iid.firstKeyOf(Topology.class).getTopologyId()).distinct()
234 .collect(Collectors.toList());
237 private List<NodeId> getAvailableNodeIds(final TopologyId topologyId) {
238 return sessionStateMap.keySet().stream()
239 .filter(iid -> iid.firstKeyOf(Topology.class).getTopologyId().equals(topologyId))
240 .map(iid -> iid.firstKeyOf(Node.class).getNodeId()).collect(Collectors.toList());