ONOS-7827 TAPI Phot. OpticalConnectivity intent.

Change-Id: I34bcc2a2bce4dbd6cca5c99f96e78cee0a53d690
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
index b585506..daf31e1 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
@@ -22,8 +22,9 @@
 
 import java.util.concurrent.atomic.AtomicReference;
 import org.onosproject.config.FailedException;
-import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.odtn.TapiResolver;
+import org.onosproject.odtn.TapiConnectivityConfig;
+import org.onosproject.odtn.TapiConnectivityService;
 import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
 import org.onosproject.odtn.utils.tapi.DcsBasedTapiObjectRefFactory;
 import org.onosproject.odtn.utils.tapi.TapiCepPair;
@@ -32,6 +33,11 @@
 import org.onosproject.odtn.utils.tapi.TapiCepRefHandler;
 import org.onosproject.odtn.utils.tapi.TapiConnectionHandler;
 
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20181210.tapiconnectivity.connectivitycontext.DefaultConnection;
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20181210.tapiconnectivity.connection.ConnectionEndPoint;
+
+import org.onosproject.net.ConnectPoint;
+
 import org.onosproject.odtn.utils.tapi.TapiNepRef;
 import org.onosproject.odtn.utils.tapi.TapiRouteHandler;
 import org.slf4j.Logger;
@@ -39,55 +45,108 @@
 
 import static org.onlab.osgi.DefaultServiceDirectory.getService;
 
+
+
 /**
  * DCS-dependent Tapi connection manager implementation.
  */
 public final class DcsBasedTapiConnectionManager implements TapiConnectionManager {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
+
     protected TapiPathComputer connectionController;
     private TapiResolver resolver;
-    private NetworkConfigService netcfgService;
+    private TapiConnectivityService processor;
 
     private List<DcsBasedTapiConnectionManager> connectionManagerList = new ArrayList<>();
     private TapiConnection connection = null;
     private TapiConnectionHandler connectionHandler = TapiConnectionHandler.create();
     private Operation op = null;
 
-
     enum Operation {
         CREATE,
         DELETE
     }
 
     private DcsBasedTapiConnectionManager() {
+        connectionController = DefaultTapiPathComputer.create();
+        resolver = getService(TapiResolver.class);
+        processor = getService(TapiConnectivityService.class);
     }
 
     public static DcsBasedTapiConnectionManager create() {
-        DcsBasedTapiConnectionManager self = new DcsBasedTapiConnectionManager();
-        self.connectionController = DefaultTapiPathComputer.create();
-        self.resolver = getService(TapiResolver.class);
-        self.netcfgService = getService(NetworkConfigService.class);
-        return self;
+        return new DcsBasedTapiConnectionManager();
     }
 
+
     @Override
     public TapiConnectionHandler createConnection(TapiNepPair neps) {
 
         // Calculate route
         TapiConnection connection = connectionController.pathCompute(neps);
-        log.info("Calculated path: {}", connection);
-
+        log.debug("Calculated path: {}", connection);
         createConnectionRecursively(connection);
+
+        /*
+         * RCAS Create Intent: Assume that if the result of the pathCompute is flat
+         * and there are no lower connections, it has to be mapped to an intent
+         * It is a connection between line ports (OCh) with an OpticalConnectivity
+         * Intent.
+         */
+        if (connection.getLowerConnections().isEmpty()) {
+            TapiNepRef left  = neps.left();
+            TapiNepRef right = neps.right();
+            ConnectPoint leftConnectPoint = left.getConnectPoint();
+            ConnectPoint rightConnectPoint = right.getConnectPoint();
+            log.debug("Creating Intent from {} to {} {}",
+                leftConnectPoint,
+                rightConnectPoint,
+                connectionHandler.getId());
+            notifyTapiConnectivityChange(connectionHandler.getId().toString(),
+                leftConnectPoint,
+                rightConnectPoint,
+                true);
+        }
         return connectionHandler;
     }
 
     @Override
     public void deleteConnection(TapiConnectionHandler connectionHandler) {
+        // Retrieve the target to be deleted (right now we have the uuid)
+        connectionHandler.read();
 
+        // Remove Intent if exists
+        if (connectionHandler.getLowerConnections().isEmpty()) {
+            // Connection object
+            DefaultConnection connection = connectionHandler.getModelObject();
+            // These are two connection.ConnectionEndpoint (Actually Refs, mainly UUID)
+            ConnectionEndPoint cepLeft  = connection.connectionEndPoint().get(0);
+            ConnectionEndPoint cepRight = connection.connectionEndPoint().get(1);
+
+            TapiNepRef left = TapiNepRef.create(
+                    cepLeft.topologyUuid().toString(),
+                    cepLeft.nodeUuid().toString(),
+                    cepLeft.nodeEdgePointUuid().toString());
+
+            TapiNepRef right = TapiNepRef.create(
+                    cepRight.topologyUuid().toString(),
+                    cepRight.nodeUuid().toString(),
+                    cepRight.nodeEdgePointUuid().toString());
+
+            // update with latest data in DCS
+            left = resolver.getNepRef(left);
+            right = resolver.getNepRef(right);
+            log.debug("Removing intent connection: {}", connection);
+            notifyTapiConnectivityChange(
+                connectionHandler.getId().toString(),
+                left.getConnectPoint(),
+                right.getConnectPoint(),
+                false);
+        }
         deleteConnectionRecursively(connectionHandler);
     }
 
+
     @Override
     public void apply() {
         connectionManagerList.forEach(DcsBasedTapiConnectionManager::apply);
@@ -106,6 +165,8 @@
         }
     }
 
