2 * Copyright © 2017 AT&T 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.transportpce.olm.util;
10 import com.google.common.base.Strings;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Optional;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.TimeUnit;
16 import java.util.concurrent.TimeoutException;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.transportpce.common.Timeouts;
21 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmInput;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmOutputBuilder;
24 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.MeasurementsBuilder;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev170228.Network;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev170228.network.Nodes;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev170228.network.NodesKey;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.CurrentPmlist;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.current.pm.Measurements;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev161014.currentpmlist.CurrentPm;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmNamesEnum;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.Resource;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.CircuitPack;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Connection;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Degree;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Interface;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.InternalLink;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.PhysicalLink;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Port;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Service;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Shelf;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.rev161014.resource.resource.resource.Srg;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
45 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.olm.get.pm.input.ResourceIdentifier;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public final class OlmUtils {
57 private static final Logger LOG = LoggerFactory.getLogger(OlmUtils.class);
58 private static long DATABROKER_READ_TIMEOUT_SECONDS = 120;
59 private static final InstanceIdentifier<Topology> NETCONF_TOPO_IID =
61 .create(NetworkTopology.class)
62 .child(Topology.class,
63 new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
66 * This static method returns the port mapping {@link Nodes} for node.
69 * Unique identifier for the mounted netconf node
71 * Databroker used to read data from data store.
72 * @return {@link Nodes } from portMapping for given nodeId
74 public static Optional<Nodes> getNode(String nodeId, DataBroker db) {
75 InstanceIdentifier<Nodes> nodesIID = InstanceIdentifier.create(Network.class)
76 .child(Nodes.class, new NodesKey(nodeId));
77 try (ReadOnlyTransaction readTransaction = db.newReadOnlyTransaction()) {
78 return readTransaction.read(LogicalDatastoreType.CONFIGURATION, nodesIID)
79 .get(DATABROKER_READ_TIMEOUT_SECONDS, TimeUnit.SECONDS).toJavaUtil();
80 } catch (InterruptedException | ExecutionException | TimeoutException ex) {
81 LOG.info("Unable to read Portmapping for nodeId {}", nodeId, ex);
82 return Optional.empty();
87 * This method retrieves list of current PMs for given nodeId,
88 * resourceType, resourceName and Granularity.Currently vendorExtentions
89 * are excluded but can be added back based on requirement
92 * 1. pmFetch This operation traverse through current PM list and gets PM for
93 * given NodeId and Resource name
96 * Input parameter from the olm yang model get-pm rpc
97 * @param deviceTransactionManager
100 * @return Result of the request list of PM readings
102 public static GetPmOutputBuilder pmFetch(GetPmInput input, DeviceTransactionManager deviceTransactionManager) {
103 LOG.info("Getting PM Data for NodeId: {} ResourceType: {} ResourceName: {}", input.getNodeId(),
104 input.getResourceType(), input.getResourceIdentifier());
105 GetPmOutputBuilder pmOutputBuilder = new GetPmOutputBuilder();
106 InstanceIdentifier<CurrentPmlist> currentPmsIID = InstanceIdentifier.create(CurrentPmlist.class);
107 Optional<CurrentPmlist> currentPmList;
109 currentPmList = deviceTransactionManager
110 .getDataFromDevice(input.getNodeId(), LogicalDatastoreType.OPERATIONAL, currentPmsIID,
111 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
112 if (currentPmList.isPresent()) {
113 List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output
114 .Measurements> measurements = extractWantedMeasurements(currentPmList.get(),
115 input.getResourceType(), input.getResourceIdentifier(), input.getGranularity());
116 if (measurements.isEmpty()) {
117 LOG.error("No Matching PM data found for node: {}, " + "resource type: {}, resource name: {}",
118 input.getNodeId(), input.getResourceType(),
119 getResourceIdentifierAsString(input.getResourceIdentifier()));
121 pmOutputBuilder.setNodeId(input.getNodeId()).setResourceType(input.getResourceType())
122 .setResourceIdentifier(input.getResourceIdentifier()).setGranularity(input.getGranularity())
123 .setMeasurements(measurements);
124 LOG.info("PM Data found successfully for node: {}, resource type: {}, " + "resource name {}",
125 input.getNodeId(), input.getResourceType(),
126 getResourceIdentifierAsString(input.getResourceIdentifier()));
130 LOG.info("Device PM Data for node: {} is not available", input.getNodeId());
133 return pmOutputBuilder;
136 private static String getResourceIdentifierAsString(ResourceIdentifier resourceIdentifier) {
137 if (Strings.isNullOrEmpty(resourceIdentifier.getCircuitPackName())) {
138 return resourceIdentifier.getResourceName();
140 return resourceIdentifier.getResourceName() + ", circuit pack name: "
141 + resourceIdentifier.getCircuitPackName();
145 private static List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output
146 .Measurements> extractWantedMeasurements(CurrentPmlist currentPmList,
147 ResourceTypeEnum wantedResourceType, ResourceIdentifier wantedResourceIdentifier,
148 PmGranularity wantedGranularity) {
149 List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output
150 .Measurements> measurements = new ArrayList<>();
151 for (CurrentPm pm : currentPmList.getCurrentPm()) {
152 ResourceTypeEnum currentResourceType = pm.getResource().getResourceType().getType();
153 if (currentResourceType.equals(wantedResourceType)) {
154 Resource currentResource = pm.getResource().getResource().getResource();
155 PmGranularity currentGranularity = pm.getGranularity();
156 boolean isWantedPowerMeasure = isWantedPowerMeasure(currentResource, currentGranularity,
157 wantedResourceType, wantedResourceIdentifier, wantedGranularity);
158 if (isWantedPowerMeasure) {
159 measurements.addAll(extractMeasurements(pm.getMeasurements()));
166 private static List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output
167 .Measurements> extractMeasurements(List<Measurements> measurementsFromDevice) {
168 List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output
169 .Measurements> extractedMeasurements = new ArrayList<>();
170 for (Measurements measure : measurementsFromDevice) {
171 MeasurementsBuilder measurement = new MeasurementsBuilder();
172 if (!measure.getMeasurement().getPmParameterName().getType().equals(PmNamesEnum.VendorExtension)) {
173 measurement.setPmparameterName(measure.getMeasurement().getPmParameterName().getType().toString());
175 measurement.setPmparameterName(measure.getMeasurement().getPmParameterName().getExtension());
178 if (measure.getMeasurement().getPmParameterValue().getDecimal64() != null) {
179 measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getDecimal64()
181 } else if (measure.getMeasurement().getPmParameterValue().getUint64() != null) {
182 measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getUint64().toString());
184 extractedMeasurements.add(measurement.build());
186 return extractedMeasurements;
189 private static boolean isWantedPowerMeasure(Resource resource, PmGranularity granularity,
190 ResourceTypeEnum wantedResourceType, ResourceIdentifier wantedResourceIdentifier,
191 PmGranularity wantedGranularity) {
192 boolean identifiersAreEqual = compareResourceIdentifiers(resource, wantedResourceType,
193 wantedResourceIdentifier);
194 return identifiersAreEqual && (granularity != null) && granularity.equals(wantedGranularity);
197 private static boolean compareResourceIdentifiers(Resource resource, ResourceTypeEnum wantedResourceType,
198 ResourceIdentifier wantedResourceIdentifier) {
199 switch (wantedResourceType) {
201 Optional<CircuitPack> circuitPackOptional = tryCastToParticularResource(CircuitPack.class, resource);
202 return circuitPackOptional.flatMap(
203 circuitPack -> Optional.ofNullable(circuitPack.getCircuitPackName()))
204 .map(circuitPackName -> circuitPackName.equals(wantedResourceIdentifier.getResourceName()))
207 Optional<Connection> connectionOptional = tryCastToParticularResource(Connection.class, resource);
208 return connectionOptional.flatMap(
209 connection -> Optional.ofNullable(connection.getConnectionNumber()))
210 .map(connectionNumber -> connectionNumber.equals(wantedResourceIdentifier.getResourceName()))
213 Optional<Degree> degreeOptional = tryCastToParticularResource(Degree.class, resource);
214 return degreeOptional.flatMap(
215 degree -> Optional.ofNullable(degree.getDegreeNumber()))
216 .flatMap(degreeInteger -> Optional.of(degreeInteger.toString()))
217 .map(degreeNumberAsString ->
218 degreeNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
221 Optional<Interface> interfaceOptional = tryCastToParticularResource(Interface.class, resource);
222 return interfaceOptional.flatMap(
223 interfaceResource -> Optional.ofNullable(interfaceResource.getInterfaceName()))
224 .map(interfaceName -> interfaceName.equals(wantedResourceIdentifier.getResourceName()))
227 Optional<InternalLink> internalLinkOptional = tryCastToParticularResource(InternalLink.class, resource);
228 return internalLinkOptional.flatMap(
229 internalLink -> Optional.ofNullable(internalLink.getInternalLinkName()))
230 .map(internalLinkName -> internalLinkName.equals(wantedResourceIdentifier.getResourceName()))
233 Optional<PhysicalLink> physicalLinkOptional = tryCastToParticularResource(PhysicalLink.class, resource);
234 return physicalLinkOptional.flatMap(
235 physicalLink -> Optional.ofNullable(physicalLink.getPhysicalLinkName()))
236 .map(physicalLinkName -> physicalLinkName.equals(wantedResourceIdentifier.getResourceName()))
239 Optional<Service> serviceOptional = tryCastToParticularResource(Service.class, resource);
240 return serviceOptional.flatMap(
241 service -> Optional.ofNullable(service.getServiceName()))
242 .map(serviceName -> serviceName.equals(wantedResourceIdentifier.getResourceName()))
245 Optional<Shelf> shelfOptional = tryCastToParticularResource(Shelf.class, resource);
246 return shelfOptional.flatMap(
247 shelf -> Optional.ofNullable(shelf.getShelfName()))
248 .map(shelfName -> shelfName.equals(wantedResourceIdentifier.getResourceName()))
250 case SharedRiskGroup:
251 Optional<Srg> sharedRiskGroupOptional = tryCastToParticularResource(Srg.class, resource);
252 return sharedRiskGroupOptional.flatMap(
253 sharedRiskGroup -> Optional.ofNullable(sharedRiskGroup.getSrgNumber()))
254 .flatMap(sharedRiskGroupNumberInteger -> Optional.of(sharedRiskGroupNumberInteger.toString()))
255 .map(srgNumberAsString -> srgNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
258 Optional<Port> portContainerOptional = tryCastToParticularResource(Port.class, resource);
259 return portContainerOptional.flatMap(
260 portContainer -> Optional.ofNullable(portContainer.getPort()))
262 String portName = port.getPortName();
263 String circuitPackName = port.getCircuitPackName();
264 return (portName != null)
265 && (circuitPackName != null)
266 && portName.equals(wantedResourceIdentifier.getResourceName())
267 && circuitPackName.equals(wantedResourceIdentifier.getCircuitPackName());
271 LOG.warn("Unknown resource type {}", wantedResourceType);
276 @SuppressWarnings("unchecked")
277 private static <T extends Resource> Optional<T> tryCastToParticularResource(Class<T> resourceClass,
279 if (resource == null) {
280 LOG.warn("Resource is null.");
281 } else if (! resourceClass.isInstance(resource)) {
282 LOG.warn("Resource implement different type than expected. Expected {}, actual {}.",
283 resourceClass.getSimpleName(), resource.getClass().getSimpleName());
285 return Optional.of((T) resource);
287 return Optional.empty();