mirror of
https://github.com/apache/sqoop.git
synced 2025-05-16 00:41:23 +08:00
SQOOP-2549: Sqoop2: Allow connector developers to mask certain keys in Maps when sending them back to clients
(Abraham Fine via Jarek Jarcec Cecho)
This commit is contained in:
parent
bec7bd046f
commit
2e74a9155d
@ -35,6 +35,7 @@ public class ConfigInputConstants {
|
|||||||
public static final String CONFIG_INPUT_NAME = "name";
|
public static final String CONFIG_INPUT_NAME = "name";
|
||||||
public static final String CONFIG_INPUT_TYPE = "type";
|
public static final String CONFIG_INPUT_TYPE = "type";
|
||||||
public static final String CONFIG_INPUT_SENSITIVE = "sensitive";
|
public static final String CONFIG_INPUT_SENSITIVE = "sensitive";
|
||||||
|
public static final String CONFIG_INPUT_SENSITIVE_KEY_PATTERN = "sensitive-pattern";
|
||||||
public static final String CONFIG_INPUT_SIZE = "size";
|
public static final String CONFIG_INPUT_SIZE = "size";
|
||||||
public static final String CONFIG_INPUT_EDITABLE = "editable";
|
public static final String CONFIG_INPUT_EDITABLE = "editable";
|
||||||
public static final String CONFIG_INPUT_OVERRIDES = "overrides";
|
public static final String CONFIG_INPUT_OVERRIDES = "overrides";
|
||||||
|
@ -106,7 +106,13 @@ static JSONObject extractConfig(MConfig mConfig, MConfigType type, boolean skipS
|
|||||||
// Skip if sensitive
|
// Skip if sensitive
|
||||||
if (!mInput.isEmpty() && !(skipSensitive && mInput.isSensitive())) {
|
if (!mInput.isEmpty() && !(skipSensitive && mInput.isSensitive())) {
|
||||||
if (mInput.getType() == MInputType.MAP) {
|
if (mInput.getType() == MInputType.MAP) {
|
||||||
input.put(ConfigInputConstants.CONFIG_INPUT_VALUE, mInput.getValue());
|
MMapInput mMapInput = (MMapInput)mInput;
|
||||||
|
input.put(ConfigInputConstants.CONFIG_INPUT_SENSITIVE_KEY_PATTERN, mMapInput.getSensitiveKeyPattern());
|
||||||
|
if (skipSensitive) {
|
||||||
|
input.put(ConfigInputConstants.CONFIG_INPUT_VALUE, mMapInput.getNonsenstiveValue());
|
||||||
|
} else {
|
||||||
|
input.put(ConfigInputConstants.CONFIG_INPUT_VALUE, mMapInput.getValue());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input.put(ConfigInputConstants.CONFIG_INPUT_VALUE, mInput.getUrlSafeValueString());
|
input.put(ConfigInputConstants.CONFIG_INPUT_VALUE, mInput.getUrlSafeValueString());
|
||||||
}
|
}
|
||||||
@ -155,6 +161,7 @@ static MConfig restoreConfig(JSONObject config) {
|
|||||||
InputEditable.valueOf((String)input.get(ConfigInputConstants.CONFIG_INPUT_EDITABLE))
|
InputEditable.valueOf((String)input.get(ConfigInputConstants.CONFIG_INPUT_EDITABLE))
|
||||||
: InputEditable.USER_ONLY;
|
: InputEditable.USER_ONLY;
|
||||||
String overrides = (String) input.get(ConfigInputConstants.CONFIG_INPUT_OVERRIDES);
|
String overrides = (String) input.get(ConfigInputConstants.CONFIG_INPUT_OVERRIDES);
|
||||||
|
String sensitveKeyPattern = (String) input.get(ConfigInputConstants.CONFIG_INPUT_SENSITIVE_KEY_PATTERN);
|
||||||
|
|
||||||
MInput mInput = null;
|
MInput mInput = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -164,7 +171,7 @@ static MConfig restoreConfig(JSONObject config) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MAP: {
|
case MAP: {
|
||||||
mInput = new MMapInput(name, sensitive.booleanValue(), editable, overrides);
|
mInput = new MMapInput(name, sensitive.booleanValue(), editable, overrides, sensitveKeyPattern);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INTEGER: {
|
case INTEGER: {
|
||||||
|
@ -144,6 +144,7 @@ private static MConfig toConfig(String configName, Class klass, Object object) {
|
|||||||
short maxLen = inputAnnotation.size();
|
short maxLen = inputAnnotation.size();
|
||||||
InputEditable editable = inputAnnotation.editable();
|
InputEditable editable = inputAnnotation.editable();
|
||||||
String overrides = inputAnnotation.overrides();
|
String overrides = inputAnnotation.overrides();
|
||||||
|
String sensitiveKeyPattern = inputAnnotation.sensitiveKeyPattern();
|
||||||
Class<?> type = field.getType();
|
Class<?> type = field.getType();
|
||||||
|
|
||||||
MInput input;
|
MInput input;
|
||||||
@ -158,7 +159,7 @@ private static MConfig toConfig(String configName, Class klass, Object object) {
|
|||||||
if (type == String.class) {
|
if (type == String.class) {
|
||||||
input = new MStringInput(inputName, sensitive, editable, overrides, maxLen);
|
input = new MStringInput(inputName, sensitive, editable, overrides, maxLen);
|
||||||
} else if (type.isAssignableFrom(Map.class)) {
|
} else if (type.isAssignableFrom(Map.class)) {
|
||||||
input = new MMapInput(inputName, sensitive, editable, overrides);
|
input = new MMapInput(inputName, sensitive, editable, overrides, sensitiveKeyPattern);
|
||||||
} else if (type == Integer.class) {
|
} else if (type == Integer.class) {
|
||||||
input = new MIntegerInput(inputName, sensitive, editable, overrides);
|
input = new MIntegerInput(inputName, sensitive, editable, overrides);
|
||||||
} else if (type == Long.class) {
|
} else if (type == Long.class) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.sqoop.model;
|
package org.apache.sqoop.model;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.sqoop.classification.InterfaceAudience;
|
import org.apache.sqoop.classification.InterfaceAudience;
|
||||||
import org.apache.sqoop.classification.InterfaceStability;
|
import org.apache.sqoop.classification.InterfaceStability;
|
||||||
|
|
||||||
@ -42,6 +43,15 @@
|
|||||||
*/
|
*/
|
||||||
boolean sensitive() default false;
|
boolean sensitive() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this input is a map, keys matching this regular expression will be
|
||||||
|
* treated as sensitive. Sqoop will ensure that values associated with the
|
||||||
|
* sensitive keys will not be easily accessible.
|
||||||
|
*
|
||||||
|
* @return The regular expression that matches sensitive fields
|
||||||
|
*/
|
||||||
|
String sensitiveKeyPattern() default StringUtils.EMPTY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the entity that can edit the input's values, all inputs are
|
* Indicates the entity that can edit the input's values, all inputs are
|
||||||
* created/deleted only by the connector code, other entities do not have
|
* created/deleted only by the connector code, other entities do not have
|
||||||
@ -63,7 +73,7 @@
|
|||||||
* separated list of other inputs in the config class. It validates the
|
* separated list of other inputs in the config class. It validates the
|
||||||
* attribute value obeys the expected conditions
|
* attribute value obeys the expected conditions
|
||||||
*/
|
*/
|
||||||
String overrides() default "";
|
String overrides() default StringUtils.EMPTY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of validators associated with this input.
|
* List of validators associated with this input.
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.sqoop.classification.InterfaceAudience;
|
import org.apache.sqoop.classification.InterfaceAudience;
|
||||||
import org.apache.sqoop.classification.InterfaceStability;
|
import org.apache.sqoop.classification.InterfaceStability;
|
||||||
import org.apache.sqoop.utils.UrlSafeUtils;
|
import org.apache.sqoop.utils.UrlSafeUtils;
|
||||||
@ -29,8 +31,13 @@
|
|||||||
@InterfaceStability.Unstable
|
@InterfaceStability.Unstable
|
||||||
public final class MMapInput extends MInput<Map<String, String>> {
|
public final class MMapInput extends MInput<Map<String, String>> {
|
||||||
|
|
||||||
public MMapInput(String name, boolean sensitive, InputEditable editable, String overrides) {
|
public static final String SENSITIVE_VALUE_PLACEHOLDER = StringUtils.EMPTY;
|
||||||
|
|
||||||
|
private final String sensitiveKeyPattern;
|
||||||
|
|
||||||
|
public MMapInput(String name, boolean sensitive, InputEditable editable, String overrides, String sensitiveKeyPattern) {
|
||||||
super(name, sensitive, editable, overrides);
|
super(name, sensitive, editable, overrides);
|
||||||
|
this.sensitiveKeyPattern = sensitiveKeyPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -117,7 +124,7 @@ public void setEmpty() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MMapInput clone(boolean cloneWithValue) {
|
public MMapInput clone(boolean cloneWithValue) {
|
||||||
MMapInput copy = new MMapInput(getName(), isSensitive(), getEditable(), getOverrides());
|
MMapInput copy = new MMapInput(getName(), isSensitive(), getEditable(), getOverrides(), getSensitiveKeyPattern());
|
||||||
copy.setPersistenceId(getPersistenceId());
|
copy.setPersistenceId(getPersistenceId());
|
||||||
if(cloneWithValue && this.getValue() != null) {
|
if(cloneWithValue && this.getValue() != null) {
|
||||||
Map<String, String> copyMap = new HashMap<String, String>();
|
Map<String, String> copyMap = new HashMap<String, String>();
|
||||||
@ -129,4 +136,23 @@ public MMapInput clone(boolean cloneWithValue) {
|
|||||||
}
|
}
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSensitiveKeyPattern() {
|
||||||
|
return sensitiveKeyPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getNonsenstiveValue() {
|
||||||
|
if (isEmpty()) return null;
|
||||||
|
|
||||||
|
Map<String, String> nonsensitveValue = new HashMap<>();
|
||||||
|
Pattern sensitivePattern = Pattern.compile(getSensitiveKeyPattern());
|
||||||
|
for (Map.Entry<String, String> entry : getValue().entrySet()) {
|
||||||
|
if (sensitivePattern.matcher(entry.getKey()).matches()){
|
||||||
|
nonsensitveValue.put(entry.getKey(), SENSITIVE_VALUE_PLACEHOLDER);
|
||||||
|
} else {
|
||||||
|
nonsensitveValue.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nonsensitveValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,36 @@ public void testMapDataTypeException() {
|
|||||||
String serializedJson = jsonObject.toJSONString();
|
String serializedJson = jsonObject.toJSONString();
|
||||||
|
|
||||||
// Replace map value with a fake string to force exception
|
// Replace map value with a fake string to force exception
|
||||||
String badSerializedJson = serializedJson.replace("{\"A\":\"B\"}", "\"nonsensical string\"");
|
String badSerializedJson = serializedJson.replace("{\"A\":\"B\"}",
|
||||||
|
"\"nonsensical string\"");
|
||||||
System.out.println(badSerializedJson);
|
System.out.println(badSerializedJson);
|
||||||
JSONObject retrievedJson = JSONUtils.parse(badSerializedJson);
|
JSONObject retrievedJson = JSONUtils.parse(badSerializedJson);
|
||||||
ConfigInputSerialization.restoreConfig(retrievedJson);
|
ConfigInputSerialization.restoreConfig(retrievedJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMapDataTypeSensitiveKeys() {
|
||||||
|
MConfig config = getMapConfig();
|
||||||
|
|
||||||
|
// Inserted values
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
map.put("A", "B");
|
||||||
|
config.getMapInput("Map").setValue(map);
|
||||||
|
|
||||||
|
// Serialize
|
||||||
|
JSONObject jsonObject = ConfigInputSerialization.extractConfig(config, MConfigType.JOB, true);
|
||||||
|
String serializedJson = jsonObject.toJSONString();
|
||||||
|
|
||||||
|
// Map with sensitive values redacted
|
||||||
|
Map<String, String> sensitiveMap = new HashMap<String, String>();
|
||||||
|
sensitiveMap.put("A", MMapInput.SENSITIVE_VALUE_PLACEHOLDER);
|
||||||
|
|
||||||
|
// Deserialize
|
||||||
|
JSONObject retrievedJson = JSONUtils.parse(serializedJson);
|
||||||
|
MConfig retrieved = ConfigInputSerialization.restoreConfig(retrievedJson);
|
||||||
|
assertEquals(sensitiveMap, retrieved.getMapInput("Map").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInputEditableOptional() {
|
public void testInputEditableOptional() {
|
||||||
// Inserted values
|
// Inserted values
|
||||||
@ -188,7 +212,7 @@ protected MConfig getMapConfig() {
|
|||||||
|
|
||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
|
|
||||||
input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY);
|
input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, "A");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
|
|
||||||
return new MConfig("c", inputs);
|
return new MConfig("c", inputs);
|
||||||
@ -208,7 +232,7 @@ protected MConfig getConfig() {
|
|||||||
input = new MStringInput("String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30);
|
input = new MStringInput("String", false, InputEditable.ANY, StringUtils.EMPTY, (short)30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
|
|
||||||
input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY);
|
input = new MMapInput("Map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
|
|
||||||
input = new MIntegerInput("Integer", false, InputEditable.ANY, StringUtils.EMPTY);
|
input = new MIntegerInput("Integer", false, InputEditable.ANY, StringUtils.EMPTY);
|
||||||
|
@ -245,7 +245,7 @@ protected List<MConfig> getConfigs() {
|
|||||||
// Config C
|
// Config C
|
||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
inputs.add(new MLongInput("cConfig.longValue", false, InputEditable.ANY, StringUtils.EMPTY));
|
inputs.add(new MLongInput("cConfig.longValue", false, InputEditable.ANY, StringUtils.EMPTY));
|
||||||
inputs.add(new MMapInput("cConfig.map", false, InputEditable.ANY, StringUtils.EMPTY));
|
inputs.add(new MMapInput("cConfig.map", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY));
|
||||||
inputs.add(new MEnumInput("cConfig.enumeration", false, InputEditable.ANY, StringUtils.EMPTY,
|
inputs.add(new MEnumInput("cConfig.enumeration", false, InputEditable.ANY, StringUtils.EMPTY,
|
||||||
new String[] { "X", "Y" }));
|
new String[] { "X", "Y" }));
|
||||||
inputs.add(new MListInput("cConfig.list", false, InputEditable.ANY, StringUtils.EMPTY));
|
inputs.add(new MListInput("cConfig.list", false, InputEditable.ANY, StringUtils.EMPTY));
|
||||||
|
@ -69,7 +69,7 @@ public void testEquals() {
|
|||||||
public void testGetInputs() {
|
public void testGetInputs() {
|
||||||
MIntegerInput intInput = new MIntegerInput("Config.A", false, InputEditable.ANY, StringUtils.EMPTY );
|
MIntegerInput intInput = new MIntegerInput("Config.A", false, InputEditable.ANY, StringUtils.EMPTY );
|
||||||
MLongInput longInput = new MLongInput("Config.A1", 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 );
|
MMapInput mapInput = new MMapInput("Config.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
|
||||||
MStringInput stringInput = new MStringInput("Config.C", false, InputEditable.ANY,
|
MStringInput stringInput = new MStringInput("Config.C", false, InputEditable.ANY,
|
||||||
StringUtils.EMPTY, (short) 3);
|
StringUtils.EMPTY, (short) 3);
|
||||||
MEnumInput enumInput = new MEnumInput("Config.D", false, InputEditable.ANY, StringUtils.EMPTY,
|
MEnumInput enumInput = new MEnumInput("Config.D", false, InputEditable.ANY, StringUtils.EMPTY,
|
||||||
|
@ -32,7 +32,7 @@ public void testGetInputs() {
|
|||||||
List<MConfig> configs = new LinkedList<MConfig>();
|
List<MConfig> configs = new LinkedList<MConfig>();
|
||||||
|
|
||||||
MIntegerInput intInput = new MIntegerInput("Config1.A", false, InputEditable.ANY, StringUtils.EMPTY);
|
MIntegerInput intInput = new MIntegerInput("Config1.A", false, InputEditable.ANY, StringUtils.EMPTY);
|
||||||
MMapInput mapInput = new MMapInput("Config1.B", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput mapInput = new MMapInput("Config1.B", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
|
|
||||||
List<MInput<?>> inputs = new ArrayList<MInput<?>>();
|
List<MInput<?>> inputs = new ArrayList<MInput<?>>();
|
||||||
inputs.add(intInput);
|
inputs.add(intInput);
|
||||||
|
@ -121,7 +121,7 @@ private MFromConfig fromConfig() {
|
|||||||
|
|
||||||
private MToConfig toConfig() {
|
private MToConfig toConfig() {
|
||||||
List<MConfig> configs = new ArrayList<MConfig>();
|
List<MConfig> configs = new ArrayList<MConfig>();
|
||||||
MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
List<MInput<?>> list = new ArrayList<MInput<?>>();
|
List<MInput<?>> list = new ArrayList<MInput<?>>();
|
||||||
list.add(input);
|
list.add(input);
|
||||||
MConfig config = new MConfig("CONFIGTONAME", list);
|
MConfig config = new MConfig("CONFIGTONAME", list);
|
||||||
@ -131,7 +131,7 @@ private MToConfig toConfig() {
|
|||||||
|
|
||||||
private MDriverConfig driverConfig() {
|
private MDriverConfig driverConfig() {
|
||||||
List<MConfig> configs = new ArrayList<MConfig>();
|
List<MConfig> configs = new ArrayList<MConfig>();
|
||||||
MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input = new MMapInput("MAP-INPUT", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
List<MInput<?>> list = new ArrayList<MInput<?>>();
|
List<MInput<?>> list = new ArrayList<MInput<?>>();
|
||||||
list.add(input);
|
list.add(input);
|
||||||
MConfig config = new MConfig("CONFIGDRIVERNAME", list);
|
MConfig config = new MConfig("CONFIGDRIVERNAME", list);
|
||||||
|
@ -38,7 +38,7 @@ public class TestMMapInput {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testInitialization() {
|
public void testInitialization() {
|
||||||
MMapInput input = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
assertEquals("sqoopsqoop", input.getName());
|
assertEquals("sqoopsqoop", input.getName());
|
||||||
assertEquals(MInputType.MAP, input.getType());
|
assertEquals(MInputType.MAP, input.getType());
|
||||||
}
|
}
|
||||||
@ -49,13 +49,13 @@ public void testInitialization() {
|
|||||||
@Test
|
@Test
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
// Positive test
|
// Positive test
|
||||||
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
MMapInput input2 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input2 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
assertTrue(input1.equals(input2));
|
assertTrue(input1.equals(input2));
|
||||||
|
|
||||||
// Negative test
|
// Negative test
|
||||||
MMapInput input3 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input3 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
MMapInput input4 = new MMapInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input4 = new MMapInput("sqoopsqoop1", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
assertFalse(input3.equals(input4));
|
assertFalse(input3.equals(input4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ public void testEquals() {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testValue() {
|
public void testValue() {
|
||||||
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
Map<String, String> map1 = new HashMap<String, String>();
|
Map<String, String> map1 = new HashMap<String, String>();
|
||||||
input1.setValue(map1);
|
input1.setValue(map1);
|
||||||
assertEquals(map1, input1.getValue());
|
assertEquals(map1, input1.getValue());
|
||||||
@ -77,7 +77,7 @@ public void testValue() {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUrlSafe() {
|
public void testUrlSafe() {
|
||||||
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input1 = new MMapInput("sqoopsqoop", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
Map<String, String> map1 = new HashMap<String, String>();
|
Map<String, String> map1 = new HashMap<String, String>();
|
||||||
input1.setValue(map1);
|
input1.setValue(map1);
|
||||||
// Getting URL safe string
|
// Getting URL safe string
|
||||||
@ -98,7 +98,7 @@ public void testUrlSafe() {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNamedElement() {
|
public void testNamedElement() {
|
||||||
MMapInput input1 = new MMapInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY);
|
MMapInput input1 = new MMapInput("sqoopsqoop", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY);
|
||||||
assertEquals("sqoopsqoop.label", input1.getLabelKey());
|
assertEquals("sqoopsqoop.label", input1.getLabelKey());
|
||||||
assertEquals("sqoopsqoop.help", input1.getHelpKey());
|
assertEquals("sqoopsqoop.help", input1.getHelpKey());
|
||||||
}
|
}
|
||||||
@ -108,9 +108,31 @@ public void testNamedElement() {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSensitivity() {
|
public void testSensitivity() {
|
||||||
MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY );
|
MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
|
||||||
MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY );
|
MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
|
||||||
assertFalse(input1.isSensitive());
|
assertFalse(input1.isSensitive());
|
||||||
assertTrue(input2.isSensitive());
|
assertTrue(input2.isSensitive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for sensitivity
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSensitiveKeyPattern() {
|
||||||
|
Map<String, String> testValue = new HashMap<>();
|
||||||
|
testValue.put("sqoop features", "awesome features");
|
||||||
|
testValue.put("sqoop bugs", "horrible bugs");
|
||||||
|
|
||||||
|
MMapInput input1 = new MMapInput("NAME", false, InputEditable.ANY, StringUtils.EMPTY, StringUtils.EMPTY );
|
||||||
|
input1.setValue(testValue);
|
||||||
|
MMapInput input2 = new MMapInput("NAME", true, InputEditable.ANY, StringUtils.EMPTY, ".*bugs.*");
|
||||||
|
input2.setValue(testValue);
|
||||||
|
|
||||||
|
assertEquals(input1.getNonsenstiveValue(), testValue);
|
||||||
|
|
||||||
|
Map<String, String> expectedNonsensitiveMap = new HashMap<>();
|
||||||
|
expectedNonsensitiveMap.put("sqoop features", "awesome features");
|
||||||
|
expectedNonsensitiveMap.put("sqoop bugs", MMapInput.SENSITIVE_VALUE_PLACEHOLDER);
|
||||||
|
assertEquals(input2.getNonsenstiveValue(), expectedNonsensitiveMap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,6 +401,11 @@ Inputs associated with the link configuration include:
|
|||||||
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
||||||
| sensitive | Boolean |Describes if the input value should be hidden from display |@Input(sensitive = true) public String password |
|
| sensitive | Boolean |Describes if the input value should be hidden from display |@Input(sensitive = true) public String password |
|
||||||
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
||||||
|
| sensitiveKeyPattern | String |If the config paramteter is a map, this java regular expression |@Input(sensitiveKeyPattern = ".*sensitive") |
|
||||||
|
| | |(http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)|public Map<String, String> sensitiveMap |
|
||||||
|
| | |will be used to decide which keys are hidden from display. | |
|
||||||
|
| | | | |
|
||||||
|
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
||||||
| editable | Enum |Describes the roles that can edit the value of this input |@Input(editable = ANY) public String value |
|
| editable | Enum |Describes the roles that can edit the value of this input |@Input(editable = ANY) public String value |
|
||||||
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
+-----------------------------+---------+-----------------------------------------------------------------------+-------------------------------------------------+
|
||||||
| overrides | String |Describes a list of other inputs this input can override in this config|@Input(overrides ="value") public String lvalue |
|
| overrides | String |Describes a list of other inputs this input can override in this config|@Input(overrides ="value") public String lvalue |
|
||||||
|
@ -1998,7 +1998,7 @@ private void loadDriverConfigs(List<MConfig> driverConfig,
|
|||||||
input = new MStringInput(inputName, inputSensitivity, editableEnum, overrides, inputStrLength);
|
input = new MStringInput(inputName, inputSensitivity, editableEnum, overrides, inputStrLength);
|
||||||
break;
|
break;
|
||||||
case MAP:
|
case MAP:
|
||||||
input = new MMapInput(inputName, inputSensitivity, editableEnum, overrides);
|
input = new MMapInput(inputName, inputSensitivity, editableEnum, overrides, StringUtils.EMPTY);
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
input = new MBooleanInput(inputName, inputSensitivity, editableEnum, overrides);
|
input = new MBooleanInput(inputName, inputSensitivity, editableEnum, overrides);
|
||||||
@ -2176,7 +2176,7 @@ public void loadConnectorConfigs(List<MConfig> linkConfig, List<MConfig> fromCon
|
|||||||
inputStrLength);
|
inputStrLength);
|
||||||
break;
|
break;
|
||||||
case MAP:
|
case MAP:
|
||||||
input = new MMapInput(inputName, inputSensitivity, editableEnum, overrides);
|
input = new MMapInput(inputName, inputSensitivity, editableEnum, overrides, StringUtils.EMPTY);
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
input = new MBooleanInput(inputName, inputSensitivity, editableEnum, overrides);
|
input = new MBooleanInput(inputName, inputSensitivity, editableEnum, overrides);
|
||||||
|
@ -1021,7 +1021,7 @@ protected List<MConfig> getConfigs(String configName1, String configName2) {
|
|||||||
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
||||||
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5");
|
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1034,7 +1034,7 @@ protected List<MConfig> getConfigs(String configName1, String configName2) {
|
|||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5");
|
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1054,7 +1054,7 @@ protected List<MConfig> getBadConfigs(String configName1, String configName2) {
|
|||||||
// I1 overrides another user_only attribute, hence a bad config
|
// I1 overrides another user_only attribute, hence a bad config
|
||||||
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I4", (short) 30);
|
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I4", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5");
|
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1067,7 +1067,7 @@ protected List<MConfig> getBadConfigs(String configName1, String configName2) {
|
|||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5");
|
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1087,7 +1087,7 @@ protected List<MConfig> getBadConfigsWithSelfOverrides(String configName1, Strin
|
|||||||
// I1 overrides another user_only attribute, hence a bad config
|
// I1 overrides another user_only attribute, hence a bad config
|
||||||
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I4", (short) 30);
|
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I4", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5");
|
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1100,7 +1100,7 @@ protected List<MConfig> getBadConfigsWithSelfOverrides(String configName1, Strin
|
|||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5");
|
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1119,7 +1119,7 @@ protected List<MConfig> getMultipleOverrideConfigs(String configName1, String co
|
|||||||
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
||||||
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I1," + configName1 + ".I3");
|
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".I1," + configName1 + ".I3", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1132,7 +1132,7 @@ protected List<MConfig> getMultipleOverrideConfigs(String configName1, String co
|
|||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5");
|
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1153,7 +1153,7 @@ protected List<MConfig> getBadConfigsWithNonExistingInputOverrides(String config
|
|||||||
// I2 overrides a nonexistant input
|
// I2 overrides a nonexistant input
|
||||||
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
MInput input = new MStringInput(configName1 + ".I1", false, InputEditable.USER_ONLY, configName1 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".FOO");
|
input = new MMapInput(configName1 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName1 + ".FOO", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
input = new MIntegerInput(configName1 + ".I3", false, InputEditable.ANY, configName1 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
@ -1166,7 +1166,7 @@ protected List<MConfig> getBadConfigsWithNonExistingInputOverrides(String config
|
|||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
input = new MStringInput(configName2 + ".I1", false, InputEditable.USER_ONLY, configName2 + ".I2", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5");
|
input = new MMapInput(configName2 + ".I2", false, InputEditable.CONNECTOR_ONLY, configName2 + ".I5", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
input = new MIntegerInput(configName2 + ".I3", false, InputEditable.ANY, configName2 + ".I1");
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
|
@ -170,14 +170,14 @@ protected List<MConfig> getConfigs(String configName1, String configName2) {
|
|||||||
MInput<?> input = new MStringInput("I1", false, InputEditable.ANY,
|
MInput<?> input = new MStringInput("I1", false, InputEditable.ANY,
|
||||||
StringUtils.EMPTY, (short) 30);
|
StringUtils.EMPTY, (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput("I2", false, InputEditable.ANY, "I1");
|
input = new MMapInput("I2", false, InputEditable.ANY, "I1", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
configs.add(new MConfig(configName1, inputs));
|
configs.add(new MConfig(configName1, inputs));
|
||||||
|
|
||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput("I3", false, InputEditable.ANY, "I4", (short) 30);
|
input = new MStringInput("I3", false, InputEditable.ANY, "I4", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput("I4", false, InputEditable.ANY, "I3");
|
input = new MMapInput("I4", false, InputEditable.ANY, "I3", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
configs.add(new MConfig(configName2, inputs));
|
configs.add(new MConfig(configName2, inputs));
|
||||||
|
|
||||||
|
@ -151,14 +151,14 @@ protected List<MConfig> getConfigs(String configName1, String configName2) {
|
|||||||
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
List<MInput<?>> inputs = new LinkedList<MInput<?>>();
|
||||||
MInput<?> input = new MStringInput("I1", false, InputEditable.ANY, StringUtils.EMPTY, (short) 30);
|
MInput<?> input = new MStringInput("I1", false, InputEditable.ANY, StringUtils.EMPTY, (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput("I2", false, InputEditable.ANY, "I1");
|
input = new MMapInput("I2", false, InputEditable.ANY, "I1", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
configs.add(new MConfig(configName1, inputs));
|
configs.add(new MConfig(configName1, inputs));
|
||||||
|
|
||||||
inputs = new LinkedList<MInput<?>>();
|
inputs = new LinkedList<MInput<?>>();
|
||||||
input = new MStringInput("I3", false, InputEditable.ANY, "I4", (short) 30);
|
input = new MStringInput("I3", false, InputEditable.ANY, "I4", (short) 30);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
input = new MMapInput("I4", false, InputEditable.ANY, "I3");
|
input = new MMapInput("I4", false, InputEditable.ANY, "I3", StringUtils.EMPTY);
|
||||||
inputs.add(input);
|
inputs.add(input);
|
||||||
configs.add(new MConfig(configName2, inputs));
|
configs.add(new MConfig(configName2, inputs));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user