[ODTN] Add read/create/delete ConnectivityService RPC

- RPC: get service interface point
- RPC: get connectivity service list
- RPC: get connectivity service detail
- RPC: create connectivity service
- RPC: delete connectivity service

- Filter method of TAPI resolver for both Node / NEP
- Change condition for sip to odtn-port-type
- Use odtn-port-type in path-computation mock
- Create CEP at topology discovery

- Add sample path calculator
- Add connection-id based path selection

Change-Id: I2f08aacb3dd14b6b3c59a64a349e50abb495f70b
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiDataProducer.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiDataProducer.java
index 5f6b96c..726d002 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiDataProducer.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiDataProducer.java
@@ -15,9 +15,12 @@
  */
 
 package org.onosproject.odtn.internal;
+
 import com.google.common.annotations.VisibleForTesting;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 import org.onosproject.config.DynamicConfigService;
 
@@ -30,14 +33,13 @@
 import org.onosproject.odtn.utils.tapi.TapiNodeRef;
 import org.onosproject.yang.gen.v1.tapicommon.rev20180307.tapicommon.DefaultContext;
 import org.onosproject.yang.gen.v1.tapicommon.rev20180307.tapicommon.globalclass.Name;
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20180307.tapiconnectivity.context.topology.node.ownednodeedgepoint.DefaultAugmentedTapiTopologyOwnedNodeEdgePoint;
 import org.onosproject.yang.gen.v1.tapitopology.rev20180307.tapitopology.context.DefaultAugmentedTapiCommonContext;
 import org.onosproject.yang.gen.v1.tapitopology.rev20180307.tapitopology.topologycontext.Topology;
-import org.onosproject.yang.model.Augmentable;
 import org.onosproject.yang.model.DataNode;
 import org.onosproject.yang.model.DefaultModelObjectData;
 import org.onosproject.yang.model.DefaultResourceData;
 import org.onosproject.yang.model.ModelConverter;
-import org.onosproject.yang.model.ModelObject;
 import org.onosproject.yang.model.ModelObjectData;
 import org.onosproject.yang.model.ModelObjectId;
 import org.onosproject.yang.model.ResourceData;
@@ -45,13 +47,19 @@
 import org.slf4j.Logger;
 
 import static org.onlab.osgi.DefaultServiceDirectory.getService;
-import static org.onosproject.odtn.utils.tapi.TapiInstanceBuilder.DEVICE_ID;
-import static org.onosproject.odtn.utils.tapi.TapiInstanceBuilder.ONOS_CP;
+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.utils.tapi.TapiObjectHandler.ONOS_CP;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.CONNECTION_ID;
 import static org.slf4j.LoggerFactory.getLogger;
 
