2 * Copyright © 2017 Orange, Inc. 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
10 package org.opendaylight.transportpce.servicehandler.stub;
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.ListenableFuture;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.TimeoutException;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.transportpce.common.ResponseCodes;
24 import org.opendaylight.transportpce.common.Timeouts;
25 import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
26 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteInput;
27 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutput;
28 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutputBuilder;
29 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestInput;
30 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutput;
31 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutputBuilder;
32 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSp;
33 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSpBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopology;
35 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopologyBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
37 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.RpcStatusEx;
38 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.ServicePathNotificationTypes;
39 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.service.path.PathDescription;
40 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
41 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
42 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.opendaylight.yangtools.yang.binding.Notification;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
46 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
53 * Class to implement StubrendererService.
54 * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
57 public class StubrendererImpl {
59 private static final Logger LOG = LoggerFactory.getLogger(StubrendererImpl.class);
60 /** check service sdnc-request-header compliancy. */
61 private final NotificationPublishService notificationPublishService;
62 private final NetworkModelWavelengthService networkModelWavelengthService;
63 private final DataBroker dataBroker;
64 private ServiceRpcResultSp notification = null;
66 public StubrendererImpl(NetworkModelWavelengthService networkModelWavelengthService, DataBroker dataBroker,
67 NotificationPublishService notificationPublishService) {
68 this.notificationPublishService = notificationPublishService;
69 this.networkModelWavelengthService = networkModelWavelengthService;
70 this.dataBroker = dataBroker;
73 private void sendNotifications(Notification notif) {
75 notificationPublishService.putNotification(notif);
76 } catch (InterruptedException e) {
77 LOG.info("notification offer rejected : ", e.getMessage());
81 public ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
82 LOG.info("ServiceDelete request ...");
83 String serviceName = input.getServiceName();
85 String responseCode = null;
86 notification = new ServiceRpcResultSpBuilder().setNotificationType(ServicePathNotificationTypes.ServiceDelete)
87 .setServiceName(serviceName).setStatus(RpcStatusEx.Pending)
88 .setStatusMessage("Service compliant, submitting serviceDelete Request ...").build();
89 sendNotifications(notification);
91 LOG.info("Wait for 10s til beginning the Renderer serviceDelete request");
92 Thread.sleep(10000); // sleep for 1s
93 } catch (InterruptedException e) {
94 message = "deleting service failed !";
95 LOG.error("deleting service failed !", e);
96 responseCode = ResponseCodes.RESPONSE_FAILED;
98 // Obtain path description
99 Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
100 PathDescription pathDescription;
101 if (pathDescriptionOpt.isPresent()) {
102 pathDescription = pathDescriptionOpt.get();
103 this.networkModelWavelengthService.freeWavelengths(pathDescription);
104 responseCode = ResponseCodes.RESPONSE_OK;
105 message = "service deleted !";
107 LOG.error("failed to get pathDescription for service : {}", serviceName);
108 responseCode = ResponseCodes.RESPONSE_FAILED;
109 message = "failed to get pathDescription for service : " + serviceName;
111 notification = new ServiceRpcResultSpBuilder().setNotificationType(ServicePathNotificationTypes.ServiceDelete)
112 .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
113 .setStatusMessage("Service deleted").build();
114 sendNotifications(notification);
115 responseCode = ResponseCodes.RESPONSE_OK;
116 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder()
117 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
118 .setRequestId(input.getServiceHandlerHeader().getRequestId())
119 .setResponseCode(responseCode)
120 .setResponseMessage(message);
121 ServiceDeleteOutput output = new ServiceDeleteOutputBuilder()
122 .setConfigurationResponseCommon(configurationResponseCommon.build())
124 return RpcResultBuilder.success(output).buildFuture();
127 public ListenableFuture<RpcResult<ServiceImplementationRequestOutput>>
128 serviceImplementation(ServiceImplementationRequestInput input) {
129 LOG.info("serviceImplementation request ...");
131 String responseCode = null;
132 notification = new ServiceRpcResultSpBuilder()
133 .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
134 .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending)
135 .setStatusMessage("Service compliant, submitting serviceImplementation Request ...").build();
136 sendNotifications(notification);
138 LOG.info("Wait for 10s til beginning the Renderer serviceImplementation request");
139 Thread.sleep(10000); // sleep for 1s
140 } catch (InterruptedException e) {
141 message = "implementing service failed !";
143 responseCode = ResponseCodes.RESPONSE_FAILED;
145 this.networkModelWavelengthService.useWavelengths(input.getPathDescription());
146 message = "service implemented !";
147 PathTopology pathTopology = new PathTopologyBuilder().build();
148 notification = new ServiceRpcResultSpBuilder()
149 .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
150 .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
151 .setStatusMessage("Service implemented").setPathTopology(pathTopology).build();
152 sendNotifications(notification);
153 responseCode = ResponseCodes.RESPONSE_OK;
154 ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder()
155 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
156 .setRequestId(input.getServiceHandlerHeader().getRequestId())
157 .setResponseCode(responseCode)
158 .setResponseMessage(message);
159 ServiceImplementationRequestOutput output = new ServiceImplementationRequestOutputBuilder()
160 .setConfigurationResponseCommon(configurationResponseCommon.build())
162 return RpcResultBuilder.success(output).buildFuture();
165 private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
166 InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
167 .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
168 ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
170 LOG.debug("Getting path description for service {}", serviceName);
171 return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
172 .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
173 } catch (InterruptedException | ExecutionException | TimeoutException e) {
174 LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
176 return Optional.absent();