HADOOP-11103. Clean up RemoteException (Contributed by Sean Busbey)

(cherry picked from commit d4a2830b63)
This commit is contained in:
Vinayakumar B 2015-05-19 14:41:05 +05:30
parent fb49967e97
commit 5bbf157cb2
5 changed files with 35 additions and 11 deletions

View File

@ -120,6 +120,8 @@ Release 2.8.0 - UNRELEASED
HADOOP-1540. Support file exclusion list in distcp. (Rich Haase via jing9) HADOOP-1540. Support file exclusion list in distcp. (Rich Haase via jing9)
HADOOP-11103. Clean up RemoteException (Sean Busbey via vinayakumarb)
OPTIMIZATIONS OPTIMIZATIONS
HADOOP-11785. Reduce the number of listStatus operation in distcp HADOOP-11785. Reduce the number of listStatus operation in distcp

View File

@ -1139,10 +1139,7 @@ public class Client {
if (erCode == null) { if (erCode == null) {
LOG.warn("Detailed error code not set by server on rpc error"); LOG.warn("Detailed error code not set by server on rpc error");
} }
RemoteException re = RemoteException re = new RemoteException(exceptionClassName, errorMsg, erCode);
( (erCode == null) ?
new RemoteException(exceptionClassName, errorMsg) :
new RemoteException(exceptionClassName, errorMsg, erCode));
if (status == RpcStatusProto.ERROR) { if (status == RpcStatusProto.ERROR) {
calls.remove(callId); calls.remove(callId);
call.setException(re); call.setException(re);

View File

@ -25,31 +25,46 @@ import org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto.Rpc
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
public class RemoteException extends IOException { public class RemoteException extends IOException {
/** this value should not be defined in RpcHeader.proto so that protobuf will return a null */
private static final int UNSPECIFIED_ERROR = -1;
/** For java.io.Serializable */ /** For java.io.Serializable */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final int errorCode; private final int errorCode;
private String className; private final String className;
/**
* @param className wrapped exception, may be null
* @param msg may be null
*/
public RemoteException(String className, String msg) { public RemoteException(String className, String msg) {
super(msg); this(className, msg, null);
this.className = className;
errorCode = -1;
} }
/**
* @param className wrapped exception, may be null
* @param msg may be null
* @param erCode may be null
*/
public RemoteException(String className, String msg, RpcErrorCodeProto erCode) { public RemoteException(String className, String msg, RpcErrorCodeProto erCode) {
super(msg); super(msg);
this.className = className; this.className = className;
if (erCode != null) if (erCode != null)
errorCode = erCode.getNumber(); errorCode = erCode.getNumber();
else else
errorCode = -1; errorCode = UNSPECIFIED_ERROR;
} }
/**
* @return the class name for the wrapped exception; may be null if none was given.
*/
public String getClassName() { public String getClassName() {
return className; return className;
} }
/**
* @return may be null if the code was newer than our protobuf definitions or none was given.
*/
public RpcErrorCodeProto getErrorCode() { public RpcErrorCodeProto getErrorCode() {
return RpcErrorCodeProto.valueOf(errorCode); return RpcErrorCodeProto.valueOf(errorCode);
} }
@ -60,7 +75,7 @@ public class RemoteException extends IOException {
* <p> * <p>
* Unwraps any IOException. * Unwraps any IOException.
* *
* @param lookupTypes the desired exception class. * @param lookupTypes the desired exception class. may be null.
* @return IOException, which is either the lookupClass exception or this. * @return IOException, which is either the lookupClass exception or this.
*/ */
public IOException unwrapRemoteException(Class<?>... lookupTypes) { public IOException unwrapRemoteException(Class<?>... lookupTypes) {
@ -108,7 +123,10 @@ public class RemoteException extends IOException {
return ex; return ex;
} }
/** Create RemoteException from attributes */ /**
* Create RemoteException from attributes
* @param attrs may not be null
*/
public static RemoteException valueOf(Attributes attrs) { public static RemoteException valueOf(Attributes attrs) {
return new RemoteException(attrs.getValue("class"), return new RemoteException(attrs.getValue("class"),
attrs.getValue("message")); attrs.getValue("message"));

View File

@ -64,6 +64,7 @@ import org.apache.hadoop.io.retry.RetryPolicies;
import org.apache.hadoop.io.retry.RetryPolicy; import org.apache.hadoop.io.retry.RetryPolicy;
import org.apache.hadoop.io.retry.RetryProxy; import org.apache.hadoop.io.retry.RetryProxy;
import org.apache.hadoop.ipc.Client.ConnectionId; import org.apache.hadoop.ipc.Client.ConnectionId;
import org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto.RpcErrorCodeProto;
import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.AccessControlException;
@ -589,6 +590,7 @@ public class TestRPC {
} }
} catch (RemoteException e) { } catch (RemoteException e) {
if (expectFailure) { if (expectFailure) {
assertEquals("RPC error code should be UNAUTHORIZED", RpcErrorCodeProto.FATAL_UNAUTHORIZED, e.getErrorCode());
assertTrue(e.unwrapRemoteException() instanceof AuthorizationException); assertTrue(e.unwrapRemoteException() instanceof AuthorizationException);
} else { } else {
throw e; throw e;
@ -728,6 +730,7 @@ public class TestRPC {
proxy.echo(""); proxy.echo("");
} catch (RemoteException e) { } catch (RemoteException e) {
LOG.info("LOGGING MESSAGE: " + e.getLocalizedMessage()); LOG.info("LOGGING MESSAGE: " + e.getLocalizedMessage());
assertEquals("RPC error code should be UNAUTHORIZED", RpcErrorCodeProto.FATAL_UNAUTHORIZED, e.getErrorCode());
assertTrue(e.unwrapRemoteException() instanceof AccessControlException); assertTrue(e.unwrapRemoteException() instanceof AccessControlException);
succeeded = true; succeeded = true;
} finally { } finally {
@ -757,6 +760,7 @@ public class TestRPC {
proxy.echo(""); proxy.echo("");
} catch (RemoteException e) { } catch (RemoteException e) {
LOG.info("LOGGING MESSAGE: " + e.getLocalizedMessage()); LOG.info("LOGGING MESSAGE: " + e.getLocalizedMessage());
assertEquals("RPC error code should be UNAUTHORIZED", RpcErrorCodeProto.FATAL_UNAUTHORIZED, e.getErrorCode());
assertTrue(e.unwrapRemoteException() instanceof AccessControlException); assertTrue(e.unwrapRemoteException() instanceof AccessControlException);
succeeded = true; succeeded = true;
} finally { } finally {

View File

@ -62,6 +62,7 @@ import org.apache.hadoop.hdfs.server.namenode.NameNodeAdapter;
import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.ipc.RemoteException; import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.ipc.StandbyException; import org.apache.hadoop.ipc.StandbyException;
import org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto.RpcErrorCodeProto;
import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.test.GenericTestUtils;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.junit.After; import org.junit.After;
@ -774,6 +775,8 @@ public class TestHASafeMode {
fail("StandBy should throw exception for isInSafeMode"); fail("StandBy should throw exception for isInSafeMode");
} catch (IOException e) { } catch (IOException e) {
if (e instanceof RemoteException) { if (e instanceof RemoteException) {
assertEquals("RPC Error code should indicate app failure.", RpcErrorCodeProto.ERROR_APPLICATION,
((RemoteException) e).getErrorCode());
IOException sbExcpetion = ((RemoteException) e).unwrapRemoteException(); IOException sbExcpetion = ((RemoteException) e).unwrapRemoteException();
assertTrue("StandBy nn should not support isInSafeMode", assertTrue("StandBy nn should not support isInSafeMode",
sbExcpetion instanceof StandbyException); sbExcpetion instanceof StandbyException);