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