sqoop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jar...@apache.org
Subject [2/3] sqoop git commit: SQOOP-1442: Sqoop2: Validations: Serialize validations over the wire for client transfer
Date Wed, 14 Oct 2015 00:00:30 GMT
http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java b/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java
index b188c4c..90eaf1e 100644
--- a/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java
+++ b/common/src/test/java/org/apache/sqoop/json/util/TestConfigSerialization.java
@@ -21,6 +21,8 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -41,6 +43,8 @@ import org.apache.sqoop.model.MListInput;
 import org.apache.sqoop.model.MLongInput;
 import org.apache.sqoop.model.MMapInput;
 import org.apache.sqoop.model.MStringInput;
+import org.apache.sqoop.model.MValidator;
+import org.apache.sqoop.validation.validators.AbstractValidator;
 import org.joda.time.DateTime;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
@@ -82,6 +86,18 @@ public class TestConfigSerialization {
     assertEquals(1, (int)retrieved.getIntegerInput("Integer").getValue());
     assertEquals(true, retrieved.getBooleanInput("Boolean").getValue().booleanValue());
     assertEquals("YES", retrieved.getEnumInput("Enum").getValue());
+
+    // Verify all expected input validators
+    assertEquals(Collections.EMPTY_LIST, retrieved.getStringInput("String")
+      .getValidators());
+    assertEquals(buildMValidators(), retrieved.getMapInput("Map")
+      .getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getIntegerInput("Integer").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getBooleanInput("Boolean").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getEnumInput("Enum").getValidators());
+
+    // Verify config validators
+    assertEquals(buildMValidators(), config.getValidators());
   }
 
   @Test
@@ -204,6 +220,18 @@ public class TestConfigSerialization {
     assertEquals("YES", retrieved.getEnumInput("Enum").getValue());
     assertEquals(list, retrieved.getListInput("List").getValue());
     assertEquals(dt, retrieved.getDateTimeInput("DateTime").getValue());
+
+    // Verify all expected input validators
+    assertEquals(Collections.EMPTY_LIST, retrieved.getStringInput("String").getValidators());
+    assertEquals(buildMValidators(), retrieved.getMapInput("Map").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getIntegerInput("Integer").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getBooleanInput("Boolean").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getEnumInput("Enum").getValidators());
+    assertEquals(Collections.EMPTY_LIST, retrieved.getListInput("List").getValidators());
+    assertEquals(buildMValidators(), retrieved.getDateTimeInput("DateTime").getValidators());
+
+    // Verify config validators
+    assertEquals(buildMValidators(), config.getValidators());
   }
 
   protected MConfig getMapConfig() {
@@ -212,10 +240,10 @@ public class TestConfigSerialization {
 
     inputs = new LinkedList<MInput<?>>();
 
-    input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, "A");
+    input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, "A", Collections.EMPTY_LIST);
     inputs.add(input);
 
-    return new MConfig("c", inputs);
+    return new MConfig("c", inputs, Collections.EMPTY_LIST);
   }
 
   /**
@@ -227,32 +255,43 @@ public class TestConfigSerialization {
     List<MInput<?>> inputs;
     MInput<?> input;
 
+    List<MValidator> mValidatorsForInput = buildMValidators();
+
     inputs = new LinkedList<MInput<?>>();
 
-    input = new MStringInput("String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30);
+    input = new MStringInput("String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, mValidatorsForInput);
     inputs.add(input);
 
-    input = new MIntegerInput("Integer", false, InputEditable.ANY, StringUtils.EMPTY);
+    input = new MIntegerInput("Integer", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MLongInput("Long", false, InputEditable.ANY, StringUtils.EMPTY);
+    input = new MLongInput("Long", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MBooleanInput("Boolean", false, InputEditable.ANY, StringUtils.EMPTY);
+    input = new MBooleanInput("Boolean", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MEnumInput("Enum", false, InputEditable.ANY, StringUtils.EMPTY, new String[] {"YES", "NO"});
+    input = new MEnumInput("Enum", false, InputEditable.ANY, StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MListInput("List", false, InputEditable.ANY, StringUtils.EMPTY);
+    input = new MListInput("List", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     inputs.add(input);
 
-    input = new MDateTimeInput("DateTime", false, InputEditable.ANY, StringUtils.EMPTY);
+    input = new MDateTimeInput("DateTime", false, InputEditable.ANY, StringUtils.EMPTY, mValidatorsForInput);
     inputs.add(input);
 
-    return new MConfig("c", inputs);
+    List<MValidator> mValidatorsForConfig = buildMValidators();
+
+    return new MConfig("c", inputs, mValidatorsForConfig);
+  }
+
+  protected List<MValidator> buildMValidators() {
+    List<MValidator> mValidators = new ArrayList<>();
+    mValidators.add(new MValidator("validator1", AbstractValidator.DEFAULT_STRING_ARGUMENT));
+    mValidators.add(new MValidator("validator1", "strarg"));
+    return mValidators;
   }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java b/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java
index 9ee0eec..d5f17f4 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestConfigUtils.java
@@ -17,6 +17,9 @@
  */
 package org.apache.sqoop.model;
 
+import com.google.common.base.Strings;
+import org.apache.sqoop.validation.Status;
+import org.apache.sqoop.validation.validators.AbstractValidator;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -24,7 +27,9 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -45,10 +50,18 @@ public class TestConfigUtils {
     config.aConfig.a1 = "value";
     config.cConfig.enumeration = Enumeration.X;
 
+    List<MValidator> expectedValidatorsOnAConfig = new ArrayList<>();
+    expectedValidatorsOnAConfig.add(new MValidator(AConfig.AConfigValidator.class.getName(), AbstractValidator.DEFAULT_STRING_ARGUMENT));
+
+    List<MValidator> expectedValidatorsOnA1 = new ArrayList<>();
+    expectedValidatorsOnA1.add(new MValidator(AConfig.A1Validator.class.getName(), AbstractValidator.DEFAULT_STRING_ARGUMENT));
+
     List<MConfig> configsByInstance = ConfigUtils.toConfigs(config);
     assertEquals(getConfigs(), configsByInstance);
     assertEquals("value", configsByInstance.get(0).getInputs().get(0).getValue());
+    assertEquals(expectedValidatorsOnA1, configsByInstance.get(0).getInputs().get(0).getValidators());
     assertEquals("X", configsByInstance.get(2).getInput("cConfig.enumeration").getValue());
+    assertEquals(expectedValidatorsOnAConfig, configsByInstance.get(0).getValidators());
 
     List<MConfig> configsByClass = ConfigUtils.toConfigs(TestConfiguration.class);
     assertEquals(getConfigs(), configsByClass);
@@ -229,28 +242,28 @@ public class TestConfigUtils {
     // Config A
     inputs = new LinkedList<MInput<?>>();
     inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, StringUtils.EMPTY,
-        (short) 30));
+        (short) 30, Collections.EMPTY_LIST));
     inputs.add(new MStringInput("aConfig.a2", true, InputEditable.ANY, StringUtils.EMPTY,
-        (short) -1));
-    ret.add(new MConfig("aConfig", inputs));
+        (short) -1, Collections.EMPTY_LIST));
+    ret.add(new MConfig("aConfig", inputs, Collections.EMPTY_LIST));
 
     // Config B
     inputs = new LinkedList<MInput<?>>();
     inputs.add(new MStringInput("bConfig.b1", false, InputEditable.ANY, StringUtils.EMPTY,
-        (short) 2));
+        (short) 2, Collections.EMPTY_LIST));
     inputs.add(new MStringInput("bConfig.b2", false, InputEditable.ANY, StringUtils.EMPTY,
-        (short) 3));
-    ret.add(new MConfig("bConfig", inputs));
+        (short) 3, Collections.EMPTY_LIST));
+    ret.add(new MConfig("bConfig", inputs, Collections.EMPTY_LIST));
 
     // Config C
     inputs = new LinkedList<MInput<?>>();
