Limit string field lengths for network/configuration objects

Change-Id: Ic375854bb697ee21a8fd7b15fccd0b0878212869
diff --git a/core/api/src/main/java/org/onosproject/net/config/Config.java b/core/api/src/main/java/org/onosproject/net/config/Config.java
index 9cea1b9..f1d6252 100644
--- a/core/api/src/main/java/org/onosproject/net/config/Config.java
+++ b/core/api/src/main/java/org/onosproject/net/config/Config.java
@@ -52,6 +52,7 @@
 
     private static final String TRUE_LITERAL = "true";
     private static final String FALSE_LITERAL = "false";
+    private static final String EMPTY_STRING = "";
 
     protected S subject;
     protected String key;
@@ -440,6 +441,20 @@
     }
 
     /**
+     * Indicates whether the specified field is of a valid length.
+     *
+     * @param field the field to validate
+     * @param maxLength the maximum allowed length of the field
+     * @return true if the field lenth is less than the required length
+     */
+    protected boolean isValidLength(String field, int maxLength) {
+        if (object.path(field).asText(EMPTY_STRING).length() > maxLength) {
+            throw new InvalidFieldException(field, "exceeds maximum length " + maxLength);
+        }
+        return true;
+    }
+
+    /**
      * Returns true if this config contains a field with the given name.
      *
      * @param name the field name
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BandwidthCapacity.java b/core/api/src/main/java/org/onosproject/net/config/basics/BandwidthCapacity.java
index f9f7b3c..e0c43dc 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BandwidthCapacity.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BandwidthCapacity.java
@@ -45,6 +45,9 @@
 
     @Override
     public boolean isValid() {
+        // Validate the capacity
+        capacity();
+
         // Open for extension (adding fields) in the future,
         // must have CAPACITY field.
         return isNumber(CAPACITY, FieldPresence.MANDATORY);
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java
index ebcdd82..1c4adb2 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java
@@ -19,6 +19,8 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.key.DeviceKeyId;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 /**
  * Basic configuration for network infrastructure devices.
  */
@@ -33,11 +35,29 @@
     private static final String SERIAL = "serial";
     private static final String DEVICE_KEY_ID = "deviceKeyId";
 
