Author: shv
Date: Tue Jun 5 04:02:31 2012
New Revision: 1346229
URL: http://svn.apache.org/viewvc?rev=1346229&view=rev
Log:
HDFS-1860. when renewing/canceling DelegationToken over http we need to pass
exception information back to the caller. Contributed by Boris Shkolnik and
Benoy Antony.
Modified:
hadoop/common/branches/branch-0.22/hdfs/CHANGES.txt
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/DFSConfigKeys.java
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/HftpFileSystem.java
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/server/namenode/RenewDelegationTokenServlet.java
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/tools/DelegationTokenFetcher.java
Modified: hadoop/common/branches/branch-0.22/hdfs/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.22/hdfs/CHANGES.txt?rev=1346229&r1=1346228&r2=1346229&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.22/hdfs/CHANGES.txt (original)
+++ hadoop/common/branches/branch-0.22/hdfs/CHANGES.txt Tue Jun 5 04:02:31 2012
@@ -42,6 +42,10 @@ Release 0.22.1 - Unreleased
HDFS-3403. SecondaryNameNode doesn't start up in secure cluster.
(Benoy Antony via shv)
+ HDFS-1860. when renewing/canceling DelegationToken over http we need to
+ pass exception information back to the caller.
+ (Boris Shkolnik and Benoy Antony via shv)
+
Release 0.22.0 - 2011-11-29
INCOMPATIBLE CHANGES
Modified:
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/DFSConfigKeys.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/DFSConfigKeys.java?rev=1346229&r1=1346228&r2=1346229&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/DFSConfigKeys.java
(original)
+++
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/DFSConfigKeys.java
Tue Jun 5 04:02:31 2012
@@ -187,6 +187,8 @@ public class DFSConfigKeys extends Commo
public static final boolean DFS_SUPPORT_APPEND_DEFAULT = true;
public static final String DFS_HTTPS_ENABLE_KEY = "dfs.https.enable";
public static final boolean DFS_HTTPS_ENABLE_DEFAULT = false;
+ public static final String DFS_HTTPS_PORT_KEY = "dfs.https.port";
+ public static final int DFS_HTTPS_PORT_DEFAULT = 50470;
public static final String DFS_DEFAULT_CHUNK_VIEW_SIZE_KEY =
"dfs.default.chunk.view.size";
public static final int DFS_DEFAULT_CHUNK_VIEW_SIZE_DEFAULT = 32*1024;
public static final String DFS_DATANODE_HTTPS_ADDRESS_KEY =
"dfs.datanode.https.address";
Modified:
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/HftpFileSystem.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/HftpFileSystem.java?rev=1346229&r1=1346228&r2=1346229&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/HftpFileSystem.java
(original)
+++
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/HftpFileSystem.java
Tue Jun 5 04:02:31 2012
@@ -138,9 +138,18 @@ public class HftpFileSystem extends File
setConf(conf);
this.ugi = UserGroupInformation.getCurrentUser();
nnAddr = NetUtils.createSocketAddr(name.toString());
-
- nnHttpUrl = buildUri("https://",
NetUtils.normalizeHostName(name.getHost()),
- conf.getInt("dfs.https.port", DEFAULT_PORT));
+
+ // in case we open connection to hftp of a different cluster
+ // we need to know this cluster https port
+ // if it is not set we assume it is the same cluster or same port
+ int urlPort = conf.getInt("dfs.hftp.https.port", -1);
+ if(urlPort == -1)
+ urlPort = conf.getInt(DFSConfigKeys.DFS_HTTPS_PORT_KEY,
+ DFSConfigKeys.DFS_HTTPS_PORT_DEFAULT);
+
+ nnHttpUrl =
+ buildUri("https://", NetUtils.normalizeHostName(name.getHost()),
urlPort);
+ LOG.debug("using url to get DT:" + nnHttpUrl);
// if one uses RPC port different from the Default one,
// one should specify what is the setvice name for this delegation token
Modified:
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/server/namenode/RenewDelegationTokenServlet.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/server/namenode/RenewDelegationTokenServlet.java?rev=1346229&r1=1346228&r2=1346229&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/server/namenode/RenewDelegationTokenServlet.java
(original)
+++
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/server/namenode/RenewDelegationTokenServlet.java
Tue Jun 5 04:02:31 2012
@@ -78,9 +78,12 @@ public class RenewDelegationTokenServlet
os.println(result);
os.close();
} catch(Exception e) {
- LOG.info("Exception while renewing token. Re-throwing. ", e);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
- e.getMessage());
+ // transfer exception over the http
+ String exceptionClass = e.getClass().getName();
+ String exceptionMsg = e.getLocalizedMessage();
+ String strException = exceptionClass + ";" + exceptionMsg;
+ LOG.info("Exception while renewing token. Re-throwing. s=" +
strException, e);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
strException);
}
}
}
Modified:
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/tools/DelegationTokenFetcher.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/tools/DelegationTokenFetcher.java?rev=1346229&r1=1346228&r2=1346229&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/tools/DelegationTokenFetcher.java
(original)
+++
hadoop/common/branches/branch-0.22/hdfs/src/java/org/apache/hadoop/hdfs/tools/DelegationTokenFetcher.java
Tue Jun 5 04:02:31 2012
@@ -254,10 +254,12 @@ public class DelegationTokenFetcher {
buf.append("=");
buf.append(tok.encodeToUrlString());
BufferedReader in = null;
+ HttpURLConnection connection = null;
+
try {
URL url = new URL(buf.toString());
SecurityUtil.fetchServiceTicket(url);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection = (HttpURLConnection) url.openConnection();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Error renewing token: " +
connection.getResponseMessage());
@@ -268,11 +270,67 @@ public class DelegationTokenFetcher {
in.close();
return result;
} catch (IOException ie) {
+ LOG.info("error in renew over HTTP", ie);
+ IOException e = getExceptionFromResponse(connection);
+
IOUtils.cleanup(LOG, in);
+ if(e!=null) {
+ LOG.info("rethrowing exception from HTTP request: " +
e.getLocalizedMessage());
+ throw e;
+ }
throw ie;
}
}
+ // parse the message and extract the name of the exception and the message
+ static private IOException getExceptionFromResponse(HttpURLConnection con) {
+ IOException e = null;
+ String resp;
+ if(con == null)
+ return null;
+
+ try {
+ resp = con.getResponseMessage();
+ } catch (IOException ie) { return null; }
+ if(resp == null || resp.isEmpty())
+ return null;
+
+ String exceptionClass = "", exceptionMsg = "";
+ String[] rs = resp.split(";");
+ if(rs.length < 2)
+ return null;
+ exceptionClass = rs[0];
+ exceptionMsg = rs[1];
+ LOG.info("Error response from HTTP request=" + resp +
+ ";ec=" + exceptionClass + ";em="+exceptionMsg);
+
+ if(exceptionClass == null || exceptionClass.isEmpty())
+ return null;
+
+ // recreate exception objects
+ try {
+ Class<? extends Exception> ec =
+ Class.forName(exceptionClass).asSubclass(Exception.class);
+ // we are interested in constructor with String arguments
+ java.lang.reflect.Constructor<? extends Exception> constructor =
+ (java.lang.reflect.Constructor<? extends Exception>)
+ ec.getConstructor (new Class[] {String.class});
+
+ // create an instance
+ e = (IOException) constructor.newInstance (exceptionMsg);
+
+ } catch (Exception ee) {
+ LOG.warn("failed to create object of this class", ee);
+ }
+ if(e == null)
+ return null;
+
+ e.setStackTrace(new StackTraceElement[0]); // local stack is not relevant
+ LOG.info("Exception from HTTP response=" + e.getLocalizedMessage());
+ return e;
+ }
+
+
/**
* Cancel a Delegation Token.
* @param nnAddr the NameNode's address
@@ -290,16 +348,24 @@ public class DelegationTokenFetcher {
buf.append("=");
buf.append(tok.encodeToUrlString());
BufferedReader in = null;
+ HttpURLConnection connection=null;
try {
URL url = new URL(buf.toString());
SecurityUtil.fetchServiceTicket(url);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection = (HttpURLConnection) url.openConnection();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Error cancelling token: " +
connection.getResponseMessage());
}
} catch (IOException ie) {
+ LOG.info("error in cancel over HTTP", ie);
+ IOException e = getExceptionFromResponse(connection);
+
IOUtils.cleanup(LOG, in);
+ if(e!=null) {
+ LOG.info("rethrowing exception from HTTP request: " +
e.getLocalizedMessage());
+ throw e;
+ }
throw ie;
}
}