HADOOP-8172. Configuration no longer sets all keys in a deprecated key list. (Anupam Seth via bobby)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1332821 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
934f466bab
commit
7d1b804d3a
@ -447,6 +447,9 @@ Release 2.0.0 - UNRELEASED
|
|||||||
HADOOP-8317. Update maven-assembly-plugin to 2.3 - fix build on FreeBSD
|
HADOOP-8317. Update maven-assembly-plugin to 2.3 - fix build on FreeBSD
|
||||||
(Radim Kolar via bobby)
|
(Radim Kolar via bobby)
|
||||||
|
|
||||||
|
HADOOP-8172. Configuration no longer sets all keys in a deprecated key
|
||||||
|
list. (Anupam Seth via bobby)
|
||||||
|
|
||||||
Release 0.23.3 - UNRELEASED
|
Release 0.23.3 - UNRELEASED
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
@ -269,10 +270,18 @@ private final String getWarningMessage(String key) {
|
|||||||
* This is to be used only by the developers in order to add deprecation of
|
* This is to be used only by the developers in order to add deprecation of
|
||||||
* keys, and attempts to call this method after loading resources once,
|
* keys, and attempts to call this method after loading resources once,
|
||||||
* would lead to <tt>UnsupportedOperationException</tt>
|
* would lead to <tt>UnsupportedOperationException</tt>
|
||||||
|
*
|
||||||
|
* If a key is deprecated in favor of multiple keys, they are all treated as
|
||||||
|
* aliases of each other, and setting any one of them resets all the others
|
||||||
|
* to the new value.
|
||||||
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @param newKeys
|
* @param newKeys
|
||||||
* @param customMessage
|
* @param customMessage
|
||||||
|
* @deprecated use {@link addDeprecation(String key, String newKey,
|
||||||
|
String customMessage)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public synchronized static void addDeprecation(String key, String[] newKeys,
|
public synchronized static void addDeprecation(String key, String[] newKeys,
|
||||||
String customMessage) {
|
String customMessage) {
|
||||||
if (key == null || key.length() == 0 ||
|
if (key == null || key.length() == 0 ||
|
||||||
@ -289,6 +298,43 @@ public synchronized static void addDeprecation(String key, String[] newKeys,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the deprecated key to the deprecation map.
|
||||||
|
* It does not override any existing entries in the deprecation map.
|
||||||
|
* This is to be used only by the developers in order to add deprecation of
|
||||||
|
* keys, and attempts to call this method after loading resources once,
|
||||||
|
* would lead to <tt>UnsupportedOperationException</tt>
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param newKey
|
||||||
|
* @param customMessage
|
||||||
|
*/
|
||||||
|
public synchronized static void addDeprecation(String key, String newKey,
|
||||||
|
String customMessage) {
|
||||||
|
addDeprecation(key, new String[] {newKey}, customMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the deprecated key to the deprecation map when no custom message
|
||||||
|
* is provided.
|
||||||
|
* It does not override any existing entries in the deprecation map.
|
||||||
|
* This is to be used only by the developers in order to add deprecation of
|
||||||
|
* keys, and attempts to call this method after loading resources once,
|
||||||
|
* would lead to <tt>UnsupportedOperationException</tt>
|
||||||
|
*
|
||||||
|
* If a key is deprecated in favor of multiple keys, they are all treated as
|
||||||
|
* aliases of each other, and setting any one of them resets all the others
|
||||||
|
* to the new value.
|
||||||
|
*
|
||||||
|
* @param key Key that is to be deprecated
|
||||||
|
* @param newKeys list of keys that take up the values of deprecated key
|
||||||
|
* @deprecated use {@link addDeprecation(String key, String newKey)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public synchronized static void addDeprecation(String key, String[] newKeys) {
|
||||||
|
addDeprecation(key, newKeys, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the deprecated key to the deprecation map when no custom message
|
* Adds the deprecated key to the deprecation map when no custom message
|
||||||
* is provided.
|
* is provided.
|
||||||
@ -298,10 +344,10 @@ public synchronized static void addDeprecation(String key, String[] newKeys,
|
|||||||
* would lead to <tt>UnsupportedOperationException</tt>
|
* would lead to <tt>UnsupportedOperationException</tt>
|
||||||
*
|
*
|
||||||
* @param key Key that is to be deprecated
|
* @param key Key that is to be deprecated
|
||||||
* @param newKeys list of keys that take up the values of deprecated key
|
* @param newKey key that takes up the value of deprecated key
|
||||||
*/
|
*/
|
||||||
public synchronized static void addDeprecation(String key, String[] newKeys) {
|
public synchronized static void addDeprecation(String key, String newKey) {
|
||||||
addDeprecation(key, newKeys, null);
|
addDeprecation(key, new String[] {newKey}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,16 +368,26 @@ public static boolean isDeprecated(String key) {
|
|||||||
* @param name property name.
|
* @param name property name.
|
||||||
* @return alternate name.
|
* @return alternate name.
|
||||||
*/
|
*/
|
||||||
private String getAlternateName(String name) {
|
private String[] getAlternateNames(String name) {
|
||||||
String altName;
|
String oldName, altNames[] = null;
|
||||||
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
||||||
if (keyInfo != null) {
|
if (keyInfo == null) {
|
||||||
altName = (keyInfo.newKeys.length > 0) ? keyInfo.newKeys[0] : null;
|
altNames = (reverseDeprecatedKeyMap.get(name) != null ) ?
|
||||||
|
new String [] {reverseDeprecatedKeyMap.get(name)} : null;
|
||||||
|
if(altNames != null && altNames.length > 0) {
|
||||||
|
//To help look for other new configs for this deprecated config
|
||||||
|
keyInfo = deprecatedKeyMap.get(altNames[0]);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
altName = reverseDeprecatedKeyMap.get(name);
|
|
||||||
}
|
}
|
||||||
return altName;
|
if(keyInfo != null && keyInfo.newKeys.length > 0) {
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
if(altNames != null) {
|
||||||
|
list.addAll(Arrays.asList(altNames));
|
||||||
|
}
|
||||||
|
list.addAll(Arrays.asList(keyInfo.newKeys));
|
||||||
|
altNames = list.toArray(new String[list.size()]);
|
||||||
|
}
|
||||||
|
return altNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -346,24 +402,29 @@ private String getAlternateName(String name) {
|
|||||||
* @return the first property in the list of properties mapping
|
* @return the first property in the list of properties mapping
|
||||||
* the <code>name</code> or the <code>name</code> itself.
|
* the <code>name</code> or the <code>name</code> itself.
|
||||||
*/
|
*/
|
||||||
private String handleDeprecation(String name) {
|
private String[] handleDeprecation(String name) {
|
||||||
|
ArrayList<String > names = new ArrayList<String>();
|
||||||
if (isDeprecated(name)) {
|
if (isDeprecated(name)) {
|
||||||
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
DeprecatedKeyInfo keyInfo = deprecatedKeyMap.get(name);
|
||||||
warnOnceIfDeprecated(name);
|
warnOnceIfDeprecated(name);
|
||||||
for (String newKey : keyInfo.newKeys) {
|
for (String newKey : keyInfo.newKeys) {
|
||||||
if(newKey != null) {
|
if(newKey != null) {
|
||||||
name = newKey;
|
names.add(newKey);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String deprecatedKey = reverseDeprecatedKeyMap.get(name);
|
if(names.size() == 0) {
|
||||||
if (deprecatedKey != null && !getOverlay().containsKey(name) &&
|
names.add(name);
|
||||||
|
}
|
||||||
|
for(String n : names) {
|
||||||
|
String deprecatedKey = reverseDeprecatedKeyMap.get(n);
|
||||||
|
if (deprecatedKey != null && !getOverlay().containsKey(n) &&
|
||||||
getOverlay().containsKey(deprecatedKey)) {
|
getOverlay().containsKey(deprecatedKey)) {
|
||||||
getProps().setProperty(name, getOverlay().getProperty(deprecatedKey));
|
getProps().setProperty(n, getOverlay().getProperty(deprecatedKey));
|
||||||
getOverlay().setProperty(name, getOverlay().getProperty(deprecatedKey));
|
getOverlay().setProperty(n, getOverlay().getProperty(deprecatedKey));
|
||||||
}
|
}
|
||||||
return name;
|
}
|
||||||
|
return names.toArray(new String[names.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDeprecation() {
|
private void handleDeprecation() {
|
||||||
@ -595,8 +656,12 @@ private String substituteVars(String expr) {
|
|||||||
* or null if no such property exists.
|
* or null if no such property exists.
|
||||||
*/
|
*/
|
||||||
public String get(String name) {
|
public String get(String name) {
|
||||||
name = handleDeprecation(name);
|
String[] names = handleDeprecation(name);
|
||||||
return substituteVars(getProps().getProperty(name));
|
String result = null;
|
||||||
|
for(String n : names) {
|
||||||
|
result = substituteVars(getProps().getProperty(n));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -633,8 +698,12 @@ public String getTrimmed(String name) {
|
|||||||
* its replacing property and null if no such property exists.
|
* its replacing property and null if no such property exists.
|
||||||
*/
|
*/
|
||||||
public String getRaw(String name) {
|
public String getRaw(String name) {
|
||||||
name = handleDeprecation(name);
|
String[] names = handleDeprecation(name);
|
||||||
return getProps().getProperty(name);
|
String result = null;
|
||||||
|
for(String n : names) {
|
||||||
|
result = getProps().getProperty(n);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -652,11 +721,13 @@ public void set(String name, String value) {
|
|||||||
getOverlay().setProperty(name, value);
|
getOverlay().setProperty(name, value);
|
||||||
getProps().setProperty(name, value);
|
getProps().setProperty(name, value);
|
||||||
updatingResource.put(name, UNKNOWN_RESOURCE);
|
updatingResource.put(name, UNKNOWN_RESOURCE);
|
||||||
String altName = getAlternateName(name);
|
String[] altNames = getAlternateNames(name);
|
||||||
if (altName != null) {
|
if (altNames != null && altNames.length > 0) {
|
||||||
|
for(String altName : altNames) {
|
||||||
getOverlay().setProperty(altName, value);
|
getOverlay().setProperty(altName, value);
|
||||||
getProps().setProperty(altName, value);
|
getProps().setProperty(altName, value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
warnOnceIfDeprecated(name);
|
warnOnceIfDeprecated(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,14 +742,16 @@ private void warnOnceIfDeprecated(String name) {
|
|||||||
* Unset a previously set property.
|
* Unset a previously set property.
|
||||||
*/
|
*/
|
||||||
public synchronized void unset(String name) {
|
public synchronized void unset(String name) {
|
||||||
String altName = getAlternateName(name);
|
String[] altNames = getAlternateNames(name);
|
||||||
getOverlay().remove(name);
|
getOverlay().remove(name);
|
||||||
getProps().remove(name);
|
getProps().remove(name);
|
||||||
if (altName !=null) {
|
if (altNames !=null && altNames.length > 0) {
|
||||||
|
for(String altName : altNames) {
|
||||||
getOverlay().remove(altName);
|
getOverlay().remove(altName);
|
||||||
getProps().remove(altName);
|
getProps().remove(altName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a property if it is currently unset.
|
* Sets a property if it is currently unset.
|
||||||
@ -711,8 +784,12 @@ private synchronized Properties getOverlay() {
|
|||||||
* doesn't exist.
|
* doesn't exist.
|
||||||
*/
|
*/
|
||||||
public String get(String name, String defaultValue) {
|
public String get(String name, String defaultValue) {
|
||||||
name = handleDeprecation(name);
|
String[] names = handleDeprecation(name);
|
||||||
return substituteVars(getProps().getProperty(name, defaultValue));
|
String result = null;
|
||||||
|
for(String n : names) {
|
||||||
|
result = substituteVars(getProps().getProperty(n, defaultValue));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +164,7 @@ public void testDeprecation() throws IOException {
|
|||||||
conf.set("Y", "y");
|
conf.set("Y", "y");
|
||||||
conf.set("Z", "z");
|
conf.set("Z", "z");
|
||||||
// get old key
|
// get old key
|
||||||
assertEquals("y", conf.get("X"));
|
assertEquals("z", conf.get("X"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,10 +18,15 @@
|
|||||||
|
|
||||||
package org.apache.hadoop.conf;
|
package org.apache.hadoop.conf;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -53,4 +58,49 @@ public void testReadWriteWithDeprecatedKeys() throws Exception {
|
|||||||
assertTrue(fileContents.contains("old.config.yet.to.be.deprecated"));
|
assertTrue(fileContents.contains("old.config.yet.to.be.deprecated"));
|
||||||
assertTrue(fileContents.contains("new.conf.to.replace.deprecated.conf"));
|
assertTrue(fileContents.contains("new.conf.to.replace.deprecated.conf"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIteratorWithDeprecatedKeysMappedToMultipleNewKeys() {
|
||||||
|
Configuration conf = new Configuration();
|
||||||
|
Configuration.addDeprecation("dK", new String[]{"nK1", "nK2"});
|
||||||
|
conf.set("k", "v");
|
||||||
|
conf.set("dK", "V");
|
||||||
|
assertEquals("V", conf.get("dK"));
|
||||||
|
assertEquals("V", conf.get("nK1"));
|
||||||
|
assertEquals("V", conf.get("nK2"));
|
||||||
|
conf.set("nK1", "VV");
|
||||||
|
assertEquals("VV", conf.get("dK"));
|
||||||
|
assertEquals("VV", conf.get("nK1"));
|
||||||
|
assertEquals("VV", conf.get("nK2"));
|
||||||
|
conf.set("nK2", "VVV");
|
||||||
|
assertEquals("VVV", conf.get("dK"));
|
||||||
|
assertEquals("VVV", conf.get("nK2"));
|
||||||
|
assertEquals("VVV", conf.get("nK1"));
|
||||||
|
boolean kFound = false;
|
||||||
|
boolean dKFound = false;
|
||||||
|
boolean nK1Found = false;
|
||||||
|
boolean nK2Found = false;
|
||||||
|
for (Map.Entry<String, String> entry : conf) {
|
||||||
|
if (entry.getKey().equals("k")) {
|
||||||
|
assertEquals("v", entry.getValue());
|
||||||
|
kFound = true;
|
||||||
|
}
|
||||||
|
if (entry.getKey().equals("dK")) {
|
||||||
|
assertEquals("VVV", entry.getValue());
|
||||||
|
dKFound = true;
|
||||||
|
}
|
||||||
|
if (entry.getKey().equals("nK1")) {
|
||||||
|
assertEquals("VVV", entry.getValue());
|
||||||
|
nK1Found = true;
|
||||||
|
}
|
||||||
|
if (entry.getKey().equals("nK2")) {
|
||||||
|
assertEquals("VVV", entry.getValue());
|
||||||
|
nK2Found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("regular Key not found", kFound);
|
||||||
|
assertTrue("deprecated Key not found", dKFound);
|
||||||
|
assertTrue("new Key 1 not found", nK1Found);
|
||||||
|
assertTrue("new Key 2 not found", nK2Found);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user