[CORD-1983] Implement addSource for Multicast REST API

Change-Id: I0cd976e76012eeb4c8ef643cd2f652e3e4e82c83
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/MulticastRouteWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/MulticastRouteWebResource.java
index 212dbeb..374605b 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/MulticastRouteWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/MulticastRouteWebResource.java
@@ -24,6 +24,8 @@
 import org.onosproject.net.mcast.MulticastRouteService;
 import org.onosproject.rest.AbstractWebResource;
 
+import static org.onlab.util.Tools.nullIsNotFound;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -73,11 +75,19 @@
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public Response createRoute(InputStream stream) {
+
+        final String ingressStr = "ingress";
         MulticastRouteService service = get(MulticastRouteService.class);
         try {
             ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
             McastRoute route = codec(McastRoute.class).decode(jsonTree, this);
             service.add(route);
+            if (jsonTree.has(ingressStr)) {
+                String ingressPathStr = jsonTree.path(ingressStr).asText();
+                ConnectPoint ingressConnectPoint = nullIsNotFound(ConnectPoint.deviceConnectPoint(ingressPathStr),
+                                                                  "ingress connection point cannot be null!");
+                service.addSource(route, ingressConnectPoint);
+            }
         } catch (IOException ex) {
             throw new IllegalArgumentException(ex);
         }
@@ -132,6 +142,7 @@
             McastRoute route = new McastRoute(IpAddress.valueOf(source), IpAddress.valueOf(group),
                     McastRoute.Type.STATIC);
             ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
             jsonTree.path("sinks").forEach(node -> {
                 ConnectPoint sink = ConnectPoint.deviceConnectPoint(node.asText());
                 service.addSink(route, sink);
diff --git a/web/api/src/main/resources/definitions/McastRoutePost.json b/web/api/src/main/resources/definitions/McastRoutePost.json
index 3a73adb..911de19 100644
--- a/web/api/src/main/resources/definitions/McastRoutePost.json
+++ b/web/api/src/main/resources/definitions/McastRoutePost.json
@@ -5,6 +5,9 @@
     "source",
     "group"
   ],
+  "optional": [
+    "ingress"
+  ],
   "properties": {
     "source": {
       "type": "string",
@@ -15,6 +18,11 @@
       "type": "string",
       "example": "10.1.1.0",
       "description": "Multicast group IP address"
+    },
+    "ingress": {
+      "type": "string",
+      "example": "of:0000000000000001/1",
+      "description": "Multicast ingress Connection Point device and port"
     }
   }
 }