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