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.renderer.provisiondevice;
10 import com.google.common.util.concurrent.Futures;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.ListeningExecutorService;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Optional;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Executors;
20 import java.util.concurrent.Future;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.TimeoutException;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
25 import org.opendaylight.mdsal.binding.api.ReadTransaction;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.transportpce.common.OperationResult;
28 import org.opendaylight.transportpce.common.ResponseCodes;
29 import org.opendaylight.transportpce.common.StringConstants;
30 import org.opendaylight.transportpce.common.Timeouts;
31 import org.opendaylight.transportpce.renderer.ModelMappingUtils;
32 import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
33 import org.opendaylight.transportpce.renderer.ServicePathInputData;
34 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
35 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingRollbackTask;
36 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingTask;
37 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupRollbackTask;
38 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupTask;
39 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.RollbackProcessor;
40 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmInputBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmOutput;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerSetupInput;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerTurndownInputBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerTurndownOutput;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.TransportpceOlmService;
46 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements;
47 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteInput;
48 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutput;
49 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestInput;
50 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutput;
51 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSp;
52 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSpBuilder;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
55 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
56 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.ServicePathNotificationTypes;
57 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.service.path.PathDescription;
58 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
60 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
61 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.get.pm.input.ResourceIdentifierBuilder;
62 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.renderer.input.Nodes;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
69 public class RendererServiceOperationsImpl implements RendererServiceOperations {
71 private static final Logger LOG = LoggerFactory.getLogger(RendererServiceOperationsImpl.class);
72 private static final String FAILED = "Failed";
73 private static final String OPERATION_FAILED = "Operation Failed";
74 private static final String OPERATION_SUCCESSFUL = "Operation Successful";
75 private static final int NUMBER_OF_THREADS = 4;
77 private final DeviceRendererService deviceRenderer;
78 private final TransportpceOlmService olmService;
79 private final DataBroker dataBroker;
80 private final NotificationPublishService notificationPublishService;
81 private ListeningExecutorService executor;
82 private NetworkModelWavelengthService networkModelWavelengthService;
83 private ServiceRpcResultSp notification = null;
85 public RendererServiceOperationsImpl(DeviceRendererService deviceRenderer, TransportpceOlmService olmService,
86 DataBroker dataBroker, NetworkModelWavelengthService networkModelWavelengthService,
87 NotificationPublishService notificationPublishService) {
88 this.deviceRenderer = deviceRenderer;
89 this.olmService = olmService;
90 this.dataBroker = dataBroker;
91 this.networkModelWavelengthService = networkModelWavelengthService;
92 this.notificationPublishService = notificationPublishService;
93 this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUMBER_OF_THREADS));
96 private void sendNotifications(ServicePathNotificationTypes servicePathNotificationTypes, String serviceName,
97 RpcStatusEx rpcStatusEx, String message) {
98 this.notification = new ServiceRpcResultSpBuilder()
99 .setNotificationType(servicePathNotificationTypes)
100 .setServiceName(serviceName)
101 .setStatus(rpcStatusEx)
102 .setStatusMessage(message)
105 notificationPublishService.putNotification(this.notification);
106 } catch (InterruptedException e) {
107 LOG.info("notification offer rejected: ", e);
112 public ListenableFuture<ServiceImplementationRequestOutput>
113 serviceImplementation(ServiceImplementationRequestInput input) {
114 LOG.info("Calling service impl request {}", input.getServiceName());
115 return executor.submit(new Callable<ServiceImplementationRequestOutput>() {
118 public ServiceImplementationRequestOutput call() throws Exception {
119 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
120 RpcStatusEx.Pending, "Service compliant, submitting service implementation Request ...");
121 RollbackProcessor rollbackProcessor = new RollbackProcessor();
122 ServicePathInputData servicePathInputDataAtoZ = ModelMappingUtils
123 .rendererCreateServiceInputAToZ(input.getServiceName(), input.getPathDescription());
124 ServicePathInputData servicePathInputDataZtoA = ModelMappingUtils
125 .rendererCreateServiceInputZToA(input.getServiceName(), input.getPathDescription());
126 List<DeviceRenderingResult> renderingResults =
127 deviceRendering(rollbackProcessor, servicePathInputDataAtoZ, servicePathInputDataZtoA);
128 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
129 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
130 RpcStatusEx.Failed, "Device rendering was not successful! Rendering will be rolled back.");
131 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
133 ServicePowerSetupInput olmPowerSetupInputAtoZ =
134 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(0).getOlmList(), input);
135 ServicePowerSetupInput olmPowerSetupInputZtoA =
136 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(1).getOlmList(), input);
137 olmPowerSetup(rollbackProcessor, olmPowerSetupInputAtoZ, olmPowerSetupInputZtoA);
138 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
139 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
141 "OLM power setup was not successful! Rendering and OLM will be rolled back.");
142 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
144 // run service activation test twice - once on source node and once on
146 List<Nodes> nodes = servicePathInputDataAtoZ.getServicePathInput().getNodes();
147 Nodes sourceNode = nodes.get(0);
148 Nodes destNode = nodes.get(nodes.size() - 1);
151 if (sourceNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
152 srcNetworkTp = sourceNode.getDestTp();
154 srcNetworkTp = sourceNode.getSrcTp();
156 if (destNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
157 dstNetowrkTp = destNode.getDestTp();
159 dstNetowrkTp = destNode.getSrcTp();
161 if (!isServiceActivated(sourceNode.getNodeId(), srcNetworkTp)
162 || !isServiceActivated(destNode.getNodeId(), dstNetowrkTp)) {
163 rollbackProcessor.rollbackAll();
164 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
165 RpcStatusEx.Failed, "Service activation test failed.");
166 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
168 // If Service activation is success update Network ModelMappingUtils
169 networkModelWavelengthService.useWavelengths(input.getPathDescription());
170 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
171 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
172 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
178 @SuppressWarnings("checkstyle:IllegalCatch")
179 public OperationResult reserveResource(PathDescription pathDescription) {
182 LOG.info("Reserving resources in network model");
183 networkModelWavelengthService.useWavelengths(pathDescription);
184 } catch (Exception e) {
185 LOG.warn("Reserving resources in network model failed");
186 return OperationResult.failed("Resources reserve failed in network model");
188 return OperationResult.ok("Resources reserved successfully in network model");
191 @SuppressWarnings("checkstyle:IllegalCatch")
192 public OperationResult freeResource(PathDescription pathDescription) {
195 networkModelWavelengthService.freeWavelengths(pathDescription);
196 } catch (Exception e) {
197 return OperationResult.failed("Resources reserve failed in network model");
199 return OperationResult.ok("Resources reserved successfully in network model");
203 public ListenableFuture<ServiceDeleteOutput> serviceDelete(ServiceDeleteInput input) {
204 String serviceName = input.getServiceName();
205 LOG.info("Calling service delete request {}", input.getServiceName());
206 return executor.submit(new Callable<ServiceDeleteOutput>() {
209 public ServiceDeleteOutput call() throws Exception {
210 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
211 RpcStatusEx.Pending, "Service compliant, submitting service delete Request ...");
212 // Obtain path description
213 Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
214 PathDescription pathDescription;
215 if (pathDescriptionOpt.isPresent()) {
216 pathDescription = pathDescriptionOpt.get();
218 LOG.error("Unable to get path description for service {}!", serviceName);
219 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
220 RpcStatusEx.Failed, "Unable to get path description for service");
221 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
224 ServicePathInputData servicePathInputDataAtoZ =
225 ModelMappingUtils.rendererCreateServiceInputAToZ(serviceName, pathDescription);
226 ServicePathInputData servicePathInputDataZtoA =
227 ModelMappingUtils.rendererCreateServiceInputZToA(serviceName, pathDescription);
228 // OLM turn down power
230 LOG.debug("Turning down power on A-to-Z path");
231 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
232 input.getServiceName(), RpcStatusEx.Pending, "Turning down power on A-to-Z path");
233 ServicePowerTurndownOutput atozPowerTurndownOutput = olmPowerTurndown(servicePathInputDataAtoZ);
234 // TODO add some flag rather than string
235 if (FAILED.equals(atozPowerTurndownOutput.getResult())) {
236 LOG.error("Service power turndown failed on A-to-Z path for service {}!", serviceName);
237 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
238 input.getServiceName(), RpcStatusEx.Failed,
239 "Service power turndown failed on A-to-Z path for service");
240 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
243 LOG.debug("Turning down power on Z-to-A path");
244 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
245 RpcStatusEx.Pending, "Turning down power on Z-to-A path");
246 ServicePowerTurndownOutput ztoaPowerTurndownOutput = olmPowerTurndown(servicePathInputDataZtoA);
247 // TODO add some flag rather than string
248 if (FAILED.equals(ztoaPowerTurndownOutput.getResult())) {
249 LOG.error("Service power turndown failed on Z-to-A path for service {}!", serviceName);
250 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
251 input.getServiceName(), RpcStatusEx.Failed,
252 "Service power turndown failed on Z-to-A path for service");
253 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
256 } catch (InterruptedException | ExecutionException | TimeoutException e) {
257 LOG.error("Error while turning down power!", e);
258 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
261 // delete service path with renderer
262 LOG.debug("Deleting service path via renderer");
263 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
264 RpcStatusEx.Pending, "Deleting service path via renderer");
265 deviceRenderer.deleteServicePath(servicePathInputDataAtoZ.getServicePathInput());
266 deviceRenderer.deleteServicePath(servicePathInputDataZtoA.getServicePathInput());
267 networkModelWavelengthService.freeWavelengths(pathDescription);
268 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
269 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
270 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
277 private ServicePowerTurndownOutput olmPowerTurndown(ServicePathInputData servicePathInputData)
278 throws InterruptedException, ExecutionException, TimeoutException {
279 LOG.debug("Turning down power on A-to-Z path");
280 Future<RpcResult<ServicePowerTurndownOutput>> powerTurndownFuture = this.olmService.servicePowerTurndown(
281 new ServicePowerTurndownInputBuilder(servicePathInputData.getServicePathInput()).build());
282 return powerTurndownFuture.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).getResult();
285 private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
286 InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
287 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
288 ReadTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
290 LOG.debug("Getting path description for service {}", serviceName);
291 return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
292 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
293 } catch (InterruptedException | ExecutionException | TimeoutException e) {
294 LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
296 return Optional.empty();
300 private List<DeviceRenderingResult> deviceRendering(RollbackProcessor rollbackProcessor,
301 ServicePathInputData servicePathDataAtoZ, ServicePathInputData servicePathDataZtoA) {
302 LOG.info("Rendering devices A-Z");
303 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
304 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
305 "Rendering devices A-Z");
306 ListenableFuture<DeviceRenderingResult> atozrenderingFuture =
307 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataAtoZ,
308 ServicePathDirection.A_TO_Z));
310 LOG.info("Rendering devices Z-A");
311 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
312 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
313 "Rendering devices A-Z");
314 ListenableFuture<DeviceRenderingResult> ztoarenderingFuture =
315 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataZtoA,
316 ServicePathDirection.Z_TO_A));
317 ListenableFuture<List<DeviceRenderingResult>> renderingCombinedFuture =
318 Futures.allAsList(atozrenderingFuture, ztoarenderingFuture);
320 List<DeviceRenderingResult> renderingResults = new ArrayList<>(2);
322 LOG.info("Waiting for A-Z and Z-A device renderers ...");
323 renderingResults = renderingCombinedFuture.get(Timeouts.RENDERING_TIMEOUT, TimeUnit.MILLISECONDS);
324 } catch (InterruptedException | ExecutionException | TimeoutException e) {
325 LOG.warn("Device rendering was not successful! Rendering will be rolled back.", e);
326 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
327 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
328 "Device rendering was not successful! Rendering will be rolled back.");
329 //FIXME we can't do rollback here, because we don't have rendering results.
330 return renderingResults;
333 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask",
334 ! renderingResults.get(0).isSuccess(), renderingResults.get(0).getRenderedNodeInterfaces(),
335 this.deviceRenderer));
336 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask",
337 ! renderingResults.get(1).isSuccess(), renderingResults.get(1).getRenderedNodeInterfaces(),
338 this.deviceRenderer));
339 return renderingResults;
342 private void olmPowerSetup(RollbackProcessor rollbackProcessor, ServicePowerSetupInput powerSetupInputAtoZ,
343 ServicePowerSetupInput powerSetupInputZtoA) {
344 LOG.info("Olm power setup A-Z");
345 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
346 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup A-Z");
347 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureAtoZ
348 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputAtoZ));
350 LOG.info("OLM power setup Z-A");
351 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
352 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup Z-A");
353 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureZtoA
354 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputZtoA));
355 ListenableFuture<List<OLMRenderingResult>> olmFutures =
356 Futures.allAsList(olmPowerSetupFutureAtoZ, olmPowerSetupFutureZtoA);
358 List<OLMRenderingResult> olmResults;
360 LOG.info("Waiting for A-Z and Z-A OLM power setup ...");
361 olmResults = olmFutures.get(Timeouts.OLM_TIMEOUT, TimeUnit.MILLISECONDS);
362 } catch (InterruptedException | ExecutionException | TimeoutException e) {
363 LOG.warn("OLM power setup was not successful! Rendering and OLM will be rolled back.", e);
364 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
365 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending,
366 "OLM power setup was not successful! Rendering and OLM will be rolled back.");
367 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", true,
368 this.olmService, powerSetupInputAtoZ));
369 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", true,
370 this.olmService, powerSetupInputZtoA));
374 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", ! olmResults.get(0).isSuccess(),
375 this.olmService, powerSetupInputAtoZ));
376 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", ! olmResults.get(1).isSuccess(),
377 this.olmService, powerSetupInputZtoA));
380 private boolean isServiceActivated(String nodeId, String tpId) {
381 LOG.info("Starting service activation test on node {} and tp {}", nodeId, tpId);
382 for (int i = 0; i < 3; i++) {
383 List<Measurements> measurements = getMeasurements(nodeId, tpId);
384 if ((measurements != null) && verifyPreFecBer(measurements)) {
386 } else if (measurements == null) {
387 LOG.warn("Device {} is not reporting PreFEC on TP: {}", nodeId, tpId);
391 Thread.sleep(Timeouts.SERVICE_ACTIVATION_TEST_RETRY_TIME);
392 } catch (InterruptedException ex) {
393 Thread.currentThread().interrupt();
397 LOG.error("Service activation test failed on node {} and termination point {}!", nodeId, tpId);
401 private List<Measurements> getMeasurements(String nodeId, String tp) {
402 GetPmInputBuilder getPmIpBldr = new GetPmInputBuilder();
403 getPmIpBldr.setNodeId(nodeId);
404 getPmIpBldr.setGranularity(PmGranularity._15min);
405 ResourceIdentifierBuilder rsrcBldr = new ResourceIdentifierBuilder();
406 rsrcBldr.setResourceName(tp + "-OTU");
407 getPmIpBldr.setResourceIdentifier(rsrcBldr.build());
408 getPmIpBldr.setResourceType(ResourceTypeEnum.Interface);
411 Future<RpcResult<GetPmOutput>> getPmFuture = this.olmService.getPm(getPmIpBldr.build());
412 RpcResult<GetPmOutput> getPmRpcResult = getPmFuture.get();
413 GetPmOutput getPmOutput = getPmRpcResult.getResult();
414 if ((getPmOutput != null) && (getPmOutput.getNodeId() != null)) {
415 LOG.info("successfully finished calling OLM's get PM");
416 return getPmOutput.getMeasurements();
419 LOG.warn("OLM's get PM failed for node {} and tp {}", nodeId, tp);
422 } catch (ExecutionException | InterruptedException e) {
423 LOG.warn("Error occurred while getting PM for node {} and tp {}", nodeId, tp, e);
429 private boolean verifyPreFecBer(List<Measurements> measurements) {
430 double preFecCorrectedErrors = Double.MIN_VALUE;
431 double fecUncorrectableBlocks = Double.MIN_VALUE;
433 for (Measurements measurement : measurements) {
434 if (measurement.getPmparameterName().equals("preFECCorrectedErrors")) {
435 preFecCorrectedErrors = Double.parseDouble(measurement.getPmparameterValue());
437 if (measurement.getPmparameterName().equals("FECUncorrectableBlocks")) {
438 fecUncorrectableBlocks = Double.parseDouble(measurement.getPmparameterValue());
442 LOG.info("Measurements: preFECCorrectedErrors = {}; FECUncorrectableBlocks = {}", preFecCorrectedErrors,
443 fecUncorrectableBlocks);
445 if (fecUncorrectableBlocks > Double.MIN_VALUE) {
446 LOG.error("Data has uncorrectable errors, BER test failed");
449 double numOfBitsPerSecond = 112000000000d;
450 double threshold = 0.00002d;
451 double result = preFecCorrectedErrors / numOfBitsPerSecond;
452 LOG.info("PreFEC value is {}", Double.toString(result));
453 return result <= threshold;