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.base.Optional;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.ListeningExecutorService;
14 import com.google.common.util.concurrent.MoreExecutors;
16 import java.util.ArrayList;
17 import java.util.List;
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.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
27 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.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.rev171016.RpcStatusEx;
58 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.ServicePathNotificationTypes;
59 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.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.rev170907.olm.get.pm.input.ResourceIdentifierBuilder;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev170907.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 Logger LOG = LoggerFactory.getLogger(RendererServiceOperationsImpl.class);
74 private static final String FAILED = "Failed";
75 private static final String OPERATION_FAILED = "Operation Failed";
76 private static final String OPERATION_SUCCESSFUL = "Operation Successful";
77 private static final int NUMBER_OF_THREADS = 4;
79 private final DeviceRendererService deviceRenderer;
80 private final TransportpceOlmService olmService;
81 private final DataBroker dataBroker;
82 private final NotificationPublishService notificationPublishService;
83 private ListeningExecutorService executor;
84 private NetworkModelWavelengthService networkModelWavelengthService;
85 private ServiceRpcResultSp notification = null;
87 public RendererServiceOperationsImpl(DeviceRendererService deviceRenderer, TransportpceOlmService olmService,
88 DataBroker dataBroker, NetworkModelWavelengthService networkModelWavelengthService,
89 NotificationPublishService notificationPublishService) {
90 this.deviceRenderer = deviceRenderer;
91 this.olmService = olmService;
92 this.dataBroker = dataBroker;
93 this.networkModelWavelengthService = networkModelWavelengthService;
94 this.notificationPublishService = notificationPublishService;
95 this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUMBER_OF_THREADS));
98 private void sendNotifications(ServicePathNotificationTypes servicePathNotificationTypes, String serviceName,
99 RpcStatusEx rpcStatusEx, String message) {
100 this.notification = new ServiceRpcResultSpBuilder()
101 .setNotificationType(servicePathNotificationTypes)
102 .setServiceName(serviceName)
103 .setStatus(rpcStatusEx)
104 .setStatusMessage(message)
107 notificationPublishService.putNotification(this.notification);
108 } catch (InterruptedException e) {
109 LOG.info("notification offer rejected : ", e.getMessage());
114 public ServiceImplementationRequestOutput serviceImplementation(ServiceImplementationRequestInput input) {
115 LOG.info("Calling service impl request {} {}", input.getServiceName());
116 RollbackProcessor rollbackProcessor = new RollbackProcessor();
118 ServicePathInputData servicePathInputDataAtoZ
119 = ModelMappingUtils.rendererCreateServiceInputAToZ(input.getServiceName(),
120 input.getPathDescription());
121 ServicePathInputData servicePathInputDataZtoA
122 = ModelMappingUtils.rendererCreateServiceInputZToA(input.getServiceName(),
123 input.getPathDescription());
124 List<DeviceRenderingResult> renderingResults = deviceRendering(rollbackProcessor, servicePathInputDataAtoZ,
125 servicePathInputDataZtoA);
126 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
127 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
130 ServicePowerSetupInput olmPowerSetupInputAtoZ = ModelMappingUtils.createServicePowerSetupInput(
131 renderingResults.get(0).getOlmList(), input);
132 ServicePowerSetupInput olmPowerSetupInputZtoA = ModelMappingUtils.createServicePowerSetupInput(
133 renderingResults.get(1).getOlmList(), input);
134 olmPowerSetup(rollbackProcessor, olmPowerSetupInputAtoZ, olmPowerSetupInputZtoA);
135 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
136 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
139 // run service activation test twice - once on source node and once on destination node
140 List<Nodes> nodes = servicePathInputDataAtoZ.getServicePathInput().getNodes();
141 Nodes sourceNode = nodes.get(0);
142 Nodes destNode = nodes.get(nodes.size() - 1);
147 if (sourceNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
148 srcNetworkTp = sourceNode.getDestTp();
150 srcNetworkTp = sourceNode.getSrcTp();
152 if (destNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
153 dstNetowrkTp = destNode.getDestTp();
155 dstNetowrkTp = destNode.getSrcTp();
158 if (!isServiceActivated(sourceNode.getNodeId(), srcNetworkTp)
159 || !isServiceActivated(destNode.getNodeId(), dstNetowrkTp)) {
160 rollbackProcessor.rollbackAll();
161 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
166 public ListenableFuture<ServiceImplementationRequestOutput>
167 serviceImplementation(ServiceImplementationRequestInput input) {
168 LOG.info("Calling service impl request {} {}", input.getServiceName());
169 return executor.submit(new Callable<ServiceImplementationRequestOutput>() {
172 public ServiceImplementationRequestOutput call() throws Exception {
173 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
174 RpcStatusEx.Pending, "Service compliant, submitting service implementation Request ...");
175 RollbackProcessor rollbackProcessor = new RollbackProcessor();
176 ServicePathInputData servicePathInputDataAtoZ = ModelMappingUtils
177 .rendererCreateServiceInputAToZ(input.getServiceName(), input.getPathDescription());
178 ServicePathInputData servicePathInputDataZtoA = ModelMappingUtils
179 .rendererCreateServiceInputZToA(input.getServiceName(), input.getPathDescription());
180 List<DeviceRenderingResult> renderingResults =
181 deviceRendering(rollbackProcessor, servicePathInputDataAtoZ, servicePathInputDataZtoA);
182 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
183 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
184 RpcStatusEx.Failed, "Device rendering was not successful! Rendering will be rolled back.");
185 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
187 ServicePowerSetupInput olmPowerSetupInputAtoZ =
188 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(0).getOlmList(), input);
189 ServicePowerSetupInput olmPowerSetupInputZtoA =
190 ModelMappingUtils.createServicePowerSetupInput(renderingResults.get(1).getOlmList(), input);
191 olmPowerSetup(rollbackProcessor, olmPowerSetupInputAtoZ, olmPowerSetupInputZtoA);
192 if (rollbackProcessor.rollbackAllIfNecessary() > 0) {
193 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
195 "OLM power setup was not successful! Rendering and OLM will be rolled back.");
196 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
198 // run service activation test twice - once on source node and once on
200 List<Nodes> nodes = servicePathInputDataAtoZ.getServicePathInput().getNodes();
201 Nodes sourceNode = nodes.get(0);
202 Nodes destNode = nodes.get(nodes.size() - 1);
205 //if (sourceNode.getDestTp().contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
206 if (sourceNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
207 srcNetworkTp = sourceNode.getDestTp();
209 srcNetworkTp = sourceNode.getSrcTp();
211 //if (destNode.getDestTp().contains(OpenRoadmInterfacesImpl.NETWORK_TOKEN)) {
212 if (destNode.getDestTp().contains(StringConstants.NETWORK_TOKEN)) {
213 dstNetowrkTp = destNode.getDestTp();
215 dstNetowrkTp = destNode.getSrcTp();
217 if (!isServiceActivated(sourceNode.getNodeId(), srcNetworkTp)
218 || !isServiceActivated(destNode.getNodeId(), dstNetowrkTp)) {
219 rollbackProcessor.rollbackAll();
220 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
221 RpcStatusEx.Failed, "Service activation test failed.");
222 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_FAILED, OPERATION_FAILED);
224 // If Service activation is success update Network ModelMappingUtils
225 networkModelWavelengthService.useWavelengths(input.getPathDescription());
226 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest, input.getServiceName(),
227 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
228 return ModelMappingUtils.createServiceImplResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
234 @SuppressWarnings("checkstyle:IllegalCatch")
235 public OperationResult reserveResource(PathDescription pathDescription) {
238 LOG.info("Reserving resources in network model");
239 networkModelWavelengthService.useWavelengths(pathDescription);
240 } catch (Exception e) {
241 LOG.warn("Reserving resources in network model failed");
242 return OperationResult.failed("Resources reserve failed in network model");
244 return OperationResult.ok("Resources reserved successfully in network model");
247 @SuppressWarnings("checkstyle:IllegalCatch")
248 public OperationResult freeResource(PathDescription pathDescription) {
251 networkModelWavelengthService.freeWavelengths(pathDescription);
252 } catch (Exception e) {
253 return OperationResult.failed("Resources reserve failed in network model");
255 return OperationResult.ok("Resources reserved successfully in network model");
259 public ListenableFuture<ServiceDeleteOutput> serviceDelete(ServiceDeleteInput input) {
260 String serviceName = input.getServiceName();
261 LOG.info("Calling service delete request {} {}", input.getServiceName());
262 return executor.submit(new Callable<ServiceDeleteOutput>() {
265 public ServiceDeleteOutput call() throws Exception {
266 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
267 RpcStatusEx.Pending, "Service compliant, submitting service delete Request ...");
268 // Obtain path description
269 Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
270 PathDescription pathDescription;
271 if (pathDescriptionOpt.isPresent()) {
272 pathDescription = pathDescriptionOpt.get();
274 LOG.error("Unable to get path description for service {}!", serviceName);
275 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
276 RpcStatusEx.Failed, "Unable to get path description for service");
277 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
280 ServicePathInputData servicePathInputDataAtoZ =
281 ModelMappingUtils.rendererCreateServiceInputAToZ(serviceName, pathDescription);
282 ServicePathInputData servicePathInputDataZtoA =
283 ModelMappingUtils.rendererCreateServiceInputZToA(serviceName, pathDescription);
284 // OLM turn down power
286 LOG.debug("Turning down power on A-to-Z path");
287 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
288 input.getServiceName(), RpcStatusEx.Pending, "Turning down power on A-to-Z path");
289 ServicePowerTurndownOutput atozPowerTurndownOutput = olmPowerTurndown(servicePathInputDataAtoZ);
290 // TODO add some flag rather than string
291 if (FAILED.equals(atozPowerTurndownOutput.getResult())) {
292 LOG.error("Service power turndown failed on A-to-Z path for service {}!", serviceName);
293 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
294 input.getServiceName(), RpcStatusEx.Failed,
295 "Service power turndown failed on A-to-Z path for service");
296 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
299 LOG.debug("Turning down power on Z-to-A path");
300 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
301 RpcStatusEx.Pending, "Turning down power on Z-to-A path");
302 ServicePowerTurndownOutput ztoaPowerTurndownOutput = olmPowerTurndown(servicePathInputDataZtoA);
303 // TODO add some flag rather than string
304 if (FAILED.equals(ztoaPowerTurndownOutput.getResult())) {
305 LOG.error("Service power turndown failed on Z-to-A path for service {}!", serviceName);
306 sendNotifications(ServicePathNotificationTypes.ServiceDelete,
307 input.getServiceName(), RpcStatusEx.Failed,
308 "Service power turndown failed on Z-to-A path for service");
309 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
312 } catch (InterruptedException | ExecutionException | TimeoutException e) {
313 LOG.error("Error while turning down power!", e);
314 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_FAILED,
317 // delete service path with renderer
318 LOG.debug("Deleting service path via renderer");
319 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
320 RpcStatusEx.Pending, "Deleting service path via renderer");
321 deviceRenderer.deleteServicePath(servicePathInputDataAtoZ.getServicePathInput());
322 deviceRenderer.deleteServicePath(servicePathInputDataZtoA.getServicePathInput());
323 networkModelWavelengthService.freeWavelengths(pathDescription);
324 sendNotifications(ServicePathNotificationTypes.ServiceDelete, input.getServiceName(),
325 RpcStatusEx.Successful, OPERATION_SUCCESSFUL);
326 return ModelMappingUtils.createServiceDeleteResponse(ResponseCodes.RESPONSE_OK, OPERATION_SUCCESSFUL);
333 private ServicePowerTurndownOutput olmPowerTurndown(ServicePathInputData servicePathInputData)
334 throws InterruptedException, ExecutionException, TimeoutException {
335 LOG.debug("Turning down power on A-to-Z path");
336 Future<RpcResult<ServicePowerTurndownOutput>> powerTurndownFuture = this.olmService.servicePowerTurndown(
337 new ServicePowerTurndownInputBuilder(servicePathInputData.getServicePathInput()).build());
338 return powerTurndownFuture.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS).getResult();
341 private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
342 InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
343 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
344 ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
346 LOG.debug("Getting path description for service {}", serviceName);
347 return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
348 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
349 } catch (InterruptedException | ExecutionException | TimeoutException e) {
350 LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
352 return Optional.absent();
356 private List<DeviceRenderingResult> deviceRendering(RollbackProcessor rollbackProcessor,
357 ServicePathInputData servicePathDataAtoZ, ServicePathInputData servicePathDataZtoA) {
358 LOG.info("Rendering devices A-Z");
359 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
360 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
361 "Rendering devices A-Z");
362 ListenableFuture<DeviceRenderingResult> atozrenderingFuture =
363 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataAtoZ,
364 ServicePathDirection.A_TO_Z));
366 LOG.info("Rendering devices Z-A");
367 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
368 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
369 "Rendering devices A-Z");
370 ListenableFuture<DeviceRenderingResult> ztoarenderingFuture =
371 this.executor.submit(new DeviceRenderingTask(this.deviceRenderer, servicePathDataZtoA,
372 ServicePathDirection.Z_TO_A));
373 ListenableFuture<List<DeviceRenderingResult>> renderingCombinedFuture =
374 Futures.allAsList(atozrenderingFuture, ztoarenderingFuture);
376 List<DeviceRenderingResult> renderingResults = new ArrayList<>(2);
378 LOG.info("Waiting for A-Z and Z-A device renderers ...");
379 renderingResults = renderingCombinedFuture.get(Timeouts.RENDERING_TIMEOUT, TimeUnit.MILLISECONDS);
380 } catch (InterruptedException | ExecutionException | TimeoutException e) {
381 LOG.warn("Device rendering was not successful! Rendering will be rolled back.", e);
382 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
383 servicePathDataAtoZ.getServicePathInput().getServiceName(), RpcStatusEx.Pending,
384 "Device rendering was not successful! Rendering will be rolled back.");
385 //FIXME we can't do rollback here, because we don't have rendering results.
386 //rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask", true));
387 //rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask", true));
388 return renderingResults;
391 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("AtoZDeviceTask",
392 ! renderingResults.get(0).isSuccess(), renderingResults.get(0).getRenderedNodeInterfaces(),
393 this.deviceRenderer));
394 rollbackProcessor.addTask(new DeviceRenderingRollbackTask("ZtoADeviceTask",
395 ! renderingResults.get(1).isSuccess(), renderingResults.get(1).getRenderedNodeInterfaces(),
396 this.deviceRenderer));
397 return renderingResults;
400 private void olmPowerSetup(RollbackProcessor rollbackProcessor, ServicePowerSetupInput powerSetupInputAtoZ,
401 ServicePowerSetupInput powerSetupInputZtoA) {
402 LOG.info("Olm power setup A-Z");
403 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
404 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup A-Z");
405 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureAtoZ
406 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputAtoZ));
408 LOG.info("OLM power setup Z-A");
409 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
410 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending, "Olm power setup Z-A");
411 ListenableFuture<OLMRenderingResult> olmPowerSetupFutureZtoA
412 = this.executor.submit(new OlmPowerSetupTask(this.olmService, powerSetupInputZtoA));
413 ListenableFuture<List<OLMRenderingResult>> olmFutures =
414 Futures.allAsList(olmPowerSetupFutureAtoZ, olmPowerSetupFutureZtoA);
416 List<OLMRenderingResult> olmResults;
418 LOG.info("Waiting for A-Z and Z-A OLM power setup ...");
419 olmResults = olmFutures.get(Timeouts.OLM_TIMEOUT, TimeUnit.MILLISECONDS);
420 } catch (InterruptedException | ExecutionException | TimeoutException e) {
421 LOG.warn("OLM power setup was not successful! Rendering and OLM will be rolled back.", e);
422 sendNotifications(ServicePathNotificationTypes.ServiceImplementationRequest,
423 powerSetupInputAtoZ.getServiceName(), RpcStatusEx.Pending,
424 "OLM power setup was not successful! Rendering and OLM will be rolled back.");
425 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", true,
426 this.olmService, powerSetupInputAtoZ));
427 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", true,
428 this.olmService, powerSetupInputZtoA));
432 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("AtoZOLMTask", ! olmResults.get(0).isSuccess(),
433 this.olmService, powerSetupInputAtoZ));
434 rollbackProcessor.addTask(new OlmPowerSetupRollbackTask("ZtoAOLMTask", ! olmResults.get(1).isSuccess(),
435 this.olmService, powerSetupInputZtoA));
438 private boolean isServiceActivated(String nodeId, String tpId) {
439 LOG.info("Starting service activation test on node {} and tp {}", nodeId, tpId);
440 for (int i = 0; i < 3; i++) {
441 List<Measurements> measurements = getMeasurements(nodeId, tpId);
442 if ((measurements != null) && verifyPreFecBer(measurements)) {
444 } else if (measurements == null) {
445 LOG.warn("Device {} is not reporting PreFEC on TP: {}", nodeId, tpId);
449 Thread.sleep(Timeouts.SERVICE_ACTIVATION_TEST_RETRY_TIME);
450 } catch (InterruptedException ex) {
451 Thread.currentThread().interrupt();
455 LOG.error("Service activation test failed on node {} and termination point {}!", nodeId, tpId);
459 private List<Measurements> getMeasurements(String nodeId, String tp) {
460 GetPmInputBuilder getPmIpBldr = new GetPmInputBuilder();
461 getPmIpBldr.setNodeId(nodeId);
462 getPmIpBldr.setGranularity(PmGranularity._15min);
463 ResourceIdentifierBuilder rsrcBldr = new ResourceIdentifierBuilder();
464 rsrcBldr.setResourceName(tp + "-OTU");
465 getPmIpBldr.setResourceIdentifier(rsrcBldr.build());
466 getPmIpBldr.setResourceType(ResourceTypeEnum.Interface);
469 Future<RpcResult<GetPmOutput>> getPmFuture = this.olmService.getPm(getPmIpBldr.build());
470 RpcResult<GetPmOutput> getPmRpcResult = getPmFuture.get();
471 GetPmOutput getPmOutput = getPmRpcResult.getResult();
472 if ((getPmOutput != null) && (getPmOutput.getNodeId() != null)) {
473 LOG.info("successfully finished calling OLM's get PM");
474 return getPmOutput.getMeasurements(); // may return null
476 LOG.warn("OLM's get PM failed for node {} and tp {}", nodeId, tp);
479 } catch (ExecutionException | InterruptedException e) {
480 LOG.warn("Error occurred while getting PM for node {} and tp {}", nodeId, tp, e);
486 private boolean verifyPreFecBer(List<Measurements> measurements) {
487 double preFecCorrectedErrors = Double.MIN_VALUE;
488 double fecUncorrectableBlocks = Double.MIN_VALUE;
490 for (Measurements measurement : measurements) {
491 if (measurement.getPmparameterName().equals("preFECCorrectedErrors")) {
492 preFecCorrectedErrors = Double.parseDouble(measurement.getPmparameterValue());
494 if (measurement.getPmparameterName().equals("FECUncorrectableBlocks")) {
495 fecUncorrectableBlocks = Double.parseDouble(measurement.getPmparameterValue());
499 LOG.info("Measurements: preFECCorrectedErrors = {}; FECUncorrectableBlocks = {}", preFecCorrectedErrors,
500 fecUncorrectableBlocks);
502 if (fecUncorrectableBlocks > Double.MIN_VALUE) {
503 LOG.error("Data has uncorrectable errors, BER test failed");
506 double numOfBitsPerSecond = 112000000000d;
507 double threshold = 0.00002d;
508 double result = preFecCorrectedErrors / numOfBitsPerSecond;
509 LOG.info("PreFEC value is {}", Double.toString(result));
510 return result <= threshold;