diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java index 378b83d13b..9f9c9741f3 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java @@ -228,6 +228,26 @@ public Builder append(String key, String value) { return this; } + /** + * Append new field which contains key and value to the context + * if the key("key:") is absent. + * @param key the key of field. + * @param value the value of field. + * @return the builder. + */ + public Builder appendIfAbsent(String key, String value) { + if (sb.toString().contains(key + KEY_VALUE_SEPARATOR)) { + return this; + } + if (isValid(key) && isValid(value)) { + if (sb.length() > 0) { + sb.append(fieldSeparator); + } + sb.append(key).append(KEY_VALUE_SEPARATOR).append(value); + } + return this; + } + public CallerContext build() { return new CallerContext(this); } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestCallerContext.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestCallerContext.java index fc1057b9f7..bb4a119e7d 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestCallerContext.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestCallerContext.java @@ -42,6 +42,37 @@ public void testBuilderAppend() { builder.build().getContext()); } + @Test + public void testBuilderAppendIfAbsent() { + Configuration conf = new Configuration(); + conf.set(HADOOP_CALLER_CONTEXT_SEPARATOR_KEY, "$"); + CallerContext.Builder builder = new CallerContext.Builder(null, conf); + builder.append("key1", "value1"); + Assert.assertEquals("key1:value1", + builder.build().getContext()); + + // Append an existed key with different value. + builder.appendIfAbsent("key1", "value2"); + String[] items = builder.build().getContext().split("\\$"); + Assert.assertEquals(1, items.length); + Assert.assertEquals("key1:value1", + builder.build().getContext()); + + // Append an absent key. + builder.appendIfAbsent("key2", "value2"); + String[] items2 = builder.build().getContext().split("\\$"); + Assert.assertEquals(2, items2.length); + Assert.assertEquals("key1:value1$key2:value2", + builder.build().getContext()); + + // Append a key that is a substring of an existing key. + builder.appendIfAbsent("key", "value"); + String[] items3 = builder.build().getContext().split("\\$"); + Assert.assertEquals(3, items3.length); + Assert.assertEquals("key1:value1$key2:value2$key:value", + builder.build().getContext()); + } + @Test(expected = IllegalArgumentException.class) public void testNewBuilder() { Configuration conf = new Configuration();