Service-notification handling for Renderer
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / stub / StubrendererImpl.java
index 167525fe89ba416738b1559c909bc91808372730..91aefe82f19912927a85d1ddfcc275c964d1c090 100644 (file)
@@ -9,16 +9,39 @@
 
 package org.opendaylight.transportpce.servicehandler.stub;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.ResponseCodes;
+import org.opendaylight.transportpce.common.Timeouts;
+import org.opendaylight.transportpce.renderer.NetworkModelWavelengthService;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceDeleteOutputBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceImplementationRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSp;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.ServiceRpcResultSpBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopology;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev171017.service.rpc.result.sp.PathTopologyBuilder;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.RpcStatusEx;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.ServicePathNotificationTypes;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev171016.service.path.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
@@ -31,28 +54,64 @@ import org.slf4j.LoggerFactory;
  * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
  *
  */
-public final class StubrendererImpl {
+public class StubrendererImpl {
     /** Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(StubrendererImpl.class);
     /** check service sdnc-request-header compliancy. */
+    private final NotificationPublishService notificationPublishService;
+    private final NetworkModelWavelengthService networkModelWavelengthService;
+    private final DataBroker dataBroker;
+    private ServiceRpcResultSp notification = null;
 
-    private StubrendererImpl() {
-
+    public StubrendererImpl(NetworkModelWavelengthService networkModelWavelengthService, DataBroker dataBroker,
+            NotificationPublishService notificationPublishService) {
+        this.notificationPublishService = notificationPublishService;
+        this.networkModelWavelengthService = networkModelWavelengthService;
+        this.dataBroker = dataBroker;
     }
 
+    private void sendNotifications(Notification notif) {
+        try {
+            notificationPublishService.putNotification(notif);
+        } catch (InterruptedException e) {
+            LOG.info("notification offer rejected : ", e.getMessage());
+        }
+    }
 
-    public static ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
+    public ListenableFuture<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
         LOG.info("ServiceDelete request ...");
+        String serviceName = input.getServiceName();
         String message = "";
         String responseCode = null;
+        notification = new ServiceRpcResultSpBuilder().setNotificationType(ServicePathNotificationTypes.ServiceDelete)
+                .setServiceName(serviceName).setStatus(RpcStatusEx.Pending)
+                .setStatusMessage("Service compliant, submitting serviceDelete Request ...").build();
+        sendNotifications(notification);
         try {
-            LOG.info("Wait for 1s til beginning the Renderer serviceDelete request");
-            Thread.sleep(1000); //sleep for 1s
+            LOG.info("Wait for 10s til beginning the Renderer serviceDelete request");
+            Thread.sleep(10000); // sleep for 1s
         } catch (InterruptedException e) {
             message = "deleting service failed !";
             LOG.error("deleting service failed !", e);
             responseCode = ResponseCodes.RESPONSE_FAILED;
         }
+        // Obtain path description
+        Optional<PathDescription> pathDescriptionOpt = getPathDescriptionFromDatastore(serviceName);
+        PathDescription pathDescription;
+        if (pathDescriptionOpt.isPresent()) {
+            pathDescription = pathDescriptionOpt.get();
+            this.networkModelWavelengthService.freeWavelengths(pathDescription);
+            responseCode = ResponseCodes.RESPONSE_OK;
+            message = "service deleted !";
+        } else {
+            LOG.error("failed to get pathDescription for service : {}", serviceName);
+            responseCode = ResponseCodes.RESPONSE_FAILED;
+            message = "failed to get pathDescription for service : " + serviceName;
+        }
+        notification = new ServiceRpcResultSpBuilder().setNotificationType(ServicePathNotificationTypes.ServiceDelete)
+                .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
+                .setStatusMessage("Service deleted").build();
+        sendNotifications(notification);
         responseCode = ResponseCodes.RESPONSE_OK;
         ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder()
                 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
@@ -65,19 +124,32 @@ public final class StubrendererImpl {
         return RpcResultBuilder.success(output).buildFuture();
     }
 
-    public static ListenableFuture<RpcResult<ServiceImplementationRequestOutput>>
+    public ListenableFuture<RpcResult<ServiceImplementationRequestOutput>>
         serviceImplementation(ServiceImplementationRequestInput input) {
         LOG.info("serviceImplementation request ...");
         String message = "";
         String responseCode = null;
+        notification = new ServiceRpcResultSpBuilder()
+                .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
+                .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending)
+                .setStatusMessage("Service compliant, submitting serviceImplementation Request ...").build();
+        sendNotifications(notification);
         try {
-            LOG.info("Wait for 1s til beginning the Renderer serviceDelete request");
-            Thread.sleep(1000); //sleep for 1s
+            LOG.info("Wait for 10s til beginning the Renderer serviceImplementation request");
+            Thread.sleep(10000); // sleep for 1s
         } catch (InterruptedException e) {
             message = "implementing service failed !";
             LOG.error(message);
             responseCode = ResponseCodes.RESPONSE_FAILED;
         }
+        this.networkModelWavelengthService.useWavelengths(input.getPathDescription());
+        message = "service implemented !";
+        PathTopology pathTopology = new PathTopologyBuilder().build();
+        notification = new ServiceRpcResultSpBuilder()
+                .setNotificationType(ServicePathNotificationTypes.ServiceImplementationRequest)
+                .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
+                .setStatusMessage("Service implemented").setPathTopology(pathTopology).build();
+        sendNotifications(notification);
         responseCode = ResponseCodes.RESPONSE_OK;
         ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder()
                 .setAckFinalIndicator(ResponseCodes.FINAL_ACK_YES)
@@ -89,4 +161,19 @@ public final class StubrendererImpl {
                 .build();
         return RpcResultBuilder.success(output).buildFuture();
     }
+
+    private Optional<PathDescription> getPathDescriptionFromDatastore(String serviceName) {
+        InstanceIdentifier<PathDescription> pathDescriptionIID = InstanceIdentifier.create(ServicePathList.class)
+                .child(ServicePaths.class, new ServicePathsKey(serviceName)).child(PathDescription.class);
+        ReadOnlyTransaction pathDescReadTx = this.dataBroker.newReadOnlyTransaction();
+        try {
+            LOG.debug("Getting path description for service {}", serviceName);
+            return pathDescReadTx.read(LogicalDatastoreType.OPERATIONAL, pathDescriptionIID)
+                    .get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            LOG.warn("Exception while getting path description from datastore {} for service {}!", pathDescriptionIID,
+                    serviceName, e);
+            return Optional.absent();
+        }
+    }
 }