+/**
+ * DCS-dependent Tapi Data producer implementation.
+ */
 public class DcsBasedTapiDataProducer implements TapiDataProducer {
 
     private final Logger log = getLogger(getClass());
+
     protected DynamicConfigService dcs;
     protected ModelConverter modelConverter;
 
@@ -63,17 +71,28 @@
 
     @Override
     public void updateCacheRequest(DefaultTapiResolver resolver) {
-        ModelObject context = readContextModelObject();
-        updateCache(resolver, context);
+        updateCache(resolver, readContextModelObject());
     }
 
+    /**
+     * Update resolver's cache with Tapi context modelObject.
+     *
+     * @param resolver TapiResolver
+     * @param context Context ModelObject which has all data nodes of Tapi DataTree in Dcs store
+     */
     @VisibleForTesting
-    protected void updateCache(DefaultTapiResolver resolver, ModelObject context) {
+    protected void updateCache(DefaultTapiResolver resolver, DefaultContext context) {
         updateNodes(resolver, getNodes(context));
         updateNeps(resolver, getNeps(context));
     }
 
-    private ModelObject readContextModelObject() {
+    /**
+     * Get Tapi context modelObject from Dcs.
+     *
+     * @return Tapi context modelObject in Dcs store
+     */
+    // FIXME update this method using TapiContextHandler
+    private DefaultContext readContextModelObject() {
         // read DataNode from DCS
         ModelObjectId mid = ModelObjectId.builder().addChild(DefaultContext.class).build();
         DataNode node = dcs.readNode(getResourceId(mid), Filter.builder().build());
@@ -82,15 +101,20 @@
         ResourceData data = DefaultResourceData.builder().addDataNode(node)
                 .resourceId(ResourceId.builder().build()).build();
         ModelObjectData modelData = modelConverter.createModel(data);
-        ModelObject context = modelData.modelObjects().get(0);
+        DefaultContext context = (DefaultContext) modelData.modelObjects().get(0);
 
         return context;
     }
 
-    private List<TapiNodeRef> getNodes(ModelObject context) {
-        Augmentable augmentedContext = (Augmentable) context;
+    /**
+     * Extract Tapi Nodes from context modelObject and convert them to NodeRefs.
+     *
+     * @param context
+     * @return List of NodeRef
+     */
+    private List<TapiNodeRef> getNodes(DefaultContext context) {
         DefaultAugmentedTapiCommonContext topologyContext
-                = augmentedContext.augmentation(DefaultAugmentedTapiCommonContext.class);
+                = context.augmentation(DefaultAugmentedTapiCommonContext.class);
         Topology topology = topologyContext.topology().get(0);
 
         if (topology.node() == null) {
@@ -98,19 +122,27 @@
         }
         return topology.node().stream()
                 .map(node -> {
-                    String deviceId = node.name().stream()
-                            .filter(kv -> kv.valueName().equals(DEVICE_ID))
-                            .findFirst().map(Name::value).get();
-                    return DcsBasedTapiNodeRef.create(topology, node)
-                            .setDeviceId(DeviceId.deviceId(deviceId));
+                    DcsBasedTapiNodeRef nodeRef = DcsBasedTapiNodeRef.create(topology, node);
+                    if (node.name() != null) {
+                        String deviceId = node.name().stream()
+                                .filter(kv -> kv.valueName().equals(DEVICE_ID))
+                                .findFirst().map(Name::value).get();
+                        nodeRef.setDeviceId(DeviceId.deviceId(deviceId));
+                    }
+                    return nodeRef;
                 })
                 .collect(Collectors.toList());
     }
 
-    private List<TapiNepRef> getNeps(ModelObject context) {
-        Augmentable augmentedContext = (Augmentable) context;
+    /**
+     * Extract Tapi Neps from context modelObject and convert them to NepRefs.
+     *
+     * @param context
+     * @return List of TapiNepRef
+     */
+    private List<TapiNepRef> getNeps(DefaultContext context) {
         DefaultAugmentedTapiCommonContext topologyContext
-                = augmentedContext.augmentation(DefaultAugmentedTapiCommonContext.class);
+                = context.augmentation(DefaultAugmentedTapiCommonContext.class);
         Topology topology = topologyContext.topology().get(0);
 
         if (topology.node() == null) {
@@ -118,22 +150,41 @@
         }
         List<TapiNepRef> ret = topology.node().stream()
                 .flatMap(node -> {
-                    if (node.ownedNodeEdgePoint() == null) {
-                        return null;
-                    }
-                    return node.ownedNodeEdgePoint().stream()
+                            if (node.ownedNodeEdgePoint() == null) {
+                                return null;
+                            }
+                            return node.ownedNodeEdgePoint().stream()
                                     .map(nep -> {
-                                        String onosConnectPoint = nep.name().stream()
-                                                .filter(kv -> kv.valueName().equals(ONOS_CP))
-                                                .findFirst().map(Name::value).get();
-                                        TapiNepRef nepRef = DcsBasedTapiNepRef.create(topology, node, nep)
-                                                .setConnectPoint(ConnectPoint.fromString(onosConnectPoint));
+                                        TapiNepRef nepRef = DcsBasedTapiNepRef.create(topology, node, nep);
+                                        if (nep.name() != null) {
+                                            Map<String, String> kvs = new HashMap<>();
+                                            nep.name().forEach(kv -> kvs.put(kv.valueName(), kv.value()));
+
+                                            String onosConnectPoint = kvs.getOrDefault(ONOS_CP, null);
+                                            String portType = kvs.getOrDefault(ODTN_PORT_TYPE, null);
+                                            String connectionId = kvs.getOrDefault(CONNECTION_ID, null);
+                                            nepRef.setConnectPoint(ConnectPoint.fromString(onosConnectPoint))
+                                                    .setPortType(portType)
+                                                    .setConnectionId(connectionId);
+                                        }
                                         if (nep.mappedServiceInterfacePoint() != null) {
                                             nep.mappedServiceInterfacePoint().stream()
                                                     .forEach(sip -> {
                                                         nepRef.setSipId(sip.serviceInterfacePointId().toString());
                                                     });
                                         }
+
+                                        DefaultAugmentedTapiTopologyOwnedNodeEdgePoint augmentNep =
+                                                nep.augmentation(DefaultAugmentedTapiTopologyOwnedNodeEdgePoint.class);
+                                        try {
+                                            if (augmentNep.connectionEndPoint() != null) {
+                                                List<String> cepIds = augmentNep.connectionEndPoint().stream()
+                                                        .map(cep -> cep.uuid().toString()).collect(Collectors.toList());
+                                                nepRef.setCepIds(cepIds);
+                                            }
+                                        } catch (NullPointerException e) {
+                                            log.warn("Augmented ownedNodeEdgePoint is not found.");
+                                        }
                                         return nepRef;
                                     });
                         }
@@ -141,16 +192,26 @@
         return ret;
     }
 
+    /**
+     * Update resolver's NodeRef list.
+     *
+     * @param resolver TapiResolver
+     * @param nodes List of NodeRef for update
+     */
     private void updateNodes(DefaultTapiResolver resolver, List<TapiNodeRef> nodes) {
         resolver.addNodeRefList(nodes);
     }
 
+    /**
+     * Update resolver's NepRef list.
+     *
+     * @param resolver TapiResolver
+     * @param neps List of NepRef for update
+     */
     private void updateNeps(DefaultTapiResolver resolver, List<TapiNepRef> neps) {
         resolver.addNepRefList(neps);
     }
 
-
-
     private ResourceId getResourceId(ModelObjectId modelId) {
         ModelObjectData data = DefaultModelObjectData.builder()
                 .identifier(modelId)