HDFS-9343. Empty caller context considered invalid. (Contributed by Mingliang Liu)

This commit is contained in:
Arpit Agarwal 2015-11-01 15:35:02 -08:00
parent 7fd6416759
commit 3cde6931cb
5 changed files with 28 additions and 13 deletions

View File

@ -44,6 +44,7 @@ public class CallerContext {
* {@link org.apache.hadoop.fs.CommonConfigurationKeysPublic#HADOOP_CALLER_CONTEXT_MAX_SIZE_DEFAULT} * {@link org.apache.hadoop.fs.CommonConfigurationKeysPublic#HADOOP_CALLER_CONTEXT_MAX_SIZE_DEFAULT}
*/ */
private final String context; private final String context;
/** The caller's signature for validation. /** The caller's signature for validation.
* *
* The signature is optional. The null or empty signature will be abandoned. * The signature is optional. The null or empty signature will be abandoned.
@ -58,10 +59,6 @@ public CallerContext(Builder builder) {
this.signature = builder.signature; this.signature = builder.signature;
} }
public boolean isValid() {
return context != null;
}
public String getContext() { public String getContext() {
return context; return context;
} }
@ -71,6 +68,11 @@ public byte[] getSignature() {
null : Arrays.copyOf(signature, signature.length); null : Arrays.copyOf(signature, signature.length);
} }
@InterfaceAudience.Private
public boolean isContextValid() {
return context != null && !context.isEmpty();
}
@Override @Override
public int hashCode() { public int hashCode() {
return new HashCodeBuilder().append(context).toHashCode(); return new HashCodeBuilder().append(context).toHashCode();
@ -92,9 +94,10 @@ public boolean equals(Object obj) {
.isEquals(); .isEquals();
} }
} }
@Override @Override
public String toString() { public String toString() {
if (!isValid()) { if (!isContextValid()) {
return ""; return "";
} }
String str = context; String str = context;

View File

@ -180,7 +180,7 @@ public static RpcRequestHeaderProto makeRpcRequestHeader(RPC.RpcKind rpcKind,
// Add caller context if it is not null // Add caller context if it is not null
CallerContext callerContext = CallerContext.getCurrent(); CallerContext callerContext = CallerContext.getCurrent();
if (callerContext != null && callerContext.isValid()) { if (callerContext != null && callerContext.isContextValid()) {
RPCCallerContextProto.Builder contextBuilder = RPCCallerContextProto RPCCallerContextProto.Builder contextBuilder = RPCCallerContextProto
.newBuilder().setContext(callerContext.getContext()); .newBuilder().setContext(callerContext.getContext());
if (callerContext.getSignature() != null) { if (callerContext.getSignature() != null) {

View File

@ -2201,6 +2201,9 @@ Release 2.8.0 - UNRELEASED
HDFS-9332. Fix Precondition failures from NameNodeEditLogRoller while HDFS-9332. Fix Precondition failures from NameNodeEditLogRoller while
saving namespace. (wang) saving namespace. (wang)
HDFS-9343. Empty caller context considered invalid. (Mingliang Liu via
Arpit Agarwal)
Release 2.7.2 - UNRELEASED Release 2.7.2 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -7498,9 +7498,7 @@ public void logAuditEvent(boolean succeeded, String userName,
sb.append(NamenodeWebHdfsMethods.isWebHdfsInvocation() ? "webhdfs" : "rpc"); sb.append(NamenodeWebHdfsMethods.isWebHdfsInvocation() ? "webhdfs" : "rpc");
if (isCallerContextEnabled && if (isCallerContextEnabled &&
callerContext != null && callerContext != null &&
callerContext.isValid() && callerContext.isContextValid()) {
(callerContext.getSignature() == null ||
callerContext.getSignature().length <= callerSignatureMaxLen)) {
sb.append("\t").append("callerContext="); sb.append("\t").append("callerContext=");
if (callerContext.getContext().length() > callerContextMaxLen) { if (callerContext.getContext().length() > callerContextMaxLen) {
sb.append(callerContext.getContext().substring(0, sb.append(callerContext.getContext().substring(0,
@ -7508,7 +7506,9 @@ public void logAuditEvent(boolean succeeded, String userName,
} else { } else {
sb.append(callerContext.getContext()); sb.append(callerContext.getContext());
} }
if (callerContext.getSignature() != null) { if (callerContext.getSignature() != null &&
callerContext.getSignature().length > 0 &&
callerContext.getSignature().length <= callerSignatureMaxLen) {
sb.append(":"); sb.append(":");
sb.append(new String(callerContext.getSignature(), sb.append(new String(callerContext.getSignature(),
CallerContext.SIGNATURE_ENCODING)); CallerContext.SIGNATURE_ENCODING));

View File

@ -243,7 +243,6 @@ public void testAuditLoggerWithCallContext() throws IOException {
CallerContext.setCurrent(context); CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent()); LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time); fs.setTimes(p, time, time);
System.out.println("LLLLLL" + auditlog.getOutput());
assertTrue(auditlog.getOutput().endsWith("callerContext=setTimes\n")); assertTrue(auditlog.getOutput().endsWith("callerContext=setTimes\n"));
auditlog.clearOutput(); auditlog.clearOutput();
@ -270,6 +269,16 @@ public void testAuditLoggerWithCallContext() throws IOException {
"callerContext=" + longContext.substring(0, 128) + ":L\n")); "callerContext=" + longContext.substring(0, 128) + ":L\n"));
auditlog.clearOutput(); auditlog.clearOutput();
// empty context is ignored
context = new CallerContext.Builder("")
.setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING))
.build();
CallerContext.setCurrent(context);
LOG.info("Set empty caller context");
fs.setTimes(p, time, time);
assertFalse(auditlog.getOutput().contains("callerContext="));
auditlog.clearOutput();
// caller context is inherited in child thread // caller context is inherited in child thread
context = new CallerContext.Builder("setTimes") context = new CallerContext.Builder("setTimes")
.setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)) .setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING))
@ -333,14 +342,14 @@ public void run() {
assertTrue(auditlog.getOutput().endsWith("callerContext=mkdirs:L\n")); assertTrue(auditlog.getOutput().endsWith("callerContext=mkdirs:L\n"));
auditlog.clearOutput(); auditlog.clearOutput();
// caller context with too long signature is abandoned // too long signature is ignored
context = new CallerContext.Builder("setTimes") context = new CallerContext.Builder("setTimes")
.setSignature(new byte[41]) .setSignature(new byte[41])
.build(); .build();
CallerContext.setCurrent(context); CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent()); LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time); fs.setTimes(p, time, time);
assertFalse(auditlog.getOutput().contains("callerContext=")); assertTrue(auditlog.getOutput().endsWith("callerContext=setTimes\n"));
auditlog.clearOutput(); auditlog.clearOutput();
// null signature is ignored // null signature is ignored