-    inputs.add(new MLongInput("cConfig.longValue", false, InputEditable.ANY, StringUtils.EMPTY));
-    inputs.add(new MMapInput("cConfig.map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY));
+    inputs.add(new MLongInput("cConfig.longValue", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
+    inputs.add(new MMapInput("cConfig.map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST));
     inputs.add(new MEnumInput("cConfig.enumeration", false, InputEditable.ANY, StringUtils.EMPTY,
-        new String[] { "X", "Y" }));
-    inputs.add(new MListInput("cConfig.list", false, InputEditable.ANY, StringUtils.EMPTY));
-    inputs.add(new MDateTimeInput("cConfig.dt", false, InputEditable.ANY, StringUtils.EMPTY));
-    ret.add(new MConfig("cConfig", inputs));
+        new String[] { "X", "Y" }, Collections.EMPTY_LIST));
+    inputs.add(new MListInput("cConfig.list", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
+    inputs.add(new MDateTimeInput("cConfig.dt", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST));
+    ret.add(new MConfig("cConfig", inputs, Collections.EMPTY_LIST));
 
     return ret;
   }
@@ -261,10 +274,10 @@ public class TestConfigUtils {
     List<MInput<?>> inputs;
     // Config A
     inputs = new LinkedList<MInput<?>>();
-    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a1", (short) 30));
+    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a1", (short) 30, Collections.EMPTY_LIST));
     inputs.add(new MStringInput("aConfig.a2", true, InputEditable.ANY, StringUtils.EMPTY,
-        (short) -1));
-    ret.add(new MConfig("aConfig", inputs));
+        (short) -1, Collections.EMPTY_LIST));
+    ret.add(new MConfig("aConfig", inputs, Collections.EMPTY_LIST));
     return ret;
   }
 
@@ -274,10 +287,10 @@ public class TestConfigUtils {
     List<MInput<?>> inputs;
     // Config A
     inputs = new LinkedList<MInput<?>>();
-    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a3", (short) 30));
+    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a3", (short) 30, Collections.EMPTY_LIST));
     inputs.add(new MStringInput("aConfig.a2", true, InputEditable.ANY, StringUtils.EMPTY,
-        (short) -1));
-    ret.add(new MConfig("aConfig", inputs));
+        (short) -1, Collections.EMPTY_LIST));
+    ret.add(new MConfig("aConfig", inputs, Collections.EMPTY_LIST));
     return ret;
   }
 
@@ -287,10 +300,10 @@ public class TestConfigUtils {
     List<MInput<?>> inputs;
     // Config A
     inputs = new LinkedList<MInput<?>>();
-    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a2", (short) 30));
+    inputs.add(new MStringInput("aConfig.a1", false, InputEditable.ANY, "aConfig.a2", (short) 30, Collections.EMPTY_LIST));
     inputs.add(new MStringInput("aConfig.a2", true, InputEditable.USER_ONLY, StringUtils.EMPTY,
-        (short) -1));
-    ret.add(new MConfig("aConfig", inputs));
+        (short) -1, Collections.EMPTY_LIST));
+    ret.add(new MConfig("aConfig", inputs, Collections.EMPTY_LIST));
     return ret;
   }
 
@@ -383,12 +396,30 @@ public class TestConfigUtils {
     DConfig dConfig;
   }
 
-  @ConfigClass
+  @ConfigClass(validators = {@Validator(AConfig.AConfigValidator.class)})
   public static class AConfig {
-    @Input(size = 30)
+    @Input(size = 30, validators = {@Validator(AConfig.A1Validator.class)})
     String a1;
     @Input(sensitive = true)
     String a2;
+
+    public static class AConfigValidator extends AbstractValidator<AConfig> {
+      @Override
+      public void validate(AConfig aConfig) {
+        if (Strings.isNullOrEmpty(aConfig.a1)) {
+          addMessage(Status.ERROR, "a1 cannot be empty");
+        }
+      }
+    }
+
+    public static class A1Validator extends AbstractValidator<String> {
+      @Override
+      public void validate(String a1) {
+        if (Strings.isNullOrEmpty(a1)) {
+          addMessage(Status.ERROR, "I am a redundant validator");
+        }
+      }
+    }
   }
 
   @ConfigClass

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMAccountableEntity.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMAccountableEntity.java b/common/src/test/java/org/apache/sqoop/model/TestMAccountableEntity.java
index 4113b50..5bf2465 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMAccountableEntity.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMAccountableEntity.java
@@ -18,6 +18,7 @@
 package org.apache.sqoop.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
@@ -37,15 +38,20 @@ public class TestMAccountableEntity {
   @Test
   public void testInitialization() {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MIntegerInput intInput = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
-    MLongInput longInput = new MLongInput("LONG-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput intInput = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MLongInput longInput = new MLongInput("LONG-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(intInput);
     list.add(longInput);
 
-    MConfig config = new MConfig("CONFIGNAME", list);
+    MConfig config = new MConfig("CONFIGNAME", list, Collections.EMPTY_LIST);
     configs.add(config);
-    MAccountableEntity link = new MLink(123l, new MLinkConfig(configs));
+
+    List<MValidator> validators = new ArrayList<>();
+    MValidator validator = new MValidator("test", "");
+    validators.add(validator);
+
+    MAccountableEntity link = new MLink(123l, new MLinkConfig(configs, validators));
     // Initially creation date and last update date is same
     assertEquals(link.getCreationDate(), link.getLastUpdateDate());
     Date testCreationDate = new Date();
@@ -63,5 +69,6 @@ public class TestMAccountableEntity {
     assertEquals(1, ((MLink) link).getConnectorLinkConfig().getConfigs().size());
     assertEquals(2, ((MLink) link).getConnectorLinkConfig().getConfigs().get(0).getInputs().size());
 
+    assertEquals(validator, ((MLink) link).getConnectorLinkConfig().getValidators().get(0));
   }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMBooleanInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMBooleanInput.java b/common/src/test/java/org/apache/sqoop/model/TestMBooleanInput.java
index d659c9e..020aebe 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMBooleanInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMBooleanInput.java
@@ -20,6 +20,8 @@ package org.apache.sqoop.model;
 import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNull;
@@ -36,7 +38,7 @@ public class TestMBooleanInput {
   @Test
   public void testInitialization() {
     MBooleanInput input = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY);
+        StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(true, input.isSensitive());
     assertEquals(MInputType.BOOLEAN, input.getType());
@@ -49,18 +51,18 @@ public class TestMBooleanInput {
   public void testEquals() {
     // Positive test
     MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY);
+        StringUtils.EMPTY, Collections.EMPTY_LIST);
     MBooleanInput input2 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY);
+        StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
-    MBooleanInput input3 = new MBooleanInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY );
-    MBooleanInput input4 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY );
+    MBooleanInput input3 = new MBooleanInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MBooleanInput input4 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     assertFalse(input3.equals(input4));
 
-    MBooleanInput input5 = new MBooleanInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY );
-    MBooleanInput input6 = new MBooleanInput("sqoop", false, InputEditable.ANY, StringUtils.EMPTY );
+    MBooleanInput input5 = new MBooleanInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MBooleanInput input6 = new MBooleanInput("sqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     assertFalse(input5.equals(input6));
   }
 
