REST interface VPLS update

In the last days, we worked with VPLS REST interface and we found a two bug
and discussed some improvements.

bug fixed:
1) the method addInterfaces, adds only one interface even if the user
had declared several interfaces.
2) I have an issue with the interface name, due to the fact that I use
the same identifier in the json for identifieng the name of vpls and the
name of interface. More in detail if I write a json declaring
first the interfaces an then the vpls the name are inverted. So in other words
could happen that vpls are called with the name of the interface.

upgrade:
1) I make the Encapsulation not mandatory, as in the CLI.
2) I add two new control in the method for the post of the VPLS and
interface for cheecking the existence of the device and the port, in
order to avoid the failing of the intent.

Change-Id: Ib3a47d6b2981a5bb187d74cd235de800c4d5aaf8
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsCodec.java b/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsCodec.java
index 8f8bf3f..77ab494 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsCodec.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsCodec.java
@@ -27,6 +27,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.stream.IntStream;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -62,11 +63,10 @@
         if (json == null || !json.isObject()) {
             return null;
         }
-
-        String vplsName = json.findValue(NAME).asText();
-        EncapsulationType encap = EncapsulationType.enumFromString(json.findValue(ENCAPSULATION_TYPE).asText());
-        VplsData vplsData = VplsData.of(vplsName, encap);
-
+        List<String> names = new ArrayList<>();
+        json.findValues(NAME).forEach(jsonNode -> {
+            names.add(jsonNode.asText());
+        });
         Collection<Interface> interfaceList = new ArrayList<>();
         JsonNode interfacesJeson = json.findValue(INTERFACES);
         JsonCodec<Interface> interfaceCodec = context.codec(Interface.class);
@@ -75,8 +75,16 @@
                     .forEach(i -> interfaceList.add(
                             interfaceCodec.decode(get(interfacesJeson, i),
                                     context)));
-            vplsData.addInterfaces(interfaceList);
+
         }
+        interfaceList.forEach(interf -> {
+            names.remove(interf.name());
+        });
+        String vplsName = names.get(0);
+        EncapsulationType encap =  json.findValue(ENCAPSULATION_TYPE) == null ?
+                null : EncapsulationType.enumFromString(json.findValue(ENCAPSULATION_TYPE).asText());
+        VplsData vplsData = VplsData.of(vplsName, encap);
+        vplsData.addInterfaces(interfaceList);
         return vplsData;
     }
 
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsWebResource.java b/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsWebResource.java
index ae227ed..9d2f488 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsWebResource.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/rest/VplsWebResource.java
@@ -16,8 +16,10 @@
 package org.onosproject.vpls.rest;
 
 
+
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.intf.Interface;
 import org.onosproject.net.intf.InterfaceAdminService;
 import org.onosproject.rest.AbstractWebResource;
@@ -44,8 +46,9 @@
 import java.util.ArrayList;
 
 
-import static org.onlab.util.Tools.readTreeFromStream;
 import static org.onlab.util.Tools.nullIsNotFound;
+import static org.onlab.util.Tools.nullIsIllegal;
+import static org.onlab.util.Tools.readTreeFromStream;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -57,9 +60,12 @@
     private UriInfo uriInfo;
 
     private static final String VPLS_NOT_FOUND = "Vpls is not found for ";
+    private static final String DEVICE_NOT_FOUND = "Device is not found for ";
+    private static final String PORT_NOT_FOUND = "Port is not found for ";
     private static final String VPLSS = "vplss";
     private static final String VPLS = "vpls";
     private static final String INTERFACES = "interfaces";
+    private static final String INTERFACES_KEY_ERROR = "No interfaces";
 
     private final ObjectNode root = mapper().createObjectNode();
     private final Logger log = getLogger(getClass());
@@ -115,12 +121,17 @@
     @Produces(MediaType.APPLICATION_JSON)
     public Response createVpls(InputStream stream) {
         Vpls service = get(Vpls.class);
+        DeviceService deviceService = get(DeviceService.class);
         InterfaceAdminService interfaceService = get(InterfaceAdminService.class);
         try {
             ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
 
             VplsData vplsData = codec(VplsData.class).decode(jsonTree, this);
             vplsData.interfaces().forEach(interf -> {
+                nullIsNotFound(deviceService.getDevice(interf.connectPoint().deviceId()),
+                        DEVICE_NOT_FOUND + interf.connectPoint().deviceId());
+                nullIsNotFound(deviceService.getPort(interf.connectPoint()),
+                        PORT_NOT_FOUND + interf.connectPoint().port());
                     interfaceService.add(interf);
             });
             service.addInterfaces(vplsData, vplsData.interfaces());
@@ -152,14 +163,21 @@
     @Produces(MediaType.APPLICATION_JSON)
     public Response addInterfaces(@PathParam("vplsName") String vplsName, InputStream stream) {
         Vpls service = get(Vpls.class);
+        DeviceService deviceService = get(DeviceService.class);
         InterfaceAdminService interfaceService = get(InterfaceAdminService.class);
         final VplsData vplsData = nullIsNotFound(service.getVpls(vplsName),
                 VPLS_NOT_FOUND + vplsName);
         try {
             ObjectNode jsonTree = readTreeFromStream(mapper(), stream);
+            ArrayNode routesArray = nullIsIllegal((ArrayNode) jsonTree.get(INTERFACES),
+                    INTERFACES_KEY_ERROR);
             Collection<Interface> interfaceList = new ArrayList<>();
-            jsonTree.forEach(interf -> {
-                Interface inter = codec(Interface.class).decode(jsonTree, this);
+           routesArray.forEach(interfJson -> {
+                Interface inter = codec(Interface.class).decode((ObjectNode) interfJson, this);
+                nullIsNotFound(deviceService.getDevice(inter.connectPoint().deviceId()),
+                        DEVICE_NOT_FOUND + inter.connectPoint().deviceId());
+                nullIsNotFound(deviceService.getPort(inter.connectPoint()),
+                        PORT_NOT_FOUND + inter.connectPoint().port());
                 interfaceList.add(inter);
                 interfaceService.add(inter);
             });
@@ -174,7 +192,6 @@
         } catch (IOException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
-
     }
 
     /**
diff --git a/apps/vpls/src/main/resources/definitions/InterfacesPost.json b/apps/vpls/src/main/resources/definitions/InterfacesPost.json
index c605c92..b526f4e 100644
--- a/apps/vpls/src/main/resources/definitions/InterfacesPost.json
+++ b/apps/vpls/src/main/resources/definitions/InterfacesPost.json
@@ -46,5 +46,4 @@
       }
     }
   }
-}
-
+}
\ No newline at end of file
diff --git a/apps/vpls/src/main/resources/definitions/VplsPost.json b/apps/vpls/src/main/resources/definitions/VplsPost.json
index 88da89a..e8cb194 100644
--- a/apps/vpls/src/main/resources/definitions/VplsPost.json
+++ b/apps/vpls/src/main/resources/definitions/VplsPost.json
@@ -15,8 +15,7 @@
         "type": "object",
         "title": "vpls",
         "required": [
-          "name",
-          "encapsulation"
+          "name"
         ],
         "properties": {
           "name": {