+    private static final int DRIVER_MAX_LENGTH = 256;
+    private static final int MANUFACTURER_MAX_LENGTH = 256;
+    private static final int HW_VERSION_MAX_LENGTH = 256;
+    private static final int SW_VERSION_MAX_LENGTH = 256;
+    private static final int SERIAL_MAX_LENGTH = 256;
+    private static final int MANAGEMENT_ADDRESS_MAX_LENGTH = 1024;
+
     @Override
     public boolean isValid() {
-        return hasOnlyFields(ALLOWED, NAME, LATITUDE, LONGITUDE, UI_TYPE,
-                RACK_ADDRESS, OWNER, TYPE, DRIVER, MANUFACTURER, HW_VERSION,
-                SW_VERSION, SERIAL, MANAGEMENT_ADDRESS, DEVICE_KEY_ID);
+        // Validate type/DeviceKeyId
+        type();
+        deviceKeyId();
+
+        return super.isValid()
+                && hasOnlyFields(ALLOWED, NAME, LATITUDE, LONGITUDE, UI_TYPE,
+                                 RACK_ADDRESS, OWNER, TYPE, DRIVER, MANUFACTURER, HW_VERSION,
+                                 SW_VERSION, SERIAL, MANAGEMENT_ADDRESS, DEVICE_KEY_ID)
+                && isValidLength(DRIVER, DRIVER_MAX_LENGTH)
+                && isValidLength(MANUFACTURER, MANUFACTURER_MAX_LENGTH)
+                && isValidLength(HW_VERSION, MANUFACTURER_MAX_LENGTH)
+                && isValidLength(SW_VERSION, MANUFACTURER_MAX_LENGTH)
+                && isValidLength(SERIAL, MANUFACTURER_MAX_LENGTH)
+                && isValidLength(MANAGEMENT_ADDRESS, MANAGEMENT_ADDRESS_MAX_LENGTH);
     }
 
     /**
@@ -75,6 +95,8 @@
      * @return self
      */
     public BasicDeviceConfig driver(String driverName) {
+        checkArgument(driverName.length() <= DRIVER_MAX_LENGTH,
+                "driver exceeds maximum length " + DRIVER_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(DRIVER, driverName);
     }
 
@@ -94,6 +116,8 @@
      * @return self
      */
     public BasicDeviceConfig manufacturer(String manufacturerName) {
+        checkArgument(manufacturerName.length() <= MANUFACTURER_MAX_LENGTH,
+                "manufacturer exceeds maximum length " + MANUFACTURER_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(MANUFACTURER, manufacturerName);
     }
 
@@ -113,6 +137,8 @@
      * @return self
      */
     public BasicDeviceConfig hwVersion(String hwVersion) {
+        checkArgument(hwVersion.length() <= HW_VERSION_MAX_LENGTH,
+                "hwVersion exceeds maximum length " + HW_VERSION_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(HW_VERSION, hwVersion);
     }
 
@@ -132,6 +158,8 @@
      * @return self
      */
     public BasicDeviceConfig swVersion(String swVersion) {
+        checkArgument(swVersion.length() <= SW_VERSION_MAX_LENGTH,
+                "swVersion exceeds maximum length " + SW_VERSION_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(SW_VERSION, swVersion);
     }
 
@@ -151,6 +179,8 @@
      * @return self
      */
     public BasicDeviceConfig serial(String serial) {
+        checkArgument(serial.length() <= SERIAL_MAX_LENGTH,
+                "serial exceeds maximum length " + SERIAL_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(SERIAL, serial);
     }
 
@@ -170,6 +200,8 @@
      * @return self
      */
     public BasicDeviceConfig managementAddress(String managementAddress) {
+        checkArgument(managementAddress.length() <= MANAGEMENT_ADDRESS_MAX_LENGTH,
+                "serialNumber exceeds maximum length " + MANAGEMENT_ADDRESS_MAX_LENGTH);
         return (BasicDeviceConfig) setOrClear(MANAGEMENT_ADDRESS, managementAddress);
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java
index 295995f..27a70f2 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java
@@ -59,6 +59,12 @@
 
     private static final double DEFAULT_COORD = 0.0;
 
+    private static final int NAME_MAX_LENGTH = 256;
+    private static final int UI_TYPE_MAX_LENGTH = 128;
+    private static final int LOC_TYPE_MAX_LENGTH = 32;
+    private static final int RACK_ADDRESS_MAX_LENGTH = 256;
+    private static final int OWNER_MAX_LENGTH = 128;
+
     /**
      * Returns friendly label for the element. If not set, returns the
      * element identifier.
@@ -193,4 +199,11 @@
         return (BasicElementConfig) setOrClear(OWNER, owner);
     }
 
+    @Override
+    public boolean isValid() {
+        return isValidLength(NAME, NAME_MAX_LENGTH)
+                && isValidLength(UI_TYPE, UI_TYPE_MAX_LENGTH)
+                && isValidLength(RACK_ADDRESS, RACK_ADDRESS_MAX_LENGTH)
+                && isValidLength(OWNER, OWNER_MAX_LENGTH);
+    }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
index cd05e14..c1a1f4d 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
@@ -36,6 +36,9 @@
 
     @Override
     public boolean isValid() {
+        // Validate type/devices
+        type();
+
         return hasOnlyFields(ALLOWED, TYPE, METRIC, LATENCY, BANDWIDTH, IS_DURABLE) &&
                 isBoolean(ALLOWED, OPTIONAL) && isNumber(METRIC, OPTIONAL) &&
                 isNumber(LATENCY, OPTIONAL) && isNumber(BANDWIDTH, OPTIONAL);
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicRegionConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicRegionConfig.java
index e27157e..9be2abf 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicRegionConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicRegionConfig.java
@@ -34,8 +34,13 @@
 
     @Override
     public boolean isValid() {
-        return hasOnlyFields(ALLOWED, NAME, LATITUDE, LONGITUDE, UI_TYPE,
-                RACK_ADDRESS, OWNER, TYPE, DEVICES);
+        // Validate type/devices
+        type();
+        devices();
+
+        return super.isValid()
+                && hasOnlyFields(ALLOWED, NAME, LATITUDE, LONGITUDE, UI_TYPE,
+                                 RACK_ADDRESS, OWNER, TYPE, DEVICES);
     }
 
     @Override
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfig.java
index 4091f4e..92533a3 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfig.java
@@ -54,14 +54,23 @@
     private static final String E_GEOMAP_ALREADY_SET =
             "Can't set sprites when geomap is already set";
 
+    private static final int GEOMAP_MAX_LENGTH = 128;
+    private static final int SPRITES_MAX_LENGTH = 128;
+
     @Override
     public boolean isValid() {
         if (object.has(GEOMAP) && object.has(SPRITES)) {
             throw new InvalidFieldException(GEOMAP, E_GEOMAP_SPRITE);
         }
 
+        // Validate the region and parent
+        region();
+        parent();
+
         return hasOnlyFields(REGION, PARENT, GEOMAP, SPRITES, SCALE,
-                OFFSET_X, OFFSET_Y);
+                OFFSET_X, OFFSET_Y)
+                && isValidLength(GEOMAP, GEOMAP_MAX_LENGTH)
+                && isValidLength(SPRITES, SPRITES_MAX_LENGTH);
     }
 
     @Override
diff --git a/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java b/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
index 0a4c705..4958a29 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
@@ -22,6 +22,7 @@
 import java.net.URI;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.Device.Type;
 import com.google.common.base.Objects;
@@ -31,6 +32,12 @@
  */
 public class DefaultDeviceDescription extends AbstractDescription
         implements DeviceDescription {
+
+    private static final int MANUFACTURER_MAX_LENGTH = 256;
+    private static final int HW_VERSION_MAX_LENGTH = 256;
+    private static final int SW_VERSION_MAX_LENGTH = 256;
+    private static final int SERIAL_NUMBER_MAX_LENGTH = 256;
+
     private final URI uri;
     private final Type type;
     private final String manufacturer;
@@ -81,6 +88,24 @@
         super(annotations);
         this.uri = checkNotNull(uri, "Device URI cannot be null");
         this.type = checkNotNull(type, "Device type cannot be null");
+
+        if (hwVersion != null) {
+            checkArgument(hwVersion.length() <= HW_VERSION_MAX_LENGTH,
+                    "hwVersion exceeds maximum length " + HW_VERSION_MAX_LENGTH);
+        }
+        if (swVersion != null) {
+            checkArgument(swVersion.length() <= SW_VERSION_MAX_LENGTH,
+                    "swVersion exceeds maximum length " + SW_VERSION_MAX_LENGTH);
+        }
+        if (manufacturer != null) {
+            checkArgument(manufacturer.length() <= MANUFACTURER_MAX_LENGTH,
+                    "manufacturer exceeds maximum length " + MANUFACTURER_MAX_LENGTH);
+        }
+        if (serialNumber != null) {
+            checkArgument(serialNumber.length() <= SERIAL_NUMBER_MAX_LENGTH,
+                    "serialNumber exceeds maximum length " + SERIAL_NUMBER_MAX_LENGTH);
+        }
+
         this.manufacturer = manufacturer;
         this.hwVersion = hwVersion;
         this.swVersion = swVersion;
diff --git a/core/store/dist/src/main/java/org/onosproject/store/link/impl/CoreConfig.java b/core/store/dist/src/main/java/org/onosproject/store/link/impl/CoreConfig.java
index 751c597..9123f6a 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/link/impl/CoreConfig.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/link/impl/CoreConfig.java
@@ -24,6 +24,12 @@
 
     protected static final String DEFAULT_LINK_DISCOVERY_MODE = "PERMISSIVE";
 
+    @Override
+    public boolean isValid() {
+        linkDiscoveryMode();
+        return hasOnlyFields(LINK_DISCOVERY_MODE);
+    }
+
     /**
      * Returns the link discovery mode.
      *