@@ -69,7 +71,7 @@ public class TestMBooleanInput {
    */
   @Test
   public void testValue() {
-    MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY );
+    MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     input1.setValue(true);
     assertEquals(true, input1.getValue().booleanValue());
     input1.setEmpty();
@@ -81,7 +83,7 @@ public class TestMBooleanInput {
    */
   @Test
   public void testUrlSafe() {
-    MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY );
+    MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     input1.setValue(true);
     // Getting URL safe string
     String tmp = input1.getUrlSafeValueString();
@@ -96,7 +98,7 @@ public class TestMBooleanInput {
   @Test
   public void testNamedElement() {
     MBooleanInput input1 = new MBooleanInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY);
+        StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMConfig.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConfig.java b/common/src/test/java/org/apache/sqoop/model/TestMConfig.java
index 00b4a46..e41fc0e 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMConfig.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMConfig.java
@@ -18,6 +18,7 @@
 package org.apache.sqoop.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
@@ -32,13 +33,13 @@ public class TestMConfig {
    */
   @Test
   public void testInitialization() {
-    MInput<String> input1 = new MStringInput("sqoopsqoop1", true, InputEditable.ANY, StringUtils.EMPTY , (short) 5);
-    MInput<String> input2 = new MStringInput("sqoopsqoop2", true, InputEditable.ANY, StringUtils.EMPTY , (short) 5);
+    MInput<String> input1 = new MStringInput("sqoopsqoop1", true, InputEditable.ANY, StringUtils.EMPTY , (short) 5, Collections.EMPTY_LIST);
+    MInput<String> input2 = new MStringInput("sqoopsqoop2", true, InputEditable.ANY, StringUtils.EMPTY , (short) 5, Collections.EMPTY_LIST);
 
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input1);
     list.add(input2);
-    MConfig mConfig = new MConfig("config", list);
+    MConfig mConfig = new MConfig("config", list, Collections.EMPTY_LIST);
 
     assertEquals("config", mConfig.getName());
     assertEquals(2, mConfig.getInputs().size());
@@ -49,33 +50,33 @@ public class TestMConfig {
    */
   @Test
   public void testEquals() {
-    MInput<Integer> input1 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY );
-    MInput<Integer> input2 = new MIntegerInput("sqoopsqoop2", false, InputEditable.ANY, StringUtils.EMPTY );
+    MInput<Integer> input1 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY , Collections.EMPTY_LIST);
+    MInput<Integer> input2 = new MIntegerInput("sqoopsqoop2", false, InputEditable.ANY, StringUtils.EMPTY , Collections.EMPTY_LIST);
     List<MInput<?>> list1 = new ArrayList<MInput<?>>();
     list1.add(input1);
     list1.add(input2);
-    MConfig mConfig1 = new MConfig("config", list1);
+    MConfig mConfig1 = new MConfig("config", list1, Collections.EMPTY_LIST);
 
-    MInput<Integer> input3 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY );
-    MInput<Integer> input4 = new MIntegerInput("sqoopsqoop2", false, InputEditable.ANY, StringUtils.EMPTY );
+    MInput<Integer> input3 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY , Collections.EMPTY_LIST);
+    MInput<Integer> input4 = new MIntegerInput("sqoopsqoop2", false, InputEditable.ANY, StringUtils.EMPTY , Collections.EMPTY_LIST);
     List<MInput<?>> list2 = new ArrayList<MInput<?>>();
     list2.add(input3);
     list2.add(input4);
-    MConfig mConfig2 = new MConfig("config", list2);
+    MConfig mConfig2 = new MConfig("config", list2, Collections.EMPTY_LIST);
     assertEquals(mConfig2, mConfig1);
   }
 
   @Test
   public void testGetInputs() {
-    MIntegerInput intInput = new MIntegerInput("Config.A", false, InputEditable.ANY, StringUtils.EMPTY );
-    MLongInput longInput = new MLongInput("Config.A1", false, InputEditable.ANY, StringUtils.EMPTY );
-    MMapInput mapInput = new MMapInput("Config.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
+    MIntegerInput intInput = new MIntegerInput("Config.A", false, InputEditable.ANY, StringUtils.EMPTY , Collections.EMPTY_LIST);
+    MLongInput longInput = new MLongInput("Config.A1", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MMapInput mapInput = new MMapInput("Config.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY , Collections.EMPTY_LIST);
     MStringInput stringInput = new MStringInput("Config.C", false, InputEditable.ANY,
-        StringUtils.EMPTY, (short) 3);
+        StringUtils.EMPTY, (short) 3, Collections.EMPTY_LIST);
     MEnumInput enumInput = new MEnumInput("Config.D", false, InputEditable.ANY, StringUtils.EMPTY,
-        new String[] { "I", "V" });
-    MListInput listInput = new MListInput("Config.E", false, InputEditable.ANY, StringUtils.EMPTY );
-    MDateTimeInput dtInput = new MDateTimeInput("Config.F", false, InputEditable.ANY, StringUtils.EMPTY );
+        new String[] { "I", "V" }, Collections.EMPTY_LIST);
+    MListInput listInput = new MListInput("Config.E", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MDateTimeInput dtInput = new MDateTimeInput("Config.F", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
 
     List<MInput<?>> inputs = new ArrayList<MInput<?>>();
     inputs.add(intInput);
@@ -86,7 +87,7 @@ public class TestMConfig {
     inputs.add(listInput);
     inputs.add(dtInput);
 
-    MConfig config = new MConfig("Config", inputs);
+    MConfig config = new MConfig("Config", inputs, Collections.EMPTY_LIST);
     assertEquals(intInput, config.getIntegerInput("Config.A"));
     assertEquals(longInput, config.getLongInput("Config.A1"));
     assertEquals(mapInput, config.getMapInput("Config.B"));

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java b/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java
index 0d2ff61..55afd07 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMConfigList.java
@@ -21,6 +21,7 @@ import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -31,29 +32,29 @@ public class TestMConfigList {
   public void testGetInputs() {
     List<MConfig> configs = new LinkedList<MConfig>();
 
-    MIntegerInput intInput = new MIntegerInput("Config1.A", false, InputEditable.ANY, StringUtils.EMPTY);
-    MMapInput mapInput = new MMapInput("Config1.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MIntegerInput intInput = new MIntegerInput("Config1.A", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MMapInput mapInput = new MMapInput("Config1.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
 
     List<MInput<?>> inputs = new ArrayList<MInput<?>>();
     inputs.add(intInput);
     inputs.add(mapInput);
-    configs.add(new MConfig("Config1", inputs));
+    configs.add(new MConfig("Config1", inputs, Collections.EMPTY_LIST));
 
     MStringInput stringInput = new MStringInput("Config2.C", false, InputEditable.ANY,
-        StringUtils.EMPTY, (short) 3);
+        StringUtils.EMPTY, (short) 3, Collections.EMPTY_LIST);
     MEnumInput enumInput = new MEnumInput("Config2.D", false, InputEditable.ANY, StringUtils.EMPTY,
-        new String[] { "I", "V" });
-    MListInput listInput = new MListInput("Config2.E", false, InputEditable.ANY, StringUtils.EMPTY);
-    MDateTimeInput dtInput = new MDateTimeInput("Config2.F", false, InputEditable.ANY, StringUtils.EMPTY);
+        new String[] { "I", "V" }, Collections.EMPTY_LIST);
+    MListInput listInput = new MListInput("Config2.E", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MDateTimeInput dtInput = new MDateTimeInput("Config2.F", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
 
     inputs = new ArrayList<MInput<?>>();
     inputs.add(stringInput);
     inputs.add(enumInput);
     inputs.add(listInput);
     inputs.add(dtInput);
-    configs.add(new MConfig("Config2", inputs));
+    configs.add(new MConfig("Config2", inputs, Collections.EMPTY_LIST));
 
-    MConfigList config = new MConfigList(configs, MConfigType.JOB);
+    MConfigList config = new MConfigList(configs, MConfigType.JOB, Collections.EMPTY_LIST);
     assertEquals(intInput, config.getIntegerInput("Config1.A"));
     assertEquals(mapInput, config.getMapInput("Config1.B"));
     assertEquals(stringInput, config.getStringInput("Config2.C"));

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
index d996692..4c6f247 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMConnector.java
@@ -26,6 +26,7 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
@@ -36,26 +37,29 @@ public class TestMConnector {
 
   private MConnector createConnector(List<Direction> supportedDirections) {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MIntegerInput inputs = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput inputs = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     inputs.setValue(100);
-    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20, Collections.EMPTY_LIST);
     strInput.setValue("TEST-VALUE");
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(inputs);
     list.add(strInput);
-    MConfig config = new MConfig("CONFIGNAME", list);
+    MConfig config = new MConfig("CONFIGNAME", list, Collections.EMPTY_LIST);
     configs.add(config);
 
-    MLinkConfig linkConfig = new MLinkConfig(configs);
+    List<MValidator> validators = new ArrayList<>();
+    validators.add(new MValidator("test", ""));
+
+    MLinkConfig linkConfig = new MLinkConfig(configs, validators);
     MFromConfig fromConfig = null;
     MToConfig toConfig = null;
 
     if (supportedDirections.contains(Direction.FROM)) {
-      fromConfig = new MFromConfig(configs);
+      fromConfig = new MFromConfig(configs, validators);
     }
 
     if (supportedDirections.contains(Direction.TO)) {
-      toConfig = new MToConfig(configs);
+      toConfig = new MToConfig(configs, validators);
     }
 
     return new MConnector("NAME", "CLASSNAME", "1.0",
@@ -67,11 +71,13 @@ public class TestMConnector {
    */
   @Test
   public void testInitialization() {
-    List<MConfig> fromJobConfig = new ArrayList<MConfig>();
-    List<MConfig> toJobConfig = new ArrayList<MConfig>();
-    MLinkConfig linkConfig = new MLinkConfig(fromJobConfig);
-    MFromConfig fromConfig1 = new MFromConfig(fromJobConfig);
-    MToConfig toConfig1 = new MToConfig(toJobConfig);
+    List<MConfig> fromJobConfig = new ArrayList<>();
+    List<MValidator> fromValidators = new ArrayList<>();
+    List<MConfig> toJobConfig = new ArrayList<>();
+    List<MValidator> toValidators = new ArrayList<>();
+    MLinkConfig linkConfig = new MLinkConfig(fromJobConfig, fromValidators);
+    MFromConfig fromConfig1 = new MFromConfig(fromJobConfig, fromValidators);
+    MToConfig toConfig1 = new MToConfig(toJobConfig, toValidators);
     MConnector connector1 = new MConnector("NAME", "CLASSNAME", "1.0",
         linkConfig, fromConfig1, toConfig1);
     assertEquals("NAME", connector1.getUniqueName());

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java b/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java
index 9c110cd..b429dc3 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMDateTimeInput.java
@@ -27,6 +27,8 @@ import org.apache.commons.lang.StringUtils;
 import org.joda.time.DateTime;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 /**
  * Test class for org.apache.sqoop.model.MDateTimeInput
  */
@@ -36,7 +38,7 @@ public class TestMDateTimeInput {
    */
   @Test
   public void testInitialization() {
-    MDateTimeInput input = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(MInputType.DATETIME, input.getType());
   }
@@ -47,13 +49,13 @@ public class TestMDateTimeInput {
   @Test
   public void testEquals() {
     // Positive test
-    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MDateTimeInput input2 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MDateTimeInput input2 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
-    MDateTimeInput input3 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MDateTimeInput input4 = new MDateTimeInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input3 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MDateTimeInput input4 = new MDateTimeInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertFalse(input3.equals(input4));
   }
 
@@ -62,7 +64,7 @@ public class TestMDateTimeInput {
    */
   @Test
   public void testValue() {
-    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
 
     //  Test for long format
     DateTime dt = new DateTime(1234567L);
@@ -83,7 +85,7 @@ public class TestMDateTimeInput {
    */
   @Test
   public void testUrlSafe() {
-    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     DateTime dt = new DateTime(1234567L);
     input1.setValue(dt);
     // Getting URL safe string
@@ -104,7 +106,7 @@ public class TestMDateTimeInput {
    */
   @Test
   public void testNamedElement() {
-    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY);
+    MDateTimeInput input1 = new MDateTimeInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }
@@ -114,8 +116,8 @@ public class TestMDateTimeInput {
    */
   @Test
   public void testSensitivity() {
-    MDateTimeInput input1 = new MDateTimeInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY );
-    MDateTimeInput input2 = new MDateTimeInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY );
+    MDateTimeInput input1 = new MDateTimeInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MDateTimeInput input2 = new MDateTimeInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     assertFalse(input1.isSensitive());
     assertTrue(input2.isSensitive());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMDriver.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMDriver.java b/common/src/test/java/org/apache/sqoop/model/TestMDriver.java
index f947a60..788f13c 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMDriver.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMDriver.java
@@ -20,6 +20,7 @@ package org.apache.sqoop.model;
 import static org.testng.Assert.assertEquals;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.sqoop.json.DriverBean;
@@ -29,12 +30,18 @@ public class TestMDriver {
 
   @Test
   public void testDriver() {
-    List<MConfig> driverConfig = new ArrayList<MConfig>();
-    driverConfig.add(new MConfig("driver-test", new ArrayList<MInput<?>>()));
-    MDriverConfig mDriverConfig = new MDriverConfig(driverConfig);
+    List<MConfig> driverConfig = new ArrayList<>();
+    driverConfig.add(new MConfig("driver-test", new ArrayList<MInput<?>>(), Collections.EMPTY_LIST));
+
+    List<MValidator> driverValidators = new ArrayList<>();
+    driverValidators.add(new MValidator("test", ""));
+
+    MDriverConfig mDriverConfig = new MDriverConfig(driverConfig, driverValidators);
 
     MDriver driver = new MDriver(mDriverConfig, DriverBean.CURRENT_DRIVER_VERSION);
     assertEquals(1, driver.getDriverConfig().getConfigs().size());
     assertEquals("driver-test", driver.getDriverConfig().getConfigs().get(0).getName());
+    assertEquals("test", driver.getDriverConfig().getValidators().get(0).getValidatorClass());
+    assertEquals("", driver.getDriverConfig().getValidators().get(0).getStrArg());
   }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMEnumInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMEnumInput.java b/common/src/test/java/org/apache/sqoop/model/TestMEnumInput.java
index 6f588ef..adf8956 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMEnumInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMEnumInput.java
@@ -20,6 +20,8 @@ package org.apache.sqoop.model;
 import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
@@ -36,19 +38,19 @@ public class TestMEnumInput {
   @Test
   public void testInitialization() {
     String[] values = { "value1", "value2" };
-    MEnumInput input = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values);
+    MEnumInput input = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values, Collections.EMPTY_LIST);
     assertEquals("NAME", input.getName());
     assertEquals(values, input.getValues());
     assertEquals(MInputType.ENUM, input.getType());
 
-    MEnumInput input1 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values);
+    MEnumInput input1 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values, Collections.EMPTY_LIST);
     assertEquals(input1, input);
     String[] testVal = { "val", "test" };
     MEnumInput input2 = new MEnumInput("NAME1", false, InputEditable.ANY, StringUtils.EMPTY,
-        testVal);
+        testVal, Collections.EMPTY_LIST);
     assertFalse(input1.equals(input2));
 
-    MEnumInput input3 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values);
+    MEnumInput input3 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values, Collections.EMPTY_LIST);
     input3.setValue(Enumeration.value1);
     assertEquals("value1", input3.getValue());
   }
@@ -59,8 +61,8 @@ public class TestMEnumInput {
   @Test
   public void testSensitivity() {
     String[] values = { "value1", "value2" };
-    MEnumInput input1 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values);
-    MEnumInput input2 = new MEnumInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, values);
+    MEnumInput input1 = new MEnumInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, values, Collections.EMPTY_LIST);
+    MEnumInput input2 = new MEnumInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, values, Collections.EMPTY_LIST);
     assertFalse(input1.isSensitive());
     assertTrue(input2.isSensitive());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMIntegerInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMIntegerInput.java b/common/src/test/java/org/apache/sqoop/model/TestMIntegerInput.java
index aa5bdef..06de327 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMIntegerInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMIntegerInput.java
@@ -20,6 +20,8 @@ package org.apache.sqoop.model;
 import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNull;
@@ -34,7 +36,7 @@ public class TestMIntegerInput {
    */
   @Test
   public void testInitialization() {
-    MIntegerInput input = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(MInputType.INTEGER, input.getType());
   }
@@ -45,13 +47,13 @@ public class TestMIntegerInput {
   @Test
   public void testEquals() {
     // Positive test
-    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MIntegerInput input2 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MIntegerInput input2 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
-    MIntegerInput input3 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MIntegerInput input4 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input3 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MIntegerInput input4 = new MIntegerInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertFalse(input3.equals(input4));
   }
 
@@ -60,7 +62,7 @@ public class TestMIntegerInput {
    */
   @Test
   public void testValue() {
-    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     input1.setValue(99);
     assertEquals(new Integer(99), input1.getValue());
     input1.setEmpty();
@@ -72,7 +74,7 @@ public class TestMIntegerInput {
    */
   @Test
   public void testUrlSafe() {
-    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input1 = new MIntegerInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     input1.setValue(1001);
     // Getting URL safe string
     String tmp = input1.getUrlSafeValueString();
@@ -86,7 +88,7 @@ public class TestMIntegerInput {
    */
   @Test
   public void testNamedElement() {
-    MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.CONNECTOR_ONLY, StringUtils.EMPTY, (short) 5);
+    MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.CONNECTOR_ONLY, StringUtils.EMPTY, (short) 5, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }
@@ -96,8 +98,8 @@ public class TestMIntegerInput {
    */
   @Test
   public void testSensitivity() {
-    MIntegerInput input1 = new MIntegerInput("NAME", false, InputEditable.USER_ONLY, StringUtils.EMPTY);
-    MIntegerInput input2 = new MIntegerInput("NAME", true, InputEditable.CONNECTOR_ONLY, StringUtils.EMPTY);
+    MIntegerInput input1 = new MIntegerInput("NAME", false, InputEditable.USER_ONLY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MIntegerInput input2 = new MIntegerInput("NAME", true, InputEditable.CONNECTOR_ONLY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertFalse(input1.isSensitive());
     assertTrue(input2.isSensitive());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMJob.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMJob.java b/common/src/test/java/org/apache/sqoop/model/TestMJob.java
index 6867ead..17388cd 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMJob.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMJob.java
@@ -21,6 +21,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
@@ -105,37 +106,49 @@ public class TestMJob {
 
   private MFromConfig fromConfig() {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     input.setValue(100);
-    MLongInput lInput = new MLongInput("LONG-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
+    MLongInput lInput = new MLongInput("LONG-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     lInput.setValue(100L);
-    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20, Collections.EMPTY_LIST);
     strInput.setValue("TEST-VALUE");
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input);
     list.add(strInput);
-    MConfig config = new MConfig("CONFIGFROMNAME", list);
+    MConfig config = new MConfig("CONFIGFROMNAME", list, Collections.EMPTY_LIST);
     configs.add(config);
-    return new MFromConfig(configs);
+
+    List<MValidator> validators = new ArrayList<>();
+    validators.add(new MValidator("testValidator", ""));
+
+    return new MFromConfig(configs, validators);
   }
 
   private MToConfig toConfig() {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input);
-    MConfig config = new MConfig("CONFIGTONAME", list);
+    MConfig config = new MConfig("CONFIGTONAME", list, Collections.EMPTY_LIST);
     configs.add(config);
-    return new MToConfig(configs);
+
+    List<MValidator> validators = new ArrayList<>();
+
+    return new MToConfig(configs, validators);
   }
 
   private MDriverConfig driverConfig() {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input);
-    MConfig config = new MConfig("CONFIGDRIVERNAME", list);
+    MConfig config = new MConfig("CONFIGDRIVERNAME", list, Collections.EMPTY_LIST);
     configs.add(config);
-    return new MDriverConfig(configs);
+
+    List<MValidator> validators = new ArrayList<>();
+    validators.add(new MValidator("testValidator1", ""));
+    validators.add(new MValidator("testValidator2", "blah"));
+
+    return new MDriverConfig(configs, validators);
   }
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMJobConfig.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMJobConfig.java b/common/src/test/java/org/apache/sqoop/model/TestMJobConfig.java
index bc69c6c..2ab5f8d 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMJobConfig.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMJobConfig.java
@@ -18,6 +18,7 @@
 package org.apache.sqoop.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -30,12 +31,14 @@ public class TestMJobConfig {
    */
   @Test
   public void testInitialization() {
-    List<MConfig> configs = new ArrayList<MConfig>();
-    MFromConfig fromJobConfig = new MFromConfig(configs);
-    List<MConfig> configs2 = new ArrayList<MConfig>();
-    MFromConfig fromJobConfig2 = new MFromConfig(configs2);
+    List<MConfig> configs = new ArrayList<>();
+    List<MValidator> validators = new ArrayList<>();
+    MFromConfig fromJobConfig = new MFromConfig(configs, validators);
+    List<MConfig> configs2 = new ArrayList<>();
+    List<MValidator> validators2 = new ArrayList<>();
+    MFromConfig fromJobConfig2 = new MFromConfig(configs2, validators2);
     assertEquals(fromJobConfig2, fromJobConfig);
-    MConfig c = new MConfig("test", null);
+    MConfig c = new MConfig("test", null, Collections.EMPTY_LIST);
     configs2.add(c);
     assertFalse(fromJobConfig.equals(fromJobConfig2));
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMLink.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMLink.java b/common/src/test/java/org/apache/sqoop/model/TestMLink.java
index f22719f..b5df18a 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMLink.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMLink.java
@@ -18,6 +18,7 @@
 package org.apache.sqoop.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
@@ -82,16 +83,20 @@ public class TestMLink {
 
   private MLinkConfig linkConfig() {
     List<MConfig> configs = new ArrayList<MConfig>();
-    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
+    MIntegerInput input = new MIntegerInput("INTEGER-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     input.setValue(100);
-    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20);
+    MStringInput strInput = new MStringInput("STRING-INPUT",false, InputEditable.ANY, StringUtils.EMPTY, (short)20, Collections.EMPTY_LIST);
     strInput.setValue("TEST-VALUE");
     List<MInput<?>> list = new ArrayList<MInput<?>>();
     list.add(input);
     list.add(strInput);
-    MConfig config = new MConfig("CONFIGNAME", list);
+    MConfig config = new MConfig("CONFIGNAME", list, Collections.EMPTY_LIST);
     configs.add(config);
-    return new MLinkConfig(configs);
+
+    List<MValidator> validators = new ArrayList<>();
+    validators.add(new MValidator("test", ""));
+
+    return new MLinkConfig(configs, validators);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMLinkConfig.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMLinkConfig.java b/common/src/test/java/org/apache/sqoop/model/TestMLinkConfig.java
index 7056f49..e38ae54 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMLinkConfig.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMLinkConfig.java
@@ -18,6 +18,7 @@
 package org.apache.sqoop.model;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -31,14 +32,16 @@ public class TestMLinkConfig {
    */
   @Test
   public void testInitialization() {
-    List<MConfig> configs = new ArrayList<MConfig>();
-    MLinkConfig linkConfig = new MLinkConfig(configs);
-    List<MConfig> testConfig = new ArrayList<MConfig>();
+    List<MConfig> configs = new ArrayList<>();
+    List<MValidator> validators = new ArrayList<>();
+    MLinkConfig linkConfig = new MLinkConfig(configs, validators);
+    List<MConfig> testConfig = new ArrayList<>();
+    List<MValidator> testValidator = new ArrayList<>();
     assertEquals(testConfig, linkConfig.getConfigs());
-    MLinkConfig linkConfig2 = new MLinkConfig(testConfig);
+    MLinkConfig linkConfig2 = new MLinkConfig(testConfig, testValidator);
     assertEquals(linkConfig2, linkConfig);
     // Add a config to list for checking not equals
-    MConfig c = new MConfig("test", null);
+    MConfig c = new MConfig("test", null, Collections.EMPTY_LIST);
     testConfig.add(c);
     assertFalse(linkConfig.equals(linkConfig2));
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMListInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMListInput.java b/common/src/test/java/org/apache/sqoop/model/TestMListInput.java
index decf927..2183375 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMListInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMListInput.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -38,7 +39,7 @@ public class TestMListInput {
    */
   @Test
   public void testInitialization() {
-    MListInput input = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(MInputType.LIST, input.getType());
   }
@@ -49,13 +50,13 @@ public class TestMListInput {
   @Test
   public void testEquals() {
     // Positive test
-    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MListInput input2 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MListInput input2 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
-    MListInput input3 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
-    MListInput input4 = new MListInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input3 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MListInput input4 = new MListInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertFalse(input3.equals(input4));
   }
 
@@ -64,7 +65,7 @@ public class TestMListInput {
    */
   @Test
   public void testValue() {
-    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     List<String> list = new LinkedList<String>();
     input1.setValue(list);
     assertEquals(list, input1.getValue());
@@ -77,7 +78,7 @@ public class TestMListInput {
    */
   @Test
   public void testUrlSafe() {
-    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input1 = new MListInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     List<String> list = new LinkedList<String>();
     input1.setValue(list);
     // Getting URL safe string
@@ -98,7 +99,7 @@ public class TestMListInput {
    */
   @Test
   public void testNamedElement() {
-    MListInput input1 = new MListInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY);
+    MListInput input1 = new MListInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }
@@ -108,8 +109,8 @@ public class TestMListInput {
    */
   @Test
   public void testSensitivity() {
-    MListInput input1 = new MListInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY );
-    MListInput input2 = new MListInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY );
+    MListInput input1 = new MListInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
+    MListInput input2 = new MListInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST );
     assertFalse(input1.isSensitive());
     assertTrue(input2.isSensitive());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMMapInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMMapInput.java b/common/src/test/java/org/apache/sqoop/model/TestMMapInput.java
index 6c2b7e6..c2aa84f 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMMapInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMMapInput.java
@@ -17,6 +17,7 @@
  */
 package org.apache.sqoop.model;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -38,7 +39,7 @@ public class TestMMapInput {
    */
   @Test
   public void testInitialization() {
-    MMapInput input = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(MInputType.MAP, input.getType());
   }
@@ -49,13 +50,13 @@ public class TestMMapInput {
   @Test
   public void testEquals() {
     // Positive test
-    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
-    MMapInput input2 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MMapInput input2 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
-    MMapInput input3 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
-    MMapInput input4 = new MMapInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input3 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    MMapInput input4 = new MMapInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertFalse(input3.equals(input4));
   }
 
@@ -64,7 +65,7 @@ public class TestMMapInput {
    */
   @Test
   public void testValue() {
-    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     Map<String, String> map1 = new HashMap<String, String>();
     input1.setValue(map1);
     assertEquals(map1, input1.getValue());
@@ -77,7 +78,7 @@ public class TestMMapInput {
    */
   @Test
   public void testUrlSafe() {
-    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     Map<String, String> map1 = new HashMap<String, String>();
     input1.setValue(map1);
     // Getting URL safe string
@@ -98,7 +99,7 @@ public class TestMMapInput {
    */
   @Test
   public void testNamedElement() {
-    MMapInput input1 = new MMapInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
+    MMapInput input1 = new MMapInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }
@@ -108,8 +109,8 @@ public class TestMMapInput {
    */
   @Test
   public void testSensitivity() {
-    MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
-    MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
+    MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY , Collections.EMPTY_LIST);
+    MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY , Collections.EMPTY_LIST);
     assertFalse(input1.isSensitive());
     assertTrue(input2.isSensitive());
   }
@@ -123,9 +124,9 @@ public class TestMMapInput {
     testValue.put("sqoop features", "awesome features");
     testValue.put("sqoop bugs", "horrible bugs");
 
-    MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
+    MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY , Collections.EMPTY_LIST);
     input1.setValue(testValue);
-    MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, ".*bugs.*");
+    MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, ".*bugs.*", Collections.EMPTY_LIST);
     input2.setValue(testValue);
 
     assertEquals(input1.getNonsenstiveValue(), testValue);

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMNamedElement.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMNamedElement.java b/common/src/test/java/org/apache/sqoop/model/TestMNamedElement.java
index c523d65..8556302 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMNamedElement.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMNamedElement.java
@@ -20,6 +20,8 @@ package org.apache.sqoop.model;
 import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 import static org.testng.Assert.*;
 
 /**
@@ -32,7 +34,7 @@ public class TestMNamedElement {
    */
   @Test
   public void testInitialization() {
-    MNamedElement named = new MIntegerInput("SQOOP", false, InputEditable.ANY, StringUtils.EMPTY);
+    MNamedElement named = new MIntegerInput("SQOOP", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
     assertEquals("SQOOP", named.getName());
     assertEquals("SQOOP.label", named.getLabelKey());
     assertEquals("SQOOP.help", named.getHelpKey());

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMStringInput.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMStringInput.java b/common/src/test/java/org/apache/sqoop/model/TestMStringInput.java
index 37a04c2..079511b 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMStringInput.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMStringInput.java
@@ -20,6 +20,8 @@ package org.apache.sqoop.model;
 import org.apache.commons.lang.StringUtils;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+
 import static org.testng.Assert.*;
 
 /**
@@ -34,7 +36,7 @@ public class TestMStringInput {
   public void testInitialization() {
     short len = 6;
     MStringInput input = new MStringInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY,
-        len);
+        len, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop", input.getName());
     assertEquals(true, input.isSensitive());
     assertEquals(len, input.getMaxLength());
@@ -49,16 +51,16 @@ public class TestMStringInput {
     short len = 6;
     // Positive test
     MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, len);
+        StringUtils.EMPTY, len, Collections.EMPTY_LIST);
     MStringInput input2 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, len);
+        StringUtils.EMPTY, len, Collections.EMPTY_LIST);
     assertTrue(input1.equals(input2));
 
     // Negative test
     MStringInput input3 = new MStringInput("sqoopsqoop", false, InputEditable.ANY,
-        StringUtils.EMPTY, len);
+        StringUtils.EMPTY, len, Collections.EMPTY_LIST);
     MStringInput input4 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, len);
+        StringUtils.EMPTY, len, Collections.EMPTY_LIST);
     assertFalse(input3.equals(input4));
   }
 
@@ -68,7 +70,7 @@ public class TestMStringInput {
   @Test
   public void testValue() {
     MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, (short) 5);
+        StringUtils.EMPTY, (short) 5, Collections.EMPTY_LIST);
     input1.setValue("sqoop");
     assertEquals("sqoop", input1.getValue());
     input1.setEmpty();
@@ -81,7 +83,7 @@ public class TestMStringInput {
   @Test
   public void testUrlSafe() {
     MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, (short) 5);
+        StringUtils.EMPTY, (short) 5, Collections.EMPTY_LIST);
     String s = "Sqoop%$!@#&*()Sqoop";
     input1.setValue(s);
     // Getting URL safe string
@@ -97,7 +99,7 @@ public class TestMStringInput {
   @Test
   public void testNamedElement() {
     MStringInput input1 = new MStringInput("sqoopsqoop", true, InputEditable.ANY,
-        StringUtils.EMPTY, (short) 5);
+        StringUtils.EMPTY, (short) 5, Collections.EMPTY_LIST);
     assertEquals("sqoopsqoop.label", input1.getLabelKey());
     assertEquals("sqoopsqoop.help", input1.getHelpKey());
   }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMValidatedElement.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMValidatedElement.java b/common/src/test/java/org/apache/sqoop/model/TestMValidatedElement.java
index 4bd218e..900f0e5 100644
--- a/common/src/test/java/org/apache/sqoop/model/TestMValidatedElement.java
+++ b/common/src/test/java/org/apache/sqoop/model/TestMValidatedElement.java
@@ -22,6 +22,10 @@ import org.apache.sqoop.validation.Message;
 import org.apache.sqoop.validation.Status;
 import org.testng.annotations.Test;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import static org.testng.Assert.*;
 
 /**
@@ -34,7 +38,10 @@ public class TestMValidatedElement {
    */
   @Test
   public void testInitialization() {
-    MValidatedElement input = new MIntegerInput("input", false,InputEditable.ANY, StringUtils.EMPTY );
+    MValidator testMValidator = new MValidator("testValidator", null);
+    List<MValidator> mValidatorList = new ArrayList<>();
+    mValidatorList.add(testMValidator);
+    MValidatedElement input = new MIntegerInput("input", false,InputEditable.ANY, StringUtils.EMPTY, mValidatorList);
     assertEquals(Status.OK, input.getValidationStatus());
   }
 
@@ -43,7 +50,7 @@ public class TestMValidatedElement {
    */
   @Test
   public void testVarious() {
-    MValidatedElement input = new MIntegerInput("input", false, InputEditable.ANY, StringUtils.EMPTY );
+    MValidatedElement input = new MIntegerInput("input", false, InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
 
     // Default status
     assertEquals(Status.OK, input.getValidationStatus());

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/common/src/test/java/org/apache/sqoop/model/TestMValidator.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/sqoop/model/TestMValidator.java b/common/src/test/java/org/apache/sqoop/model/TestMValidator.java
new file mode 100644
index 0000000..aade665
--- /dev/null
+++ b/common/src/test/java/org/apache/sqoop/model/TestMValidator.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sqoop.model;
+
+import org.apache.sqoop.validation.validators.AbstractValidator;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test class for org.apache.sqoop.model.MValidator
+ */
+public class TestMValidator {
+  @Test
+  public void testEquality() {
+    MValidator testMValidator1 = new MValidator("testValidator", AbstractValidator.DEFAULT_STRING_ARGUMENT);
+    MValidator testMValidator2 = new MValidator("testValidator", AbstractValidator.DEFAULT_STRING_ARGUMENT);
+    assertEquals(testMValidator1, testMValidator2);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestGenericJdbcConnectorUpgrader.java
----------------------------------------------------------------------
diff --git a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestGenericJdbcConnectorUpgrader.java b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestGenericJdbcConnectorUpgrader.java
index e05b93d..c53a0b0 100644
--- a/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestGenericJdbcConnectorUpgrader.java
+++ b/connector/connector-generic-jdbc/src/test/java/org/apache/sqoop/connector/jdbc/TestGenericJdbcConnectorUpgrader.java
@@ -44,8 +44,8 @@ public class TestGenericJdbcConnectorUpgrader {
   @Test
   public void testFromConfig() {
     // No upgrade
-    MFromConfig originalConfigs = new MFromConfig(ConfigUtils.toConfigs(FromJobConfiguration.class));
-    MFromConfig newConfigs = new MFromConfig(ConfigUtils.toConfigs(FromJobConfiguration.class));
+    MFromConfig originalConfigs = new MFromConfig(ConfigUtils.toConfigs(FromJobConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(FromJobConfiguration.class));
+    MFromConfig newConfigs = new MFromConfig(ConfigUtils.toConfigs(FromJobConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(FromJobConfiguration.class));
     originalConfigs.getInput("fromJobConfig.schemaName").setValue("test-schema");
     originalConfigs.getInput("fromJobConfig.tableName").setValue("test-tableName");
     originalConfigs.getInput("fromJobConfig.columns").setValue("test-columns");
@@ -63,8 +63,8 @@ public class TestGenericJdbcConnectorUpgrader {
   @Test
   public void testToConfig() {
     // No upgrade
-    MToConfig originalConfigs = new MToConfig(ConfigUtils.toConfigs(ToJobConfiguration.class));
-    MToConfig newConfigs = new MToConfig(ConfigUtils.toConfigs(ToJobConfiguration.class));
+    MToConfig originalConfigs = new MToConfig(ConfigUtils.toConfigs(ToJobConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(ToJobConfiguration.class));
+    MToConfig newConfigs = new MToConfig(ConfigUtils.toConfigs(ToJobConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(ToJobConfiguration.class));
     originalConfigs.getInput("toJobConfig.schemaName").setValue("test-schema");
     originalConfigs.getInput("toJobConfig.tableName").setValue("test-tableName");
     originalConfigs.getInput("toJobConfig.columns").setValue("test-columns");
@@ -82,8 +82,8 @@ public class TestGenericJdbcConnectorUpgrader {
   @Test
   public void testLinkConfig() {
     // No upgrade
-    MLinkConfig originalConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class));
-    MLinkConfig newConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class));
+    MLinkConfig originalConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(LinkConfiguration.class));
+    MLinkConfig newConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(LinkConfiguration.class));
     originalConfigs.getInput("linkConfig.jdbcDriver").setValue("test-jdbcDriver");
     originalConfigs.getInput("linkConfig.connectionString").setValue("test-connectionString");
     originalConfigs.getInput("linkConfig.username").setValue("test-username");

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/connector/connector-kite/src/test/java/org/apache/sqoop/connector/kite/TestKiteConnectorUpgrader.java
----------------------------------------------------------------------
diff --git a/connector/connector-kite/src/test/java/org/apache/sqoop/connector/kite/TestKiteConnectorUpgrader.java b/connector/connector-kite/src/test/java/org/apache/sqoop/connector/kite/TestKiteConnectorUpgrader.java
index a6943f4..5d154d0 100644
--- a/connector/connector-kite/src/test/java/org/apache/sqoop/connector/kite/TestKiteConnectorUpgrader.java
+++ b/connector/connector-kite/src/test/java/org/apache/sqoop/connector/kite/TestKiteConnectorUpgrader.java
@@ -26,9 +26,11 @@ import org.apache.sqoop.model.MConfig;
 import org.apache.sqoop.model.MInput;
 import org.apache.sqoop.model.MLinkConfig;
 import org.apache.sqoop.model.MStringInput;
+import org.apache.sqoop.model.MValidator;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
 import java.util.LinkedList;
 
 import static org.testng.Assert.assertEquals;
@@ -43,10 +45,10 @@ public class TestKiteConnectorUpgrader {
 
   @Test
   public void testLinkUpgrade() throws Exception {
-    MLinkConfig originalConfigs = new MLinkConfig(new LinkedList<MConfig>());
-    MLinkConfig newConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class));
-    originalConfigs.getConfigs().add(new MConfig("linkConfig", new LinkedList<MInput<?>>()));
-    originalConfigs.getConfigs().get(0).getInputs().add(new MStringInput("linkConfig.hdfsHostAndPort", false, InputEditable.ANY, StringUtils.EMPTY, (short)255));
+    MLinkConfig originalConfigs = new MLinkConfig(new LinkedList<MConfig>(), new LinkedList<MValidator>());
+    MLinkConfig newConfigs = new MLinkConfig(ConfigUtils.toConfigs(LinkConfiguration.class), ConfigUtils.getMValidatorsFromConfigurationClass(LinkConfiguration.class));
+    originalConfigs.getConfigs().add(new MConfig("linkConfig", new LinkedList<MInput<?>>(), Collections.EMPTY_LIST));
+    originalConfigs.getConfigs().get(0).getInputs().add(new MStringInput("linkConfig.hdfsHostAndPort", false, InputEditable.ANY, StringUtils.EMPTY, (short)255, Collections.EMPTY_LIST));
     originalConfigs.getInput("linkConfig.hdfsHostAndPort").setValue("test:8020");
     upgrader.upgradeLinkConfig(originalConfigs, newConfigs);
     assertEquals("test:8020", newConfigs.getInput("linkConfig.authority").getValue());

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java b/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
index 4df7782..1899bb7 100644
--- a/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
+++ b/core/src/main/java/org/apache/sqoop/connector/ConnectorHandler.java
@@ -90,16 +90,16 @@ public final class ConnectorHandler {
     MToConfig toConfig = null;
     if (connector.getSupportedDirections().contains(Direction.FROM)) {
       fromConfig = new MFromConfig(ConfigUtils.toConfigs(
-          connector.getJobConfigurationClass(Direction.FROM)));
+          connector.getJobConfigurationClass(Direction.FROM)), ConfigUtils.getMValidatorsFromConfigurationClass(connector.getJobConfigurationClass(Direction.FROM)));
     }
 
     if (connector.getSupportedDirections().contains(Direction.TO)) {
       toConfig = new MToConfig(ConfigUtils.toConfigs(
-          connector.getJobConfigurationClass(Direction.TO)));
+          connector.getJobConfigurationClass(Direction.TO)), ConfigUtils.getMValidatorsFromConfigurationClass(connector.getJobConfigurationClass(Direction.TO)));
     }
 
     MLinkConfig linkConfig = new MLinkConfig(
-        ConfigUtils.toConfigs(connector.getLinkConfigurationClass()));
+        ConfigUtils.toConfigs(connector.getLinkConfigurationClass()), ConfigUtils.getMValidatorsFromConfigurationClass(connector.getLinkConfigurationClass()));
 
     connectorConfigurable = new MConnector(connectorUniqueName, connectorClassName, connector.getVersion(),
         linkConfig, fromConfig, toConfig);

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/core/src/main/java/org/apache/sqoop/driver/Driver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/driver/Driver.java b/core/src/main/java/org/apache/sqoop/driver/Driver.java
index cff2bef..c4f84d6 100644
--- a/core/src/main/java/org/apache/sqoop/driver/Driver.java
+++ b/core/src/main/java/org/apache/sqoop/driver/Driver.java
@@ -17,6 +17,7 @@
  */
 package org.apache.sqoop.driver;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
@@ -32,6 +33,8 @@ import org.apache.sqoop.model.ConfigUtils;
 import org.apache.sqoop.model.MConfig;
 import org.apache.sqoop.model.MDriver;
 import org.apache.sqoop.model.MDriverConfig;
+import org.apache.sqoop.model.MValidator;
+import org.apache.sqoop.model.Validator;
 import org.apache.sqoop.repository.RepositoryManager;
 
 /**
@@ -112,7 +115,8 @@ public class Driver implements Reconfigurable {
 
   private Driver() {
     List<MConfig> driverConfig = ConfigUtils.toConfigs(getDriverJobConfigurationClass());
-    mDriver = new MDriver(new MDriverConfig(driverConfig), DriverBean.CURRENT_DRIVER_VERSION);
+    List<MValidator> mValidators = ConfigUtils.getMValidatorsFromConfigurationClass(getDriverJobConfigurationClass());
+    mDriver = new MDriver(new MDriverConfig(driverConfig, mValidators), DriverBean.CURRENT_DRIVER_VERSION);
 
     // Build upgrader
     driverUpgrader = new DriverUpgrader();

http://git-wip-us.apache.org/repos/asf/sqoop/blob/d69bd34e/core/src/main/java/org/apache/sqoop/repository/Repository.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/sqoop/repository/Repository.java b/core/src/main/java/org/apache/sqoop/repository/Repository.java
index cc29e39..144e419 100644
--- a/core/src/main/java/org/apache/sqoop/repository/Repository.java
+++ b/core/src/main/java/org/apache/sqoop/repository/Repository.java
@@ -34,6 +34,7 @@ import org.apache.sqoop.driver.DriverUpgrader;
 import org.apache.sqoop.json.DriverBean;
 import org.apache.sqoop.model.ConfigUtils;
 import org.apache.sqoop.model.MConfig;
+import org.apache.sqoop.model.MConfigList;
 import org.apache.sqoop.model.MConnector;
 import org.apache.sqoop.model.MDriver;
 import org.apache.sqoop.model.MDriverConfig;
@@ -476,8 +477,8 @@ public abstract class Repository {
         for (MLink link : existingLinksByConnector) {
           LOG.info(" Link upgrade for link:" + link.getName() + " for connector:" + connectorName);
           // Make a new copy of the configs
-          List<MConfig> linkConfig = newConnector.getLinkConfig().clone(false).getConfigs();
-          MLinkConfig newLinkConfig = new MLinkConfig(linkConfig);
+          MConfigList linkConfig = newConnector.getLinkConfig().clone(false);
+          MLinkConfig newLinkConfig = new MLinkConfig(linkConfig.getConfigs(), linkConfig.getCloneOfValidators());
           MLinkConfig oldLinkConfig = link.getConnectorLinkConfig();
           upgrader.upgradeLinkConfig(oldLinkConfig, newLinkConfig);
           MLink newlink = new MLink(link, newLinkConfig);
@@ -513,9 +514,9 @@ public abstract class Repository {
               && supportedDirections.isDirectionSupported(Direction.TO)
               && job.getToConnectorId() == newConnector.getPersistenceId()) {
             // Upgrade both configs
-            MFromConfig newFromConfig = new MFromConfig(newConnector.getFromConfig().clone(false).getConfigs());
+            MFromConfig newFromConfig = new MFromConfig(newConnector.getFromConfig().clone(false).getConfigs(), newConnector.getFromConfig().getCloneOfValidators());
             MFromConfig oldFromConfig = job.getFromJobConfig();
-            MToConfig newToConfig = new MToConfig(newConnector.getToConfig().clone(false).getConfigs());
+            MToConfig newToConfig = new MToConfig(newConnector.getToConfig().clone(false).getConfigs(), newConnector.getToConfig().getCloneOfValidators());
             MToConfig oldToConfig = job.getToJobConfig();
             upgrader.upgradeFromJobConfig(oldFromConfig, newFromConfig);
             upgrader.upgradeToJobConfig(oldToConfig, newToConfig);
@@ -536,7 +537,7 @@ public abstract class Repository {
             }
           } else if (supportedDirections.isDirectionSupported(Direction.FROM)
               && job.getFromConnectorId() == newConnector.getPersistenceId()) {
-            MFromConfig newFromConfig = new MFromConfig(newConnector.getFromConfig().clone(false).getConfigs());
+            MFromConfig newFromConfig = new MFromConfig(newConnector.getFromConfig().clone(false).getConfigs(), newConnector.getFromConfig().getCloneOfValidators());
             MFromConfig oldFromConfig = job.getFromJobConfig();
             upgrader.upgradeFromJobConfig(oldFromConfig, newFromConfig);
             MToConfig oldToConfig = job.getToJobConfig();
@@ -559,7 +560,7 @@ public abstract class Repository {
           } else if (supportedDirections.isDirectionSupported(Direction.TO)
               && job.getToConnectorId() == newConnector.getPersistenceId()) {
             MToConfig oldToConfig = job.getToJobConfig();
-            MToConfig newToConfig = new MToConfig(newConnector.getToConfig().clone(false).getConfigs());
+            MToConfig newToConfig = new MToConfig(newConnector.getToConfig().clone(false).getConfigs(), newConnector.getToConfig().getCloneOfValidators());
             upgrader.upgradeToJobConfig(oldToConfig, newToConfig);
             MFromConfig oldFromConfig = job.getFromJobConfig();
             // create a job with old FROM direction configs but new TO direction


Mime
View raw message