+
+
     /**
      * Emit NetworkConfig event with parameters for device config,
      * to notify configuration change to device drivers.
@@ -137,6 +198,16 @@
         eventEmitter.emit(line.get(), client.get(), enable);
     }
 
+
+
+    /**
+     * Request Application to setup / release Intent.
+     */
+    private void notifyTapiConnectivityChange(String uuid, ConnectPoint left, ConnectPoint right, boolean enable) {
+        TapiConnectivityConfig cfg = new TapiConnectivityConfig(uuid, left, right, enable);
+        processor.processTapiEvent(cfg);
+    }
+
     /**
      * Generate TAPI connection and its under connections recursively
      * and add them to creation queue.
@@ -179,10 +250,7 @@
         op = Operation.DELETE;
         connectionManagerList.clear();
 
-        // read target to be deleted
-        connectionHandler.read();
         log.info("model: {}", connectionHandler.getModelObject());
-
         this.connection = TapiConnection.create(
                 TapiCepPair.create(
                         DcsBasedTapiObjectRefFactory.create(connectionHandler.getCeps().get(0)),
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
index 82c8ee2..d5f2962 100755
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
@@ -65,6 +65,7 @@
         resolver = getService(TapiResolver.class);
     }
 
+
     /**
      * Service interface of createConnectivityService.
      *
@@ -89,19 +90,21 @@
             List<TapiNepRef> nepRefs = input.getSips().stream()
                     .map(sipId -> resolver.getNepRef(sipId))
                     .collect(Collectors.toList());
-            // for test
-//            Map<String, String> filter = new HashMap<>();
-//            filter.put(ODTN_PORT_TYPE, OdtnDeviceDescriptionDiscovery.OdtnPortType.CLIENT.value());
-//            List<TapiNepRef> nepRefs = resolver.getNepRefs(filter);
 
             // setup connections
             TapiNepPair neps = TapiNepPair.create(nepRefs.get(0), nepRefs.get(1));
-            DcsBasedTapiConnectionManager connectionManager = DcsBasedTapiConnectionManager.create();
-            connectionManager.createConnection(neps);
 
-            // setup connectivity service
+            // Allocate a connectivity Service
             TapiConnectivityServiceHandler connectivityServiceHandler = TapiConnectivityServiceHandler.create();
-            connectivityServiceHandler.addConnection(connectionManager.getConnectionHandler().getModelObject().uuid());
+
+            // This connectivity service will be supported over a single end-to-end connection
+            // Allocate a manager for that connection
+            DcsBasedTapiConnectionManager connectionManager = DcsBasedTapiConnectionManager.create();
+            TapiConnectionHandler connectionHandler = connectionManager.createConnection(neps);
+
+            // Add the supporting connection uuid to the service
+            connectivityServiceHandler.addConnection(connectionHandler.getModelObject().uuid());
+
             neps.stream()
                     .map(nepRef -> TapiSepHandler.create().setSip(nepRef.getSipId()))
                     .forEach(sepBuilder -> {
@@ -113,7 +116,9 @@
             connectivityServiceHandler.add();
 
             // output
-            TapiCreateConnectivityOutputHandler output = TapiCreateConnectivityOutputHandler.create()
+            TapiCreateConnectivityOutputHandler output =
+                TapiCreateConnectivityOutputHandler
+                    .create()
                     .addService(connectivityServiceHandler.getModelObject());
             return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, output.getDataNode());
 
@@ -136,17 +141,20 @@
         try {
             TapiDeleteConnectivityInputHandler input = new TapiDeleteConnectivityInputHandler();
             input.setRpcInput(inputVar);
-            log.info("input serviceId: {}", input.getId());
+            log.info("deleteConnectivityService - serviceId: {}", input.getId());
 
+            // Retrieve the Connectivity Service from the DCS, based on Id
             TapiConnectivityServiceHandler serviceHandler = TapiConnectivityServiceHandler.create();
             serviceHandler.setId(input.getId());
-
             DefaultConnectivityService service = serviceHandler.read();
 
+            // For each top-most connection of the service handler, delete that connection
+            // using a manager
             service.connection().stream().forEach(connection -> {
                 TapiConnectionHandler connectionHandler = TapiConnectionHandler.create();
                 connectionHandler.setId(Uuid.fromString(connection.connectionUuid().toString()));
                 DcsBasedTapiConnectionManager manager = DcsBasedTapiConnectionManager.create();
+                log.info("deleteConnectivityService - connectionId: {}", connectionHandler.getId());
                 manager.deleteConnection(connectionHandler);
                 manager.apply();
             });
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
index f7688cc..c26f26e 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
@@ -30,6 +30,7 @@
 import static org.onosproject.odtn.utils.tapi.TapiObjectHandler.DEVICE_ID;
 import static org.onosproject.odtn.utils.tapi.TapiObjectHandler.ODTN_PORT_TYPE;
 import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.CONNECTION_ID;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,7 +65,24 @@
      * as list of Cep pair for each connection to be created
      */
     private TapiConnection pathComputeDetail(TapiNepPair neps) {
-        return mockPathCompute(neps);
+        log.debug("TapiNepPair {}", neps);
+        log.debug("Nep0 {}", neps.left());
+        log.debug("Nep1 {}", neps.right());
+
+        /*
+         * RCAS: 20190117 - We assume that if port type is LINE, it relies on intents.
+         * We construct just a single top-most connection object.
+         */
+        if (neps.left().getPortType() == LINE) {
+            log.info("Connection between line ports");
+            TapiConnection connection = TapiConnection.create(
+                TapiCepRef.create(neps.left(), neps.left().getCepIds().get(0)),
+                TapiCepRef.create(neps.right(), neps.right().getCepIds().get(0))
+                );
+            return connection;
+        } else {
+            return mockPathCompute(neps);
+        }
     }