Added builder and more logs for VtnService and VtnPort

Change-Id: I52f672caebf1946b9bb01c9de0ca2ad2cee23f69
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java
index 9a22552..9dae6e9 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java
@@ -16,12 +16,15 @@
 package org.onosproject.xosclient.api;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 
 import java.util.Map;
 import java.util.Objects;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Representation of port in a CORD VTN controlled network, it can be for VM
  * or container.
@@ -36,23 +39,12 @@
     // TODO remove this when XOS provides vSG information
     private final Map<IpAddress, MacAddress> addressPairs;
 
-
-    /**
-     * Creates a new vtn port with the specified entities.
-     *
-     * @param id vtn port id
-     * @param name vtn port name
-     * @param serviceId id of the service this port is in
-     * @param mac mac address
-     * @param ip ip address
-     * @param addressPairs ip and mac pairs of nested container
-     */
-    public VtnPort(VtnPortId id,
-                        String name,
-                        VtnServiceId serviceId,
-                        MacAddress mac,
-                        IpAddress ip,
-                        Map<IpAddress, MacAddress> addressPairs) {
+   private VtnPort(VtnPortId id,
+                   String name,
+                   VtnServiceId serviceId,
+                   MacAddress mac,
+                   IpAddress ip,
+                   Map<IpAddress, MacAddress> addressPairs) {
         this.id = id;
         this.name = name;
         this.serviceId = serviceId;
@@ -143,4 +135,161 @@
                 .add("addressPairs", addressPairs)
                 .toString();
     }
+
+    /**
+     * Returns a new vtn port builder instance.
+     *
+     * @return new vtn port builder
+     */
+    public static final Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of VTN port entities.
+     */
+    public static final class Builder {
+
+        private VtnPortId id;
+        private String name;
+        private VtnServiceId serviceId;
+        private MacAddress mac;
+        private IpAddress ip;
+        // TODO remove this when XOS provides vSG information
+        private Map<IpAddress, MacAddress> addressPairs;
+
+        private Builder() {
+        }
+
+        /**
+         * Builds an immutable VTN port.
+         *
+         * @return vtn port instance
+         */
+        public VtnPort build() {
+            checkNotNull(id, "VTN port ID cannot be null");
+            checkNotNull(serviceId, "VTN port service ID cannot be null");
+            checkNotNull(mac, "VTN port MAC address cannot be null");
+            checkNotNull(ip, "VTN port IP address cannot be null");
+            addressPairs = addressPairs == null ? ImmutableMap.of() : addressPairs;
+
+            return new VtnPort(id,
+                               name,
+                               serviceId,
+                               mac,
+                               ip,
+                               addressPairs);
+        }
+
+        /**
+         * Returns VTN port builder with the supplied port ID.
+         *
+         * @param id port identifier
+         * @return vtn port builder
+         */
+        public Builder id(VtnPortId id) {
+            this.id = id;
+            return this;
+        }
+
+        /**
+         * Returns VTN port builder with the supplied port name.
+         * Port name can be null.
+         *
+         * @param name port name
+         * @return vtn port builder
+         */
+        public Builder name(String name) {
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Returns VTN port builder with the supplied service ID.
+         *
+         * @param serviceId vtn port service id
+         * @return vtn port builder
+         */
+        public Builder serviceId(VtnServiceId serviceId) {
+            this.serviceId = serviceId;
+            return this;
+        }
+
+        /**
+         * Returns VTN port builder with the supplied MAC address.
+         *
+         * @param mac mac address
+         * @return vtn port builder
+         */
+        public Builder mac(MacAddress mac) {
+            if (mac == null) {
+                final String msg = "VTN port MAC address cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.mac = mac;
+            return this;
+        }
+
+        /**
+         * Returns VTN port builder with the supplied MAC address.
+         *
+         * @param mac mac address as a string
+         * @return vtn port builder
+         */
+        public Builder mac(String mac) {
+            try {
+                return mac(MacAddress.valueOf(mac));
+            } catch (IllegalArgumentException | NullPointerException e) {
+                final String msg = "Malformed MAC address string " + mac +
+                        " for VTN port MAC address";
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        /**
+         * Returns VTN port builder with the supplied IP address.
+         *
+         * @param ip ip address
+         * @return vtn port builder
+         */
+        public Builder ip(IpAddress ip) {
+            if (ip == null) {
+                final String msg = "VTN port IP address cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.ip = ip;
+            return this;
+        }
+
+        /**
+         * Returns VTN port builder with the supplied IP address.
+         *
+         * @param ip ip address as a string
+         * @return vtn port builder
+         */
+        public Builder ip(String ip) {
+            try {
+                return ip(IpAddress.valueOf(ip));
+            } catch (IllegalArgumentException | NullPointerException e) {
+                final String msg = "Malformed IP address string " + ip +
+                        " for VTN port IP address";
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        /**
+         * Returns VTN port builder with the supplied address pairs.
+         *
+         * @param addressPairs address pairs
+         * @return vtn port builder
+         */
+        public Builder addressPairs(Map<IpAddress, MacAddress> addressPairs) {
+            if (addressPairs == null) {
+                final String msg = "VTN address pairs cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.addressPairs = addressPairs;
+            return this;
+        }
+    }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java
index ef2416b..eaf7ac1 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java
@@ -36,7 +36,7 @@
      * @return instance port id
      */
     public static VtnPortId of(String id) {
-        checkArgument(!Strings.isNullOrEmpty(id));
+        checkArgument(!Strings.isNullOrEmpty(id), "VTN port ID cannot be null");
         return new VtnPortId(id);
     }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java
index ec33b9f..3e7b100 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java
@@ -16,7 +16,8 @@
 package org.onosproject.xosclient.api;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.Sets;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onosproject.xosclient.api.VtnServiceApi.NetworkType;
@@ -25,6 +26,7 @@
 import java.util.Objects;
 import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -42,37 +44,24 @@
     private final Set<VtnServiceId> providerServices;
     private final Set<VtnServiceId> tenantServices;
 
-    /**
-     * Creates a new VTN service with the specified entities.
-     *
-     * @param id service id
-     * @param name user friendly name
-     * @param serviceType service type
-     * @param networkType network type
-     * @param vni vni of this service network
-     * @param subnet service network subnet range
-     * @param serviceIp service ip for indirect service access
-     * @param providerServices provider services
-     * @param tenantServices tenant services
-     */
-    public VtnService(VtnServiceId id,
-                      String name,
-                      ServiceType serviceType,
-                      NetworkType networkType,
-                      long vni,
-                      IpPrefix subnet,
-                      IpAddress serviceIp,
-                      Set<VtnServiceId> providerServices,
-                      Set<VtnServiceId> tenantServices) {
-        this.id = checkNotNull(id);
+    private VtnService(VtnServiceId id,
+                       String name,
+                       ServiceType serviceType,
+                       NetworkType networkType,
+                       long vni,
+                       IpPrefix subnet,
+                       IpAddress serviceIp,
+                       Set<VtnServiceId> providerServices,
+                       Set<VtnServiceId> tenantServices) {
+        this.id = id;
         this.name = name;
         this.serviceType = serviceType;
         this.networkType = networkType;
         this.vni = vni;
-        this.subnet = checkNotNull(subnet);
-        this.serviceIp = checkNotNull(serviceIp);
-        this.providerServices = providerServices == null ? Sets.newHashSet() : providerServices;
-        this.tenantServices = tenantServices == null ? Sets.newHashSet() : tenantServices;
+        this.subnet = subnet;
+        this.serviceIp = serviceIp;
+        this.providerServices = providerServices;
+        this.tenantServices = tenantServices;
     }
 
     /**
@@ -187,4 +176,231 @@
                 .add("tenantServices", tenantServices)
                 .toString();
     }
+
+    /**
+     * Returns a new builder instance.
+     *
+     * @return new builder
+     */
+    public static final Builder build() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of VTN service entities.
+     */
+    public static final class Builder {
+
+        private VtnServiceId id;
+        private String name;
+        private ServiceType serviceType;
+        private NetworkType networkType;
+        private long vni = -1;
+        private IpPrefix subnet;
+        private IpAddress serviceIp;
+        private Set<VtnServiceId> providerServices;
+        private Set<VtnServiceId> tenantServices;
+
+        private Builder() {
+        }
+
+        /**
+         * Builds an immutable VTN service.
+         *
+         * @return vtn service instance
+         */
+        public VtnService build() {
+            checkNotNull(id, "VTN service ID cannot be null");
+            checkArgument(!Strings.isNullOrEmpty(name), "VTN service name cannot be null");
+            checkNotNull(serviceType, "VTN service type cannot be null");
+            checkNotNull(networkType, "VTN network type cannot be null");
+            checkArgument(vni > 0, "VTN network VNI is not set");
+            checkNotNull(subnet, "VTN subnet cannot be null");
+            checkNotNull(serviceIp, "VTN service IP cannot be null");
+
+            providerServices = providerServices == null ? ImmutableSet.of() : providerServices;
+            tenantServices = tenantServices == null ? ImmutableSet.of() : tenantServices;
+
+            return new VtnService(id,
+                                  name,
+                                  serviceType,
+                                  networkType,
+                                  vni,
+                                  subnet,
+                                  serviceIp,
+                                  providerServices,
+                                  tenantServices);
+        }
+
+        /**
+         * Returns VTN service builder with the supplied service ID.
+         *
+         * @param id service identifier
+         * @return vtn service builder
+         */
+        public Builder id(VtnServiceId id) {
+            this.id = id;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied service name.
+         *
+         * @param name service name
+         * @return vtn service builder
+         */
+        public Builder name(String name) {
+            if (Strings.isNullOrEmpty(name)) {
+                final String msg = "VTN service name cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied service type.
+         *
+         * @param serviceType service type
+         * @return vtn service builder
+         */
+        public Builder serviceType(ServiceType serviceType) {
+            this.serviceType = serviceType;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied network type.
+         *
+         * @param networkType network type
+         * @return vtn service builder
+         */
+        public Builder networkType(NetworkType networkType) {
+            this.networkType = networkType;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied VNI.
+         *
+         * @param vni vni of the service network
+         * @return vtn service builder
+         */
+        public Builder vni(long vni) {
+            if (vni < 0 || vni > 16777215) {
+                final String msg = "VNI " + vni + " is out of range";
+                throw new IllegalArgumentException(msg);
+            }
+            this.vni = vni;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied VNI.
+         *
+         * @param vni vni of the service network as a string
+         * @return vtn service builder
+         */
+        public Builder vni(String vni) {
+            try {
+                return vni(Long.parseLong(vni));
+            } catch (NumberFormatException | NullPointerException e) {
+                final String msg = "Malformed number string " + vni +
+                        " for VTN network VNI";
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        /**
+         * Returns VTN service builder with the supplied subnet.
+         *
+         * @param subnet subnet of the service network
+         * @return vtn service builder
+         */
+        public Builder subnet(IpPrefix subnet) {
+            if (subnet == null) {
+                final String msg = "VTN service subnet is null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.subnet = subnet;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied subnet.
+         *
+         * @param subnet subnet of the service network as a string
+         * @return vtn service builder
+         */
+        public Builder subnet(String subnet) {
+            try {
+                return subnet(IpPrefix.valueOf(subnet));
+            } catch (IllegalArgumentException | NullPointerException e) {
+                final String msg = "Malformed IP prefix string " + subnet +
+                        " for VTN service subnet";
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        /**
+         * Returns VTN service builder with the supplied service IP address.
+         *
+         * @param serviceIp service ip address
+         * @return vtn service builder
+         */
+        public Builder serviceIp(IpAddress serviceIp) {
+            if (serviceIp == null) {
+                final String msg = "VTN service IP cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.serviceIp = serviceIp;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied service IP address.
+         *
+         * @param serviceIp service ip address as a string
+         * @return vtn service builder
+         */
+        public Builder serviceIp(String serviceIp) {
+            try {
+                return serviceIp(IpAddress.valueOf(serviceIp));
+            } catch (IllegalArgumentException | NullPointerException e) {
+                final String msg = "Malformed IP address string " + serviceIp +
+                        " for VTN service IP address";
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        /**
+         * Returns VTN service builder with the supplied provider services.
+         *
+         * @param pServices provider services
+         * @return vtn service builder
+         */
+        public Builder providerServices(Set<VtnServiceId> pServices) {
+            if (pServices == null) {
+                final String msg = "Provider services cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.providerServices = pServices;
+            return this;
+        }
+
+        /**
+         * Returns VTN service builder with the supplied tenant services.
+         *
+         * @param tServices tenant services
+         * @return vtn service builder
+         */
+        public Builder tenantServices(Set<VtnServiceId> tServices) {
+            if (tServices == null) {
+                final String msg = "Tenant services cannot be null";
+                throw new IllegalArgumentException(msg);
+            }
+            this.tenantServices = tServices;
+            return this;
+        }
+    }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java
index 5850696..6fc4a43 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java
@@ -15,9 +15,10 @@
  */
 package org.onosproject.xosclient.api;
 
+import com.google.common.base.Strings;
 import org.onlab.util.Identifier;
 
-import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
 
 /**
  * Representation of VTN service identifier.
@@ -39,7 +40,7 @@
      * @return CordServiceId
      */
     public static VtnServiceId of(String id) {
-        checkNotNull(id);
+        checkArgument(!Strings.isNullOrEmpty(id), "VTN service ID cannot be null");
         return new VtnServiceId(id);
     }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
index a7329d4..8054dfe 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
@@ -119,12 +119,14 @@
                 pair -> addressPairs.put(IpAddress.valueOf(pair.getIpAddress()),
                                          MacAddress.valueOf(pair.getMacAddress())));
 
-        return new VtnPort(VtnPortId.of(osPort.getId()),
-                           osPort.getName(),
-                           VtnServiceId.of(osPort.getNetworkId()),
-                           MacAddress.valueOf(osPort.getMacAddress()),
-                           IpAddress.valueOf(ipAddr.getIpAddress()),
-                           addressPairs);
+        return VtnPort.builder()
+                .id(VtnPortId.of(osPort.getId()))
+                .name(osPort.getName())
+                .serviceId(VtnServiceId.of(osPort.getNetworkId()))
+                .mac(osPort.getMacAddress())
+                .ip(ipAddr.getIpAddress())
+                .addressPairs(addressPairs)
+                .build();
     }
 
     // TODO remove this when XOS provides this information
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
index 84c366f6..25f5740 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
@@ -19,8 +19,6 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Strings;
 import com.google.common.collect.Sets;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
 import org.onosproject.xosclient.api.OpenStackAccess;
 import org.onosproject.xosclient.api.VtnServiceApi;
 import org.onosproject.xosclient.api.XosAccess;
@@ -146,15 +144,17 @@
             return null;
         }
 
-        return new VtnService(serviceId,
-                              osNet.getName(),
-                              serviceType(osNet.getName()),
-                              networkType(osNet.getName()),
-                              Long.parseLong(osNet.getProviderSegID()),
-                              IpPrefix.valueOf(osSubnet.getCidr()),
-                              IpAddress.valueOf(osSubnet.getGateway()),
-                              providerServices(serviceId),
-                              tenantServices(serviceId));
+        return VtnService.build()
+                .id(serviceId)
+                .name(osNet.getName())
+                .serviceType(serviceType(osNet.getName()))
+                .networkType(networkType(osNet.getName()))
+                .vni(osNet.getProviderSegID())
+                .subnet(osSubnet.getCidr())
+                .serviceIp(osSubnet.getGateway())
+                .providerServices(providerServices(serviceId))
+                .tenantServices(tenantServices(serviceId))
+                .build();
     }
 
     // TODO remove this when XOS provides this information
@@ -177,7 +177,7 @@
 
     // TODO remove this when XOS provides this information
     private NetworkType networkType(String netName) {
-        checkArgument(!Strings.isNullOrEmpty(netName));
+        checkArgument(!Strings.isNullOrEmpty(netName), "VTN network name cannot be null");
 
         String name = netName.toUpperCase();
         if (name.contains(PUBLIC.name())) {
@@ -193,7 +193,7 @@
 
     // TODO remove this when XOS provides this information
     private ServiceType serviceType(String netName) {
-        checkArgument(!Strings.isNullOrEmpty(netName));
+        checkArgument(!Strings.isNullOrEmpty(netName), "VTN network name cannot be null");
 
         String name = netName.toUpperCase();
         if (name.contains(VSG.name())) {