Integrate renderer & olm code to run on device221
[transportpce.git] / olm / src / main / java / org / opendaylight / transportpce / olm / util / OlmUtils121.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.stream.Collectors;
16 import java.util.stream.Stream;
17
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.transportpce.common.Timeouts;
20 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
21 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmInput;
22 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmOutputBuilder;
23 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.MeasurementsBuilder;
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.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 final class OlmUtils121 {
47
48     private static final Logger LOG = LoggerFactory.getLogger(OlmUtils121.class);
49
50     /**
51      * This method retrieves list of current PMs for given nodeId,
52      * resourceType, resourceName and Granularity.Currently vendorExtentions
53      * are excluded but can be added back based on requirement
54      *
55      * <p>
56      * 1. pmFetch This operation traverse through current PM list and gets PM for
57      * given NodeId and Resource name
58      *
59      * @param input
60      *            Input parameter from the olm yang model get-pm rpc
61      * @param deviceTransactionManager
62      *            Device tx manager
63      *
64      * @return Result of the request list of PM readings
65      */
66     public static GetPmOutputBuilder pmFetch(GetPmInput input, DeviceTransactionManager deviceTransactionManager) {
67         LOG.info("Getting PM Data for 1.2.1 NodeId: {} ResourceType: {} ResourceName: {}", input.getNodeId(),
68                 input.getResourceType(), input.getResourceIdentifier());
69         GetPmOutputBuilder pmOutputBuilder = new GetPmOutputBuilder();
70         InstanceIdentifier<CurrentPmlist> currentPmsIID = InstanceIdentifier.create(CurrentPmlist.class);
71         Optional<CurrentPmlist> currentPmList;
72         currentPmList = deviceTransactionManager
73                 .getDataFromDevice(input.getNodeId(), LogicalDatastoreType.OPERATIONAL, currentPmsIID,
74                         Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
75         if (currentPmList.isPresent()) {
76             String pmExtension = null;
77             org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Location location = null;
78             org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Direction direction = null;
79             if (input.getPmExtension() != null) {
80                 pmExtension = input.getPmExtension();
81             }
82             if (input.getLocation() != null) {
83                 location = input.getLocation();
84             }
85             if (input.getDirection() != null) {
86                 direction = input.getDirection();
87             }
88             PmNamesEnum pmName = null;
89             List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm
90                 .rev170418.get.pm.output.Measurements>
91                 measurements = extractWantedMeasurements(currentPmList.get(),
92                 ResourceTypeEnum.forValue(input.getResourceType().getIntValue()),
93                 input.getResourceIdentifier(),
94                 PmGranularity.forValue(input.getGranularity().getIntValue()),
95                 pmName, pmExtension, location, direction);
96             if (measurements.isEmpty()) {
97                 LOG.error("No Matching PM data found for node: {}, " + "resource type: {}, resource name: {}",
98                         input.getNodeId(), input.getResourceType(),
99                         getResourceIdentifierAsString(input.getResourceIdentifier()));
100             } else {
101                 pmOutputBuilder.setNodeId(input.getNodeId()).setResourceType(input.getResourceType())
102                         .setResourceIdentifier(input.getResourceIdentifier()).setGranularity(input.getGranularity())
103                         .setMeasurements(measurements);
104                 LOG.info("PM Data found successfully for node: {}, resource type: {}, " + "resource name {}",
105                         input.getNodeId(), input.getResourceType(),
106                         getResourceIdentifierAsString(input.getResourceIdentifier()));
107             }
108
109         } else {
110             LOG.info("Device PM Data for node: {} is not available", input.getNodeId());
111         }
112
113         return pmOutputBuilder;
114     }
115
116     private static String getResourceIdentifierAsString(ResourceIdentifier resourceIdentifier) {
117         if (Strings.isNullOrEmpty(resourceIdentifier.getCircuitPackName())) {
118             return resourceIdentifier.getResourceName();
119         } else {
120             return resourceIdentifier.getResourceName() + ", circuit pack name: "
121                     + resourceIdentifier.getCircuitPackName();
122         }
123     }
124
125     private static
126         List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements>
127             extractWantedMeasurements(CurrentPmlist currentPmList, ResourceTypeEnum resourceTypeEnum,
128             ResourceIdentifier wantedResourceIdentifier,PmGranularity pmGranularity, PmNamesEnum pmNamesEnum,
129             String extension, org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Location
130             location, org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Direction direction) {
131         List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements>
132             measurements = new ArrayList<>();
133         for (CurrentPm pm : currentPmList.getCurrentPm()) {
134             ResourceTypeEnum currentResourceType = pm.getResource().getResourceType().getType();
135             if (currentResourceType.equals(resourceTypeEnum)) {
136                 Resource currentResource = pm.getResource().getResource().getResource();
137                 PmGranularity currentGranularity = pm.getGranularity();
138                 boolean isWantedPowerMeasure = isWantedPowerMeasure(currentResource, currentGranularity,
139                         resourceTypeEnum, wantedResourceIdentifier, pmGranularity);
140                 if (isWantedPowerMeasure) {
141                     measurements.addAll(extractMeasurements(pm.getMeasurements(),pmNamesEnum,
142                             extension,location,direction));
143                 }
144             }
145         }
146         return measurements;
147     }
148
149     private static
150          List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements>
151             extractMeasurements(List<Measurements> measurementsFromDevice, PmNamesEnum pmNamesEnum, String extension,
152             org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Location location,
153             org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.Direction direction) {
154         List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements>
155             extractedMeasurements = new ArrayList<>();
156         List<Measurements> pmMeasurements = measurementsFromDevice;
157         Stream<Measurements> measurementStream = pmMeasurements.stream();
158         if (pmNamesEnum != null) {
159             LOG.info("pm name is not null {} {} {}",pmNamesEnum,pmNamesEnum.getName(),pmMeasurements.get(0)
160                 .getMeasurement().getPmParameterName().getType());
161             measurementStream = measurementStream.filter(measure -> measure.getMeasurement().getPmParameterName()
162                 .getType().getName().equals(pmNamesEnum.getName()));
163         }
164         if (extension != null) {
165             LOG.info("extension is not null {}",extension);
166             measurementStream = measurementStream.filter(measure -> measure.getMeasurement()
167                     .getPmParameterName().getType().equals("vendorExtension")
168                     && measure.getMeasurement().getPmParameterName().getExtension().equals(extension));
169         }
170         if (location != null) {
171             LOG.info("location is not null {}",location);
172             measurementStream = measurementStream.filter(measure -> measure.getMeasurement().getLocation().getName()
173                 .equals(location.getName()));
174         }
175         if (direction != null) {
176             LOG.info("direction is not null {}",direction);
177             measurementStream = measurementStream.filter(measure -> measure.getMeasurement().getDirection().getName()
178                 .equals(direction.getName()));
179         }
180         List<Measurements> filteredMeasurements = measurementStream.collect(Collectors.toList());
181         for (Measurements measure : filteredMeasurements) {
182             MeasurementsBuilder measurement = new MeasurementsBuilder();
183             measurement.setPmparameterName(measure.getMeasurement().getPmParameterName().getType().toString());
184             if (measure.getMeasurement().getPmParameterValue().getDecimal64() != null) {
185                 measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getDecimal64()
186                     .toPlainString());
187             } else if (measure.getMeasurement().getPmParameterValue().getUint64() != null) {
188                 measurement.setPmparameterValue(measure.getMeasurement().getPmParameterValue().getUint64().toString());
189             }
190             extractedMeasurements.add(measurement.build());
191         }
192         return extractedMeasurements;
193     }
194
195     private static boolean isWantedPowerMeasure(Resource resource, PmGranularity granularity,
196             ResourceTypeEnum resourceTypeEnum, ResourceIdentifier wantedResourceIdentifier,
197             PmGranularity pmGranularity) {
198         boolean identifiersAreEqual = compareResourceIdentifiers(resource, resourceTypeEnum,
199                 wantedResourceIdentifier);
200         return identifiersAreEqual && granularity != null && granularity.equals(pmGranularity);
201     }
202
203     private static boolean compareResourceIdentifiers(Resource resource, ResourceTypeEnum resourceTypeEnum,
204             ResourceIdentifier wantedResourceIdentifier) {
205         switch (resourceTypeEnum) {
206             case CircuitPack:
207                 Optional<CircuitPack> circuitPackOptional = tryCastToParticularResource(CircuitPack.class, resource);
208                 return circuitPackOptional.flatMap(
209                     circuitPack -> Optional.ofNullable(circuitPack.getCircuitPackName()))
210                         .map(circuitPackName -> circuitPackName.equals(wantedResourceIdentifier.getResourceName()))
211                         .orElse(false);
212             case Connection:
213                 Optional<Connection> connectionOptional = tryCastToParticularResource(Connection.class, resource);
214                 return connectionOptional.flatMap(
215                     connection -> Optional.ofNullable(connection.getConnectionNumber()))
216                         .map(connectionNumber -> connectionNumber.equals(wantedResourceIdentifier.getResourceName()))
217                         .orElse(false);
218             case Degree:
219                 Optional<Degree> degreeOptional = tryCastToParticularResource(Degree.class, resource);
220                 return degreeOptional.flatMap(
221                     degree -> Optional.ofNullable(degree.getDegreeNumber()))
222                         .flatMap(degreeInteger -> Optional.of(degreeInteger.toString()))
223                         .map(degreeNumberAsString ->
224                                 degreeNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
225                         .orElse(false);
226             case Interface:
227                 Optional<Interface> interfaceOptional = tryCastToParticularResource(Interface.class, resource);
228                 return interfaceOptional.flatMap(
229                     interfaceResource -> Optional.ofNullable(interfaceResource.getInterfaceName()))
230                         .map(interfaceName -> interfaceName.equals(wantedResourceIdentifier.getResourceName()))
231                         .orElse(false);
232             case InternalLink:
233                 Optional<InternalLink> internalLinkOptional = tryCastToParticularResource(InternalLink.class, resource);
234                 return internalLinkOptional.flatMap(
235                     internalLink -> Optional.ofNullable(internalLink.getInternalLinkName()))
236                         .map(internalLinkName -> internalLinkName.equals(wantedResourceIdentifier.getResourceName()))
237                         .orElse(false);
238             case PhysicalLink:
239                 Optional<PhysicalLink> physicalLinkOptional = tryCastToParticularResource(PhysicalLink.class, resource);
240                 return physicalLinkOptional.flatMap(
241                     physicalLink -> Optional.ofNullable(physicalLink.getPhysicalLinkName()))
242                         .map(physicalLinkName -> physicalLinkName.equals(wantedResourceIdentifier.getResourceName()))
243                         .orElse(false);
244             case Service:
245                 Optional<Service> serviceOptional = tryCastToParticularResource(Service.class, resource);
246                 return serviceOptional.flatMap(
247                     service -> Optional.ofNullable(service.getServiceName()))
248                         .map(serviceName -> serviceName.equals(wantedResourceIdentifier.getResourceName()))
249                     .orElse(false);
250             case Shelf:
251                 Optional<Shelf> shelfOptional = tryCastToParticularResource(Shelf.class, resource);
252                 return shelfOptional.flatMap(
253                     shelf -> Optional.ofNullable(shelf.getShelfName()))
254                         .map(shelfName -> shelfName.equals(wantedResourceIdentifier.getResourceName()))
255                         .orElse(false);
256             case SharedRiskGroup:
257                 Optional<Srg> sharedRiskGroupOptional = tryCastToParticularResource(Srg.class, resource);
258                 return sharedRiskGroupOptional.flatMap(
259                     sharedRiskGroup -> Optional.ofNullable(sharedRiskGroup.getSrgNumber()))
260                         .flatMap(sharedRiskGroupNumberInteger -> Optional.of(sharedRiskGroupNumberInteger.toString()))
261                         .map(srgNumberAsString -> srgNumberAsString.equals(wantedResourceIdentifier.getResourceName()))
262                         .orElse(false);
263             case Port:
264                 Optional<Port> portContainerOptional = tryCastToParticularResource(Port.class, resource);
265                 return portContainerOptional.flatMap(
266                     portContainer -> Optional.ofNullable(portContainer.getPort()))
267                         .map(port -> {
268                             String portName = port.getPortName();
269                             String circuitPackName = port.getCircuitPackName();
270                             return portName != null && circuitPackName != null
271                                     && portName.equals(wantedResourceIdentifier.getResourceName())
272                                     && circuitPackName.equals(wantedResourceIdentifier.getCircuitPackName());
273                         })
274                         .orElse(false);
275             default:
276                 LOG.warn("Unknown resource type {}", resourceTypeEnum);
277                 return false;
278         }
279     }
280
281     @SuppressWarnings("unchecked")
282     public static <T extends Resource> Optional<T> tryCastToParticularResource(Class<T> resourceClass,
283             Resource resource) {
284         if (resource == null) {
285             LOG.warn("Resource is null.");
286         } else if (! resourceClass.isInstance(resource)) {
287             LOG.warn("Resource implement different type than expected. Expected {}, actual {}.",
288                     resourceClass.getSimpleName(), resource.getClass().getSimpleName());
289         } else {
290             return Optional.of((T) resource);
291         }
292         return Optional.empty();
293     }
294
295     private OlmUtils121() {
296     }
297
298 }