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;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Optional;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Executors;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
27 import org.opendaylight.mdsal.binding.api.ReadTransaction;
28 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.transportpce.common.OperationResult;
30 import org.opendaylight.transportpce.common.ResponseCodes;
31 import org.opendaylight.transportpce.common.StringConstants;
32 import org.opendaylight.transportpce.common.Timeouts;
33 import org.opendaylight.transportpce.renderer.ModelMappingUtils;
34 import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
35 import org.opendaylight.transportpce.renderer.ServicePathInputData;
36 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
37 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingRollbackTask;
38 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.DeviceRenderingTask;
39 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupRollbackTask;
40 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.OlmPowerSetupTask;
41 import org.opendaylight.transportpce.renderer.provisiondevice.tasks.RollbackProcessor;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmInputBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.GetPmOutput;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerSetupInput;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerTurndownInputBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.ServicePowerTurndownOutput;
47 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.TransportpceOlmService;
48 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.olm.rev170418.get.pm.output.Measurements;
49 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteInput;
50 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutput;
51 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestInput;
52 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutput;
53 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSp;
54 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSpBuilder;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev161014.PmGranularity;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.resource.types.rev161014.ResourceTypeEnum;
57 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.RpcStatusEx;
58 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.ServicePathNotificationTypes;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.service.path.PathDescription;
60 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
61 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
62 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
63 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.get.pm.input.ResourceIdentifierBuilder;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.renderer.input.Nodes;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.common.RpcResult;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
71 public class RendererServiceOperationsImpl implements RendererServiceOperations {
73 private static final String DEVICE_RENDERING_ROLL_BACK_MSG =
74 "Device rendering was not successful! Rendering will be rolled back.";
75 private static final String OLM_ROLL_BACK_MSG =
76 "OLM power setup was not successful! Rendering and OLM will be rolled back.";
77 private static final String RENDERING_DEVICES_A_Z_MSG = "Rendering devices A-Z";
78 private static final String TURNING_DOWN_POWER_ON_A_TO_Z_PATH_MSG = "Turning down power on A-to-Z path";
79 private static final Logger LOG = LoggerFactory.getLogger(RendererServiceOperationsImpl.class);
80 private static final String FAILED = "Failed";
81 private static final String OPERATION_FAILED = "Operation Failed";
82 private static final String OPERATION_SUCCESSFUL = "Operation Successful";
83 private static final int NUMBER_OF_THREADS = 4;
85 private final DeviceRendererService deviceRenderer;
86 private final TransportpceOlmService olmService;
87 private final DataBroker dataBroker;
88 private final NotificationPublishService notificationPublishService;
89 private ListeningExecutorService executor;
90 private NetworkModelWavelengthService networkModelWavelengthService;
91 private ServiceRpcResultSp notification = null;
93 public RendererServiceOperationsImpl(DeviceRendererService deviceRenderer, TransportpceOlmService olmService,
94 DataBroker dataBroker, NetworkModelWavelengthService networkModelWavelengthService,
95 NotificationPublishService notificationPublishService) {
96 this.deviceRenderer = deviceRenderer;
97 this.olmService = olmService;
98 this.dataBroker = dataBroker;
99 this.networkModelWavelengthService = networkModelWavelengthService;
100 this.notificationPublishService = notificationPublishService;
101 this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUMBER_OF_THREADS));
104 private void sendNotifications(ServicePathNotificationTypes servicePathNotificationTypes, String serviceName,
105 RpcStatusEx rpcStatusEx, String message) {
106 this.notification = new ServiceRpcResultSpBuilder()
107 .setNotificationType(servicePathNotificationTypes)
108 .setServiceName(serviceName)
109 .setStatus(rpcStatusEx)
110 .setStatusMessage(message)
113 notificationPublishService.putNotification(this.notification);
114 } catch (InterruptedException e) {
115 LOG.info("notification offer rejected: ", e);
120 public ListenableFuture<ServiceImplementationRequestOutput>
121 serviceImplementation(ServiceImplementationRequestInput input) {
122 LOG.info("Calling service impl request {}", input.getServiceName());
123 return executor.submit(new Callable<ServiceImplementationRequestOutput>() {
126 public ServiceImplementationRequestOutput call() throws Exception {
127 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
128 RpcStatusEx.Pending, "Service compliant, submitting service implementation Request ...");
129 RollbackProcessor rollbackProcessor = new RollbackProcessor();
130 ServicePathInputData servicePathInputDataAtoZ = ModelMappingUtils
131 .rendererCreateServiceInputAToZ(input.getServiceName(), input.getPathDescription());
132 ServicePathInputData servicePathInputDataZtoA = ModelMappingUtils
133 .rendererCreateServiceInputZToA(input.getServiceName(), input.getPathDescription());
134 List<DeviceRenderingResult> renderingResults =
135 deviceRendering(rollbackProcessor, servicePathInputDataAtoZ, servicePathInputDataZtoA);
136 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
137 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
138 RpcStatusEx.Failed, DEVICE_RENDERING_ROLL_BACK_MSG);
139 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
141 ServicePowerSetupInput olmPowerSetupInputAtoZ =
142 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(0).getOlmList(), input);
143 ServicePowerSetupInput olmPowerSetupInputZtoA =
144 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(1).getOlmList(), input);
145 olmPowerSetup(rollbackProcessor, olmPowerSetupInputAtoZ, olmPowerSetupInputZtoA);
146 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
147 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
150 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
152 // run service activation test twice - once on source node and once on
154 List<Nodes> nodes = servicePathInputDataAtoZ.getServicePathInput().getNodes();
155 Nodes sourceNode = nodes.get(0);
156 Nodes destNode = nodes.get(nodes.size() - 1);
159 if (sourceNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
160 srcNetworkTp = sourceNode.getDestTp();
162 srcNetworkTp = sourceNode.getSrcTp();
164 if (destNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
165 dstNetowrkTp = destNode.getDestTp();
167 dstNetowrkTp = destNode.getSrcTp();
169 if (!isServiceActivated(sourceNode.getNodeId(), srcNetworkTp)
170 || !isServiceActivated(destNode.getNodeId(), dstNetowrkTp)) {
171 rollbackProcessor.rollbackAll();
172 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
173 RpcStatusEx.Failed, "Service activation test failed.");
174 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
176 // If Service activation is success update Network ModelMappingUtils
177 networkModelWavelengthService.useWavelengths(input.getPathDescription());
178 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
179 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
180 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
186 @SuppressWarnings("checkstyle:IllegalCatch")
187 public OperationResult reserveResource(PathDescription pathDescription) {
190 LOG.info("Reserving resources in network model");
191 networkModelWavelengthService.useWavelengths(pathDescription);
192 } catch (Exception e) {
193 LOG.warn("Reserving resources in network model failed");
194 return OperationResult.failed("Resources reserve failed in network model");
196 return OperationResult.ok("Resources reserved successfully in network model");
200 @SuppressWarnings("checkstyle:IllegalCatch")
201 public OperationResult freeResource(PathDescription pathDescription) {
204 networkModelWavelengthService.freeWavelengths(pathDescription);
205 } catch (Exception e) {
206 return OperationResult.failed("Resources reserve failed in network model");
208 return OperationResult.ok("Resources reserved successfully in network model");
212 public ListenableFuture<ServiceDeleteOutput> serviceDelete(ServiceDeleteInput input) {
213 String serviceName = input.getServiceName();
214 LOG.info("Calling service delete request {}", input.getServiceName());
215 return executor.submit(new Callable<ServiceDeleteOutput>() {
218 public ServiceDeleteOutput call() throws Exception {
219 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
220 RpcStatusEx.Pending, "Service compliant, submitting service delete Request ...");
221 // Obtain path description
222 Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
223 PathDescription pathDescription;
224 if (pathDescriptionOpt.isPresent()) {
225 pathDescription = pathDescriptionOpt.get();
227 LOG.error("Unable to get path description for service {}!", serviceName);
228 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
229 RpcStatusEx.Failed, "Unable to get path description for service");
230 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
233 ServicePathInputData servicePathInputDataAtoZ =
234 ModelMappingUtils.rendererCreateServiceInputAToZ(serviceName, pathDescription);
235 ServicePathInputData servicePathInputDataZtoA =
236 ModelMappingUtils.rendererCreateServiceInputZToA(serviceName, pathDescription);
237 // OLM turn down power
239 LOG.debug(TURNING_DOWN_POWER_ON_A_TO_Z_PATH_MSG);
240 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
241 input.getServiceName(), RpcStatusEx.Pending, TURNING_DOWN_POWER_ON_A_TO_Z_PATH_MSG);
242 ServicePowerTurndownOutput atozPowerTurndownOutput = olmPowerTurndown(servicePathInputDataAtoZ);
243 // TODO add some flag rather than string
244 if (FAILED.equals(atozPowerTurndownOutput.getResult())) {
245 LOG.error("Service power turndown failed on A-to-Z path for service {}!", serviceName);
246 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
247 input.getServiceName(), RpcStatusEx.Failed,
248 "Service power turndown failed on A-to-Z path for service");
249 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
252 LOG.debug("Turning down power on Z-to-A path");
253 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
254 RpcStatusEx.Pending, "Turning down power on Z-to-A path");
255 ServicePowerTurndownOutput ztoaPowerTurndownOutput = olmPowerTurndown(servicePathInputDataZtoA);
256 // TODO add some flag rather than string
257 if (FAILED.equals(ztoaPowerTurndownOutput.getResult())) {
258 LOG.error("Service power turndown failed on Z-to-A path for service {}!", serviceName);
259 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
260 input.getServiceName(), RpcStatusEx.Failed,
261 "Service power turndown failed on Z-to-A path for service");
262 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
265 } catch (InterruptedException | ExecutionException | TimeoutException e) {
266 LOG.error("Error while turning down power!", e);
267 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
270 // delete service path with renderer
271 LOG.debug("Deleting service path via renderer");
272 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
273 RpcStatusEx.Pending, "Deleting service path via renderer");
274 deviceRenderer.deleteServicePath(servicePathInputDataAtoZ.getServicePathInput());
275 deviceRenderer.deleteServicePath(servicePathInputDataZtoA.getServicePathInput());
276 networkModelWavelengthService.freeWavelengths(pathDescription);
277 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
278 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
279 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
286 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
287 value = "UPM_UNCALLED_PRIVATE_METHOD",
288 justification = "call in call() method")
289 private ServicePowerTurndownOutput olmPowerTurndown(ServicePathInputData servicePathInputData)
290 throws InterruptedException, ExecutionException, TimeoutException {
291 LOG.debug(TURNING_DOWN_POWER_ON_A_TO_Z_PATH_MSG);
292 Future<RpcResult<ServicePowerTurndownOutput>> powerTurndownFuture = this.olmService.servicePowerTurndown(
293 new ServicePowerTurndownInputBuilder(servicePathInputData.getServicePathInput()).build());
294 return powerTurndownFuture.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).getResult();
297 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
298 value = "UPM_UNCALLED_PRIVATE_METHOD",
299 justification = "call in call() method")
300 private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
301 InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
302 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
303 ReadTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
305 LOG.debug("Getting path description for service {}", serviceName);
306 return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
307 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
308 } catch (InterruptedException | ExecutionException | TimeoutException e) {
309 LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
311 return Optional.empty();
315 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
316 value = "UPM_UNCALLED_PRIVATE_METHOD",
317 justification = "call in call() method")
318 private List<DeviceRenderingResult> deviceRendering(RollbackProcessor rollbackProcessor,
319 ServicePathInputData servicePathDataAtoZ, ServicePathInputData servicePathDataZtoA) {
320 LOG.info(RENDERING_DEVICES_A_Z_MSG);
321 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
322 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
323 RENDERING_DEVICES_A_Z_MSG);
324 ListenableFuture<DeviceRenderingResult> atozrenderingFuture =
325 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataAtoZ,
326 ServicePathDirection.A_TO_Z));
328 LOG.info("Rendering devices Z-A");
329 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
330 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
331 RENDERING_DEVICES_A_Z_MSG);
332 ListenableFuture<DeviceRenderingResult> ztoarenderingFuture =
333 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataZtoA,
334 ServicePathDirection.Z_TO_A));
335 ListenableFuture<List<DeviceRenderingResult>> renderingCombinedFuture =
336 Futures.allAsList(atozrenderingFuture, ztoarenderingFuture);
338 List<DeviceRenderingResult> renderingResults = new ArrayList<>(2);
340 LOG.info("Waiting for A-Z and Z-A device renderers ...");
341 renderingResults = renderingCombinedFuture.get(Timeouts.RENDERING_TIMEOUT, TimeUnit.MILLISECONDS);
342 } catch (InterruptedException | ExecutionException | TimeoutException e) {
343 LOG.warn(DEVICE_RENDERING_ROLL_BACK_MSG, e);
344 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
345 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
346 DEVICE_RENDERING_ROLL_BACK_MSG);
347 //FIXME we can't do rollback here, because we don't have rendering results.
348 return renderingResults;
351 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask",
352 ! renderingResults.get(0).isSuccess(), renderingResults.get(0).getRenderedNodeInterfaces(),
353 this.deviceRenderer));
354 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask",
355 ! renderingResults.get(1).isSuccess(), renderingResults.get(1).getRenderedNodeInterfaces(),
356 this.deviceRenderer));
357 return renderingResults;
360 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
361 value = "UPM_UNCALLED_PRIVATE_METHOD",
362 justification = "call in call() method")
363 private void olmPowerSetup(RollbackProcessor rollbackProcessor, ServicePowerSetupInput powerSetupInputAtoZ,
364 ServicePowerSetupInput powerSetupInputZtoA) {
365 LOG.info("Olm power setup A-Z");
366 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
367 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup A-Z");
368 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureAtoZ
369 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputAtoZ));
371 LOG.info("OLM power setup Z-A");
372 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
373 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup Z-A");
374 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureZtoA
375 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputZtoA));
376 ListenableFuture<List<OLMRenderingResult>> olmFutures =
377 Futures.allAsList(olmPowerSetupFutureAtoZ, olmPowerSetupFutureZtoA);
379 List<OLMRenderingResult> olmResults;
381 LOG.info("Waiting for A-Z and Z-A OLM power setup ...");
382 olmResults = olmFutures.get(Timeouts.OLM_TIMEOUT, TimeUnit.MILLISECONDS);
383 } catch (InterruptedException | ExecutionException | TimeoutException e) {
384 LOG.warn(OLM_ROLL_BACK_MSG, e);
385 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
386 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending,
388 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", true,
389 this.olmService, powerSetupInputAtoZ));
390 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", true,
391 this.olmService, powerSetupInputZtoA));
395 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", ! olmResults.get(0).isSuccess(),
396 this.olmService, powerSetupInputAtoZ));
397 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", ! olmResults.get(1).isSuccess(),
398 this.olmService, powerSetupInputZtoA));
401 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
402 value = "UPM_UNCALLED_PRIVATE_METHOD",
403 justification = "call in call() method")
404 private boolean isServiceActivated(String nodeId, String tpId) {
405 LOG.info("Starting service activation test on node {} and tp {}", nodeId, tpId);
406 for (int i = 0; i < 3; i++) {
407 List<Measurements> measurements = getMeasurements(nodeId, tpId);
408 if ((measurements != null) && verifyPreFecBer(measurements)) {
410 } else if (measurements == null) {
411 LOG.warn("Device {} is not reporting PreFEC on TP: {}", nodeId, tpId);
415 Thread.sleep(Timeouts.SERVICE_ACTIVATION_TEST_RETRY_TIME);
416 } catch (InterruptedException ex) {
417 Thread.currentThread().interrupt();
421 LOG.error("Service activation test failed on node {} and termination point {}!", nodeId, tpId);
425 private List<Measurements> getMeasurements(String nodeId, String tp) {
426 GetPmInputBuilder getPmIpBldr = new GetPmInputBuilder();
427 getPmIpBldr.setNodeId(nodeId);
428 getPmIpBldr.setGranularity(PmGranularity._15min);
429 ResourceIdentifierBuilder rsrcBldr = new ResourceIdentifierBuilder();
430 rsrcBldr.setResourceName(tp + "-OTU");
431 getPmIpBldr.setResourceIdentifier(rsrcBldr.build());
432 getPmIpBldr.setResourceType(ResourceTypeEnum.Interface);
435 Future<RpcResult<GetPmOutput>> getPmFuture = this.olmService.getPm(getPmIpBldr.build());
436 RpcResult<GetPmOutput> getPmRpcResult = getPmFuture.get();
437 GetPmOutput getPmOutput = getPmRpcResult.getResult();
438 if ((getPmOutput != null) && (getPmOutput.getNodeId() != null)) {
439 LOG.info("successfully finished calling OLM's get PM");
440 return getPmOutput.getMeasurements();
443 LOG.warn("OLM's get PM failed for node {} and tp {}", nodeId, tp);
446 } catch (ExecutionException | InterruptedException e) {
447 LOG.warn("Error occurred while getting PM for node {} and tp {}", nodeId, tp, e);
453 private boolean verifyPreFecBer(List<Measurements> measurements) {
454 double preFecCorrectedErrors = Double.MIN_VALUE;
455 double fecUncorrectableBlocks = Double.MIN_VALUE;
457 for (Measurements measurement : measurements) {
458 if (measurement.getPmparameterName().equals("preFECCorrectedErrors")) {
459 preFecCorrectedErrors = Double.parseDouble(measurement.getPmparameterValue());
461 if (measurement.getPmparameterName().equals("FECUncorrectableBlocks")) {
462 fecUncorrectableBlocks = Double.parseDouble(measurement.getPmparameterValue());
466 LOG.info("Measurements: preFECCorrectedErrors = {}; FECUncorrectableBlocks = {}", preFecCorrectedErrors,
467 fecUncorrectableBlocks);
469 if (fecUncorrectableBlocks > Double.MIN_VALUE) {
470 LOG.error("Data has uncorrectable errors, BER test failed");
473 double numOfBitsPerSecond = 112000000000d;
474 double threshold = 0.00002d;
475 double result = preFecCorrectedErrors / numOfBitsPerSecond;
476 LOG.info("PreFEC value is {}", Double.toString(result));
477 return result <= threshold;