You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by su...@apache.org on 2012/01/05 19:51:47 UTC
svn commit: r1227744 - in
/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common: ./
src/main/java/org/apache/hadoop/fs/ src/main/java/org/apache/hadoop/ipc/
src/main/java/org/apache/hadoop/metrics/spi/
src/main/java/org/apache/hadoop/...
Author: suresh
Date: Thu Jan 5 18:51:47 2012
New Revision: 1227744
URL: http://svn.apache.org/viewvc?rev=1227744&view=rev
Log:
HDFS-7808 merging change r1227737 from trunk to 0.23 branch
Added:
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileSystemCanonicalization.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/NetUtilsTestResolver.java
Modified:
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics/spi/Util.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/Servers.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/TestNetUtils.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java
hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/CHANGES.txt Thu Jan 5 18:51:47 2012
@@ -51,6 +51,10 @@ Release 0.23.1 - Unreleased
HADOOP-7933. Add a getDelegationTokens api to FileSystem which checks
for known tokens in the passed Credentials object. (sseth)
+ HADOOP-7808. Port HADOOP-7510 - Add configurable option to use original
+ hostname in token instead of IP to allow server IP change.
+ (Daryn Sharp via suresh)
+
OPTIMIZATIONS
BUG FIXES
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java Thu Jan 5 18:51:47 2012
@@ -114,5 +114,11 @@ public class CommonConfigurationKeys ext
public static final String
HADOOP_SECURITY_SERVICE_AUTHORIZATION_REFRESH_USER_MAPPINGS =
"security.refresh.user.mappings.protocol.acl";
+
+ public static final String HADOOP_SECURITY_TOKEN_SERVICE_USE_IP =
+ "hadoop.security.token.service.use_ip";
+ public static final boolean HADOOP_SECURITY_TOKEN_SERVICE_USE_IP_DEFAULT =
+ true;
+
}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java Thu Jan 5 18:51:47 2012
@@ -47,6 +47,7 @@ import org.apache.hadoop.conf.Configured
import org.apache.hadoop.fs.Options.Rename;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.MultipleIOException;
+import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
@@ -187,6 +188,15 @@ public abstract class FileSystem extends
public abstract URI getUri();
/**
+ * Resolve the uri's hostname and add the default port if not in the uri
+ * @return URI
+ * @see NetUtils#getCanonicalUri(URI, int)
+ */
+ protected URI getCanonicalUri() {
+ return NetUtils.getCanonicalUri(getUri(), getDefaultPort());
+ }
+
+ /**
* Get the default port for this file system.
* @return the default port or 0 if there isn't one
*/
@@ -195,8 +205,13 @@ public abstract class FileSystem extends
}
/**
- * Get a canonical name for this file system.
- * @return a URI string that uniquely identifies this file system
+ * Get a canonical service name for this file system. The token cache is
+ * the only user of this value, and uses it to lookup this filesystem's
+ * service tokens. The token cache will not attempt to acquire tokens if the
+ * service is null.
+ * @return a service string that uniquely identifies this file system, null
+ * if the filesystem does not implement tokens
+ * @see SecurityUtil#buildDTServiceName(URI, int)
*/
public String getCanonicalServiceName() {
return SecurityUtil.buildDTServiceName(getUri(), getDefaultPort());
@@ -487,32 +502,31 @@ public abstract class FileSystem extends
*/
protected void checkPath(Path path) {
URI uri = path.toUri();
- if (uri.getScheme() == null) // fs is relative
- return;
- String thisScheme = this.getUri().getScheme();
String thatScheme = uri.getScheme();
- String thisAuthority = this.getUri().getAuthority();
- String thatAuthority = uri.getAuthority();
+ if (thatScheme == null) // fs is relative
+ return;
+ URI thisUri = getCanonicalUri();
+ String thisScheme = thisUri.getScheme();
//authority and scheme are not case sensitive
if (thisScheme.equalsIgnoreCase(thatScheme)) {// schemes match
- if (thisAuthority == thatAuthority || // & authorities match
- (thisAuthority != null &&
- thisAuthority.equalsIgnoreCase(thatAuthority)))
- return;
-
+ String thisAuthority = thisUri.getAuthority();
+ String thatAuthority = uri.getAuthority();
if (thatAuthority == null && // path's authority is null
thisAuthority != null) { // fs has an authority
- URI defaultUri = getDefaultUri(getConf()); // & is the conf default
- if (thisScheme.equalsIgnoreCase(defaultUri.getScheme()) &&
- thisAuthority.equalsIgnoreCase(defaultUri.getAuthority()))
- return;
- try { // or the default fs's uri
- defaultUri = get(getConf()).getUri();
- } catch (IOException e) {
- throw new RuntimeException(e);
+ URI defaultUri = getDefaultUri(getConf());
+ if (thisScheme.equalsIgnoreCase(defaultUri.getScheme())) {
+ uri = defaultUri; // schemes match, so use this uri instead
+ } else {
+ uri = null; // can't determine auth of the path
}
- if (thisScheme.equalsIgnoreCase(defaultUri.getScheme()) &&
- thisAuthority.equalsIgnoreCase(defaultUri.getAuthority()))
+ }
+ if (uri != null) {
+ // canonicalize uri before comparing with this fs
+ uri = NetUtils.getCanonicalUri(uri, getDefaultPort());
+ thatAuthority = uri.getAuthority();
+ if (thisAuthority == thatAuthority || // authorities match
+ (thisAuthority != null &&
+ thisAuthority.equalsIgnoreCase(thatAuthority)))
return;
}
}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FilterFileSystem.java Thu Jan 5 18:51:47 2012
@@ -77,6 +77,15 @@ public class FilterFileSystem extends Fi
return fs.getUri();
}
+ /**
+ * Returns a qualified URI whose scheme and authority identify this
+ * FileSystem.
+ */
+ @Override
+ protected URI getCanonicalUri() {
+ return fs.getCanonicalUri();
+ }
+
/** Make sure that a path specifies a FileSystem. */
public Path makeQualified(Path path) {
return fs.makeQualified(path);
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java Thu Jan 5 18:51:47 2012
@@ -417,7 +417,7 @@ public class Client {
*/
private synchronized boolean updateAddress() throws IOException {
// Do a fresh lookup with the old host name.
- InetSocketAddress currentAddr = new InetSocketAddress(
+ InetSocketAddress currentAddr = NetUtils.createSocketAddrForHost(
server.getHostName(), server.getPort());
if (!server.equals(currentAddr)) {
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics/spi/Util.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics/spi/Util.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics/spi/Util.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics/spi/Util.java Thu Jan 5 18:51:47 2012
@@ -28,6 +28,7 @@ import java.util.List;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.net.NetUtils;
/**
* Static utility methods
@@ -56,14 +57,7 @@ public class Util {
else {
String[] specStrings = specs.split("[ ,]+");
for (String specString : specStrings) {
- int colon = specString.indexOf(':');
- if (colon < 0 || colon == specString.length() - 1) {
- result.add(new InetSocketAddress(specString, defaultPort));
- } else {
- String hostname = specString.substring(0, colon);
- int port = Integer.parseInt(specString.substring(colon+1));
- result.add(new InetSocketAddress(hostname, port));
- }
+ result.add(NetUtils.createSocketAddr(specString, defaultPort));
}
}
return result;
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/Servers.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/Servers.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/Servers.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/Servers.java Thu Jan 5 18:51:47 2012
@@ -28,6 +28,7 @@ import com.google.common.collect.Lists;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.net.NetUtils;
/**
* Helpers to handle server addresses
@@ -57,14 +58,7 @@ public class Servers {
else {
String[] specStrings = specs.split("[ ,]+");
for (String specString : specStrings) {
- int colon = specString.indexOf(':');
- if (colon < 0 || colon == specString.length() - 1) {
- result.add(new InetSocketAddress(specString, defaultPort));
- } else {
- String hostname = specString.substring(0, colon);
- int port = Integer.parseInt(specString.substring(colon+1));
- result.add(new InetSocketAddress(hostname, port));
- }
+ result.add(NetUtils.createSocketAddr(specString, defaultPort));
}
}
return result;
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java Thu Jan 5 18:51:47 2012
@@ -37,6 +37,7 @@ import java.nio.channels.SocketChannel;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import javax.net.SocketFactory;
@@ -45,11 +46,17 @@ import org.apache.commons.logging.LogFac
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
import org.apache.hadoop.ipc.Server;
import org.apache.hadoop.ipc.VersionedProtocol;
+import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.util.ReflectionUtils;
+import com.google.common.annotations.VisibleForTesting;
+
+//this will need to be replaced someday when there is a suitable replacement
+import sun.net.dns.ResolverConfiguration;
+import sun.net.util.IPAddressUtil;
+
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Unstable
public class NetUtils {
@@ -65,6 +72,26 @@ public class NetUtils {
/** Base URL of the Hadoop Wiki: {@value} */
public static final String HADOOP_WIKI = "http://wiki.apache.org/hadoop/";
+ private static HostResolver hostResolver;
+
+ static {
+ // SecurityUtils requires a more secure host resolver if tokens are
+ // using hostnames
+ setUseQualifiedHostResolver(!SecurityUtil.getTokenServiceUseIp());
+ }
+
+ /**
+ * This method is intended for use only by SecurityUtils!
+ * @param flag where the qualified or standard host resolver is used
+ * to create socket addresses
+ */
+ @InterfaceAudience.Private
+ public static void setUseQualifiedHostResolver(boolean flag) {
+ hostResolver = flag
+ ? new QualifiedHostResolver()
+ : new StandardHostResolver();
+ }
+
/**
* Get the socket factory for the given class according to its
* configuration parameter
@@ -178,43 +205,256 @@ public class NetUtils {
throw new IllegalArgumentException("Target address cannot be null." +
helpText);
}
- int colonIndex = target.indexOf(':');
- if (colonIndex < 0 && defaultPort == -1) {
- throw new RuntimeException("Not a host:port pair: " + target +
- helpText);
+ boolean hasScheme = target.contains("://");
+ URI uri = null;
+ try {
+ uri = hasScheme ? URI.create(target) : URI.create("dummyscheme://"+target);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "Does not contain a valid host:port authority: " + target + helpText
+ );
+ }
+
+ String host = uri.getHost();
+ int port = uri.getPort();
+ if (port == -1) {
+ port = defaultPort;
+ }
+ String path = uri.getPath();
+
+ if ((host == null) || (port < 0) ||
+ (!hasScheme && path != null && !path.isEmpty()))
+ {
+ throw new IllegalArgumentException(
+ "Does not contain a valid host:port authority: " + target + helpText
+ );
+ }
+ return createSocketAddrForHost(host, port);
+ }
+
+ /**
+ * Create a socket address with the given host and port. The hostname
+ * might be replaced with another host that was set via
+ * {@link #addStaticResolution(String, String)}. The value of
+ * hadoop.security.token.service.use_ip will determine whether the
+ * standard java host resolver is used, or if the fully qualified resolver
+ * is used.
+ * @param host the hostname or IP use to instantiate the object
+ * @param port the port number
+ * @return InetSocketAddress
+ */
+ public static InetSocketAddress createSocketAddrForHost(String host, int port) {
+ String staticHost = getStaticResolution(host);
+ String resolveHost = (staticHost != null) ? staticHost : host;
+
+ InetSocketAddress addr;
+ try {
+ InetAddress iaddr = hostResolver.getByName(resolveHost);
+ // if there is a static entry for the host, make the returned
+ // address look like the original given host
+ if (staticHost != null) {
+ iaddr = InetAddress.getByAddress(host, iaddr.getAddress());
+ }
+ addr = new InetSocketAddress(iaddr, port);
+ } catch (UnknownHostException e) {
+ addr = InetSocketAddress.createUnresolved(host, port);
}
- String hostname;
- int port = -1;
- if (!target.contains("/")) {
- if (colonIndex == -1) {
- hostname = target;
+ return addr;
+ }
+
+ interface HostResolver {
+ InetAddress getByName(String host) throws UnknownHostException;
+ }
+
+ /**
+ * Uses standard java host resolution
+ */
+ static class StandardHostResolver implements HostResolver {
+ public InetAddress getByName(String host) throws UnknownHostException {
+ return InetAddress.getByName(host);
+ }
+ }
+
+ /**
+ * This an alternate resolver with important properties that the standard
+ * java resolver lacks:
+ * 1) The hostname is fully qualified. This avoids security issues if not
+ * all hosts in the cluster do not share the same search domains. It
+ * also prevents other hosts from performing unnecessary dns searches.
+ * In contrast, InetAddress simply returns the host as given.
+ * 2) The InetAddress is instantiated with an exact host and IP to prevent
+ * further unnecessary lookups. InetAddress may perform an unnecessary
+ * reverse lookup for an IP.
+ * 3) A call to getHostName() will always return the qualified hostname, or
+ * more importantly, the IP if instantiated with an IP. This avoids
+ * unnecessary dns timeouts if the host is not resolvable.
+ * 4) Point 3 also ensures that if the host is re-resolved, ex. during a
+ * connection re-attempt, that a reverse lookup to host and forward
+ * lookup to IP is not performed since the reverse/forward mappings may
+ * not always return the same IP. If the client initiated a connection
+ * with an IP, then that IP is all that should ever be contacted.
+ *
+ * NOTE: this resolver is only used if:
+ * hadoop.security.token.service.use_ip=false
+ */
+ protected static class QualifiedHostResolver implements HostResolver {
+ @SuppressWarnings("unchecked")
+ private List<String> searchDomains =
+ ResolverConfiguration.open().searchlist();
+
+ /**
+ * Create an InetAddress with a fully qualified hostname of the given
+ * hostname. InetAddress does not qualify an incomplete hostname that
+ * is resolved via the domain search list.
+ * {@link InetAddress#getCanonicalHostName()} will fully qualify the
+ * hostname, but it always return the A record whereas the given hostname
+ * may be a CNAME.
+ *
+ * @param host a hostname or ip address
+ * @return InetAddress with the fully qualified hostname or ip
+ * @throws UnknownHostException if host does not exist
+ */
+ public InetAddress getByName(String host) throws UnknownHostException {
+ InetAddress addr = null;
+
+ if (IPAddressUtil.isIPv4LiteralAddress(host)) {
+ // use ipv4 address as-is
+ byte[] ip = IPAddressUtil.textToNumericFormatV4(host);
+ addr = InetAddress.getByAddress(host, ip);
+ } else if (IPAddressUtil.isIPv6LiteralAddress(host)) {
+ // use ipv6 address as-is
+ byte[] ip = IPAddressUtil.textToNumericFormatV6(host);
+ addr = InetAddress.getByAddress(host, ip);
+ } else if (host.endsWith(".")) {
+ // a rooted host ends with a dot, ex. "host."
+ // rooted hosts never use the search path, so only try an exact lookup
+ addr = getByExactName(host);
+ } else if (host.contains(".")) {
+ // the host contains a dot (domain), ex. "host.domain"
+ // try an exact host lookup, then fallback to search list
+ addr = getByExactName(host);
+ if (addr == null) {
+ addr = getByNameWithSearch(host);
+ }
} else {
- // must be the old style <host>:<port>
- hostname = target.substring(0, colonIndex);
- String portStr = target.substring(colonIndex + 1);
- try {
- port = Integer.parseInt(portStr);
- } catch (NumberFormatException nfe) {
- throw new IllegalArgumentException(
- "Can't parse port '" + portStr + "'"
- + helpText);
+ // it's a simple host with no dots, ex. "host"
+ // try the search list, then fallback to exact host
+ InetAddress loopback = InetAddress.getByName(null);
+ if (host.equalsIgnoreCase(loopback.getHostName())) {
+ addr = InetAddress.getByAddress(host, loopback.getAddress());
+ } else {
+ addr = getByNameWithSearch(host);
+ if (addr == null) {
+ addr = getByExactName(host);
+ }
}
}
- } else {
- // a new uri
- URI addr = new Path(target).toUri();
- hostname = addr.getHost();
- port = addr.getPort();
+ // unresolvable!
+ if (addr == null) {
+ throw new UnknownHostException(host);
+ }
+ return addr;
}
- if (port == -1) {
- port = defaultPort;
+ InetAddress getByExactName(String host) {
+ InetAddress addr = null;
+ // InetAddress will use the search list unless the host is rooted
+ // with a trailing dot. The trailing dot will disable any use of the
+ // search path in a lower level resolver. See RFC 1535.
+ String fqHost = host;
+ if (!fqHost.endsWith(".")) fqHost += ".";
+ try {
+ addr = getInetAddressByName(fqHost);
+ // can't leave the hostname as rooted or other parts of the system
+ // malfunction, ex. kerberos principals are lacking proper host
+ // equivalence for rooted/non-rooted hostnames
+ addr = InetAddress.getByAddress(host, addr.getAddress());
+ } catch (UnknownHostException e) {
+ // ignore, caller will throw if necessary
+ }
+ return addr;
+ }
+
+ InetAddress getByNameWithSearch(String host) {
+ InetAddress addr = null;
+ if (host.endsWith(".")) { // already qualified?
+ addr = getByExactName(host);
+ } else {
+ for (String domain : searchDomains) {
+ String dot = !domain.startsWith(".") ? "." : "";
+ addr = getByExactName(host + dot + domain);
+ if (addr != null) break;
+ }
+ }
+ return addr;
+ }
+
+ // implemented as a separate method to facilitate unit testing
+ InetAddress getInetAddressByName(String host) throws UnknownHostException {
+ return InetAddress.getByName(host);
}
+
+ void setSearchDomains(String ... domains) {
+ searchDomains = Arrays.asList(domains);
+ }
+ }
+
+ /**
+ * This is for testing only!
+ */
+ @VisibleForTesting
+ static void setHostResolver(HostResolver newResolver) {
+ hostResolver = newResolver;
+ }
- if (getStaticResolution(hostname) != null) {
- hostname = getStaticResolution(hostname);
+ /**
+ * Resolve the uri's hostname and add the default port if not in the uri
+ * @param uri to resolve
+ * @param defaultPort if none is given
+ * @return URI
+ */
+ public static URI getCanonicalUri(URI uri, int defaultPort) {
+ // skip if there is no authority, ie. "file" scheme or relative uri
+ String host = uri.getHost();
+ if (host == null) {
+ return uri;
+ }
+ String fqHost = canonicalizeHost(host);
+ int port = uri.getPort();
+ // short out if already canonical with a port
+ if (host.equals(fqHost) && port != -1) {
+ return uri;
+ }
+ // reconstruct the uri with the canonical host and port
+ try {
+ uri = new URI(uri.getScheme(), uri.getUserInfo(),
+ fqHost, (port == -1) ? defaultPort : port,
+ uri.getPath(), uri.getQuery(), uri.getFragment());
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ return uri;
+ }
+
+ // cache the canonicalized hostnames; the cache currently isn't expired,
+ // but the canonicals will only change if the host's resolver configuration
+ // changes
+ private static final ConcurrentHashMap<String, String> canonicalizedHostCache =
+ new ConcurrentHashMap<String, String>();
+
+ private static String canonicalizeHost(String host) {
+ // check if the host has already been canonicalized
+ String fqHost = canonicalizedHostCache.get(host);
+ if (fqHost == null) {
+ try {
+ fqHost = hostResolver.getByName(host).getHostName();
+ // slight race condition, but won't hurt
+ canonicalizedHostCache.put(host, fqHost);
+ } catch (UnknownHostException e) {
+ fqHost = host;
+ }
}
- return new InetSocketAddress(hostname, port);
+ return fqHost;
}
/**
@@ -279,8 +519,8 @@ public class NetUtils {
*/
public static InetSocketAddress getConnectAddress(Server server) {
InetSocketAddress addr = server.getListenerAddress();
- if (addr.getAddress().getHostAddress().equals("0.0.0.0")) {
- addr = new InetSocketAddress("127.0.0.1", addr.getPort());
+ if (addr.getAddress().isAnyLocalAddress()) {
+ addr = createSocketAddrForHost("127.0.0.1", addr.getPort());
}
return addr;
}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java Thu Jan 5 18:51:47 2012
@@ -35,6 +35,7 @@ import org.apache.commons.logging.LogFac
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.token.Token;
@@ -50,6 +51,35 @@ public class SecurityUtil {
public static final Log LOG = LogFactory.getLog(SecurityUtil.class);
public static final String HOSTNAME_PATTERN = "_HOST";
+ // controls whether buildTokenService will use an ip or host/ip as given
+ // by the user
+ private static boolean useIpForTokenService;
+
+ static {
+ boolean useIp = new Configuration().getBoolean(
+ CommonConfigurationKeys.HADOOP_SECURITY_TOKEN_SERVICE_USE_IP,
+ CommonConfigurationKeys.HADOOP_SECURITY_TOKEN_SERVICE_USE_IP_DEFAULT);
+ setTokenServiceUseIp(useIp);
+ }
+
+ /**
+ * For use only by tests and initialization
+ */
+ @InterfaceAudience.Private
+ static void setTokenServiceUseIp(boolean flag) {
+ useIpForTokenService = flag;
+ NetUtils.setUseQualifiedHostResolver(!flag);
+ }
+
+ /**
+ * Intended only for temporary use by NetUtils. Do not use.
+ * @return whether tokens use an IP address
+ */
+ @InterfaceAudience.Private
+ public static boolean getTokenServiceUseIp() {
+ return useIpForTokenService;
+ }
+
/**
* Find the original TGT within the current subject's credentials. Cross-realm
* TGT's of the form "krbtgt/TWO.COM@ONE.COM" may be present.
@@ -263,29 +293,20 @@ public class SecurityUtil {
}
/**
- * create service name for Delegation token ip:port
- * @param uri
- * @param defPort
- * @return "ip:port"
+ * create the service name for a Delegation token
+ * @param uri of the service
+ * @param defPort is used if the uri lacks a port
+ * @return the token service, or null if no authority
+ * @see #buildTokenService(InetSocketAddress)
*/
public static String buildDTServiceName(URI uri, int defPort) {
- int port = uri.getPort();
- if(port == -1)
- port = defPort;
-
- // build the service name string "/ip:port"
- // for whatever reason using NetUtils.createSocketAddr(target).toString()
- // returns "localhost/ip:port"
- StringBuffer sb = new StringBuffer();
- String host = uri.getHost();
- if (host != null) {
- host = NetUtils.normalizeHostName(host);
- } else {
- host = "";
+ String authority = uri.getAuthority();
+ if (authority == null) {
+ return null;
}
- sb.append(host).append(":").append(port);
- return sb.toString();
- }
+ InetSocketAddress addr = NetUtils.createSocketAddr(authority, defPort);
+ return buildTokenService(addr).toString();
+ }
/**
* Get the host name from the principal name of format <service>/host@realm.
@@ -368,21 +389,57 @@ public class SecurityUtil {
}
/**
+ * Decode the given token's service field into an InetAddress
+ * @param token from which to obtain the service
+ * @return InetAddress for the service
+ */
+ public static InetSocketAddress getTokenServiceAddr(Token<?> token) {
+ return NetUtils.createSocketAddr(token.getService().toString());
+ }
+
+ /**
* Set the given token's service to the format expected by the RPC client
* @param token a delegation token
* @param addr the socket for the rpc connection
*/
public static void setTokenService(Token<?> token, InetSocketAddress addr) {
- token.setService(buildTokenService(addr));
+ Text service = buildTokenService(addr);
+ if (token != null) {
+ token.setService(service);
+ LOG.info("Acquired token "+token); // Token#toString() prints service
+ } else {
+ LOG.warn("Failed to get token for service "+service);
+ }
}
/**
* Construct the service key for a token
* @param addr InetSocketAddress of remote connection with a token
- * @return "ip:port"
+ * @return "ip:port" or "host:port" depending on the value of
+ * hadoop.security.token.service.use_ip
*/
public static Text buildTokenService(InetSocketAddress addr) {
- String host = addr.getAddress().getHostAddress();
+ String host = null;
+ if (useIpForTokenService) {
+ if (addr.isUnresolved()) { // host has no ip address
+ throw new IllegalArgumentException(
+ new UnknownHostException(addr.getHostName())
+ );
+ }
+ host = addr.getAddress().getHostAddress();
+ } else {
+ host = addr.getHostName().toLowerCase();
+ }
return new Text(host + ":" + addr.getPort());
}
+
+ /**
+ * Construct the service key for a token
+ * @param uri of remote connection with a token
+ * @return "ip:port" or "host:port" depending on the value of
+ * hadoop.security.token.service.use_ip
+ */
+ public static Text buildTokenService(URI uri) {
+ return buildTokenService(NetUtils.createSocketAddr(uri.getAuthority()));
+ }
}
Added: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileSystemCanonicalization.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileSystemCanonicalization.java?rev=1227744&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileSystemCanonicalization.java (added)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileSystemCanonicalization.java Thu Jan 5 18:51:47 2012
@@ -0,0 +1,365 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.fs;
+
+import java.io.IOException;
+import java.net.URI;
+
+import junit.framework.TestCase;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.net.NetUtilsTestResolver;
+import org.apache.hadoop.util.Progressable;
+import org.junit.Test;
+
+public class TestFileSystemCanonicalization extends TestCase {
+ static String[] authorities = {
+ "myfs://host",
+ "myfs://host.a",
+ "myfs://host.a.b",
+ };
+
+ static String[] ips = {
+ "myfs://127.0.0.1"
+ };
+
+
+ @Test
+ public void testSetupResolver() throws Exception {
+ NetUtilsTestResolver.install();
+ }
+
+ // no ports
+
+ @Test
+ public void testShortAuthority() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testPartialAuthority() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testFullAuthority() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a.b", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ // with default ports
+
+ @Test
+ public void testShortAuthorityWithDefaultPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host:123", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testPartialAuthorityWithDefaultPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a:123", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testFullAuthorityWithDefaultPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a.b:123", "myfs://host.a.b:123");
+ verifyPaths(fs, authorities, -1, true);
+ verifyPaths(fs, authorities, 123, true);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ // with non-standard ports
+
+ @Test
+ public void testShortAuthorityWithOtherPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host:456", "myfs://host.a.b:456");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, true);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testPartialAuthorityWithOtherPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a:456", "myfs://host.a.b:456");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, true);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testFullAuthorityWithOtherPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://host.a.b:456", "myfs://host.a.b:456");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, true);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ // ips
+
+ @Test
+ public void testIpAuthority() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://127.0.0.1", "myfs://127.0.0.1:123");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, true);
+ verifyPaths(fs, ips, 123, true);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testIpAuthorityWithDefaultPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://127.0.0.1:123", "myfs://127.0.0.1:123");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, true);
+ verifyPaths(fs, ips, 123, true);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testIpAuthorityWithOtherPort() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://127.0.0.1:456", "myfs://127.0.0.1:456");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, true);
+ }
+
+ // bad stuff
+
+ @Test
+ public void testMismatchedSchemes() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs2://simple", "myfs2://simple:123");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testMismatchedHosts() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs://simple", "myfs://simple:123");
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testNullAuthority() throws Exception {
+ FileSystem fs = getVerifiedFS("myfs:///", "myfs:///");
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, true);
+ verifyPaths(fs, authorities, -1, false);
+ verifyPaths(fs, authorities, 123, false);
+ verifyPaths(fs, authorities, 456, false);
+ verifyPaths(fs, ips, -1, false);
+ verifyPaths(fs, ips, 123, false);
+ verifyPaths(fs, ips, 456, false);
+ }
+
+ @Test
+ public void testAuthorityFromDefaultFS() throws Exception {
+ Configuration config = new Configuration();
+ String defaultFsKey = CommonConfigurationKeys.FS_DEFAULT_NAME_KEY;
+
+ FileSystem fs = getVerifiedFS("myfs://host", "myfs://host.a.b:123", config);
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, false);
+
+ config.set(defaultFsKey, "myfs://host");
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, true);
+
+ config.set(defaultFsKey, "myfs2://host");
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, false);
+
+ config.set(defaultFsKey, "myfs://host:123");
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, true);
+
+ config.set(defaultFsKey, "myfs://host:456");
+ verifyPaths(fs, new String[]{ "myfs://" }, -1, false);
+ }
+
+ FileSystem getVerifiedFS(String authority, String canonical) throws Exception {
+ return getVerifiedFS(authority, canonical, new Configuration());
+ }
+
+ // create a fs from the authority, then check its uri against the given uri
+ // and the canonical. then try to fetch paths using the canonical
+ FileSystem getVerifiedFS(String authority, String canonical, Configuration conf)
+ throws Exception {
+ URI uri = URI.create(authority);
+ URI canonicalUri = URI.create(canonical);
+
+ FileSystem fs = new DummyFileSystem(uri, conf);
+ assertEquals(uri, fs.getUri());
+ assertEquals(canonicalUri, fs.getCanonicalUri());
+ verifyCheckPath(fs, "/file", true);
+ return fs;
+ }
+
+ void verifyPaths(FileSystem fs, String[] uris, int port, boolean shouldPass) {
+ for (String uri : uris) {
+ if (port != -1) uri += ":"+port;
+ verifyCheckPath(fs, uri+"/file", shouldPass);
+ }
+ }
+
+ void verifyCheckPath(FileSystem fs, String path, boolean shouldPass) {
+ Path rawPath = new Path(path);
+ Path fqPath = null;
+ Exception e = null;
+ try {
+ fqPath = fs.makeQualified(rawPath);
+ } catch (IllegalArgumentException iae) {
+ e = iae;
+ }
+ if (shouldPass) {
+ assertEquals(null, e);
+ String pathAuthority = rawPath.toUri().getAuthority();
+ if (pathAuthority == null) {
+ pathAuthority = fs.getUri().getAuthority();
+ }
+ assertEquals(pathAuthority, fqPath.toUri().getAuthority());
+ } else {
+ assertNotNull("did not fail", e);
+ assertEquals("Wrong FS: "+rawPath+", expected: "+fs.getUri(),
+ e.getMessage());
+ }
+ }
+
+ static class DummyFileSystem extends FileSystem {
+ URI uri;
+ static int defaultPort = 123;
+
+ DummyFileSystem(URI uri, Configuration conf) throws IOException {
+ this.uri = uri;
+ setConf(conf);
+ }
+
+ @Override
+ public URI getUri() {
+ return uri;
+ }
+
+ @Override
+ protected int getDefaultPort() {
+ return defaultPort;
+ }
+
+ @Override
+ public FSDataInputStream open(Path f, int bufferSize) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public FSDataOutputStream create(Path f, FsPermission permission,
+ boolean overwrite, int bufferSize, short replication, long blockSize,
+ Progressable progress) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public FSDataOutputStream append(Path f, int bufferSize,
+ Progressable progress) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public boolean rename(Path src, Path dst) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public boolean delete(Path f, boolean recursive) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public FileStatus[] listStatus(Path f) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public void setWorkingDirectory(Path new_dir) {
+ }
+
+ @Override
+ public Path getWorkingDirectory() {
+ return new Path("/");
+ }
+
+ @Override
+ public boolean mkdirs(Path f, FsPermission permission) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+
+ @Override
+ public FileStatus getFileStatus(Path f) throws IOException {
+ throw new IOException("not supposed to be here");
+ }
+ }
+}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java Thu Jan 5 18:51:47 2012
@@ -34,6 +34,7 @@ import org.apache.hadoop.fs.CommonConfig
import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.KerberosInfo;
+import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.ProxyUsers;
import org.apache.hadoop.security.token.Token;
@@ -213,8 +214,7 @@ public class MiniRPCBenchmark {
token = p.getDelegationToken(new Text(RENEWER));
currentUgi = UserGroupInformation.createUserForTesting(MINI_USER,
GROUP_NAMES);
- token.setService(new Text(addr.getAddress().getHostAddress()
- + ":" + addr.getPort()));
+ SecurityUtil.setTokenService(token, addr);
currentUgi.addToken(token);
return p;
}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java Thu Jan 5 18:51:47 2012
@@ -287,10 +287,7 @@ public class TestSaslRPC {
.getUserName()));
Token<TestTokenIdentifier> token = new Token<TestTokenIdentifier>(tokenId,
sm);
- Text host = new Text(addr.getAddress().getHostAddress() + ":"
- + addr.getPort());
- token.setService(host);
- LOG.info("Service IP address for token is " + host);
+ SecurityUtil.setTokenService(token, addr);
current.addToken(token);
TestSaslProtocol proxy = null;
@@ -362,10 +359,7 @@ public class TestSaslRPC {
.getUserName()));
Token<TestTokenIdentifier> token = new Token<TestTokenIdentifier>(tokenId,
sm);
- Text host = new Text(addr.getAddress().getHostAddress() + ":"
- + addr.getPort());
- token.setService(host);
- LOG.info("Service IP address for token is " + host);
+ SecurityUtil.setTokenService(token, addr);
current.addToken(token);
Configuration newConf = new Configuration(conf);
@@ -452,10 +446,7 @@ public class TestSaslRPC {
.getUserName()));
Token<TestTokenIdentifier> token = new Token<TestTokenIdentifier>(tokenId,
sm);
- Text host = new Text(addr.getAddress().getHostAddress() + ":"
- + addr.getPort());
- token.setService(host);
- LOG.info("Service IP address for token is " + host);
+ SecurityUtil.setTokenService(token, addr);
current.addToken(token);
current.doAs(new PrivilegedExceptionAction<Object>() {
Added: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/NetUtilsTestResolver.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/NetUtilsTestResolver.java?rev=1227744&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/NetUtilsTestResolver.java (added)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/NetUtilsTestResolver.java Thu Jan 5 18:51:47 2012
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.net;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.net.NetUtils.QualifiedHostResolver;
+
+/**
+ * provides a dummy dns search resolver with a configurable search path
+ * and host mapping
+ */
+public class NetUtilsTestResolver extends QualifiedHostResolver {
+ Map<String, InetAddress> resolvedHosts = new HashMap<String, InetAddress>();
+ List<String> hostSearches = new LinkedList<String>();
+
+ public static NetUtilsTestResolver install() {
+ NetUtilsTestResolver resolver = new NetUtilsTestResolver();
+ resolver.setSearchDomains("a.b", "b", "c");
+ resolver.addResolvedHost("host.a.b.", "1.1.1.1");
+ resolver.addResolvedHost("b-host.b.", "2.2.2.2");
+ resolver.addResolvedHost("simple.", "3.3.3.3");
+ NetUtils.setHostResolver(resolver);
+ return resolver;
+ }
+
+ public void addResolvedHost(String host, String ip) {
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(ip);
+ addr = InetAddress.getByAddress(host, addr.getAddress());
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("not an ip:"+ip);
+ }
+ resolvedHosts.put(host, addr);
+ }
+
+ InetAddress getInetAddressByName(String host) throws UnknownHostException {
+ hostSearches.add(host);
+ if (!resolvedHosts.containsKey(host)) {
+ throw new UnknownHostException(host);
+ }
+ return resolvedHosts.get(host);
+ }
+
+ String[] getHostSearches() {
+ return hostSearches.toArray(new String[0]);
+ }
+
+ void reset() {
+ hostSearches.clear();
+ }
+}
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/TestNetUtils.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/TestNetUtils.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/TestNetUtils.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/TestNetUtils.java Thu Jan 5 18:51:47 2012
@@ -17,25 +17,29 @@
*/
package org.apache.hadoop.net;
-import junit.framework.AssertionFailedError;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.Test;
-
import static org.junit.Assert.*;
import java.io.IOException;
import java.net.BindException;
+import java.net.ConnectException;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
-import java.net.ConnectException;
import java.net.SocketException;
-import java.net.InetSocketAddress;
+import java.net.URI;
import java.net.UnknownHostException;
import java.util.Enumeration;
+import junit.framework.AssertionFailedError;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
public class TestNetUtils {
@@ -248,4 +252,255 @@ public class TestNetUtils {
}
return wrapped;
}
-}
+
+ static NetUtilsTestResolver resolver;
+ static Configuration config;
+
+ @BeforeClass
+ public static void setupResolver() {
+ resolver = NetUtilsTestResolver.install();
+ }
+
+ @Before
+ public void resetResolver() {
+ resolver.reset();
+ config = new Configuration();
+ }
+
+ // getByExactName
+
+ private void verifyGetByExactNameSearch(String host, String ... searches) {
+ assertNull(resolver.getByExactName(host));
+ assertBetterArrayEquals(searches, resolver.getHostSearches());
+ }
+
+ @Test
+ public void testResolverGetByExactNameUnqualified() {
+ verifyGetByExactNameSearch("unknown", "unknown.");
+ }
+
+ @Test
+ public void testResolverGetByExactNameUnqualifiedWithDomain() {
+ verifyGetByExactNameSearch("unknown.domain", "unknown.domain.");
+ }
+
+ @Test
+ public void testResolverGetByExactNameQualified() {
+ verifyGetByExactNameSearch("unknown.", "unknown.");
+ }
+
+ @Test
+ public void testResolverGetByExactNameQualifiedWithDomain() {
+ verifyGetByExactNameSearch("unknown.domain.", "unknown.domain.");
+ }
+
+ // getByNameWithSearch
+
+ private void verifyGetByNameWithSearch(String host, String ... searches) {
+ assertNull(resolver.getByNameWithSearch(host));
+ assertBetterArrayEquals(searches, resolver.getHostSearches());
+ }
+
+ @Test
+ public void testResolverGetByNameWithSearchUnqualified() {
+ String host = "unknown";
+ verifyGetByNameWithSearch(host, host+".a.b.", host+".b.", host+".c.");
+ }
+
+ @Test
+ public void testResolverGetByNameWithSearchUnqualifiedWithDomain() {
+ String host = "unknown.domain";
+ verifyGetByNameWithSearch(host, host+".a.b.", host+".b.", host+".c.");
+ }
+
+ @Test
+ public void testResolverGetByNameWithSearchQualified() {
+ String host = "unknown.";
+ verifyGetByNameWithSearch(host, host);
+ }
+
+ @Test
+ public void testResolverGetByNameWithSearchQualifiedWithDomain() {
+ String host = "unknown.domain.";
+ verifyGetByNameWithSearch(host, host);
+ }
+
+ // getByName
+
+ private void verifyGetByName(String host, String ... searches) {
+ InetAddress addr = null;
+ try {
+ addr = resolver.getByName(host);
+ } catch (UnknownHostException e) {} // ignore
+ assertNull(addr);
+ assertBetterArrayEquals(searches, resolver.getHostSearches());
+ }
+
+ @Test
+ public void testResolverGetByNameQualified() {
+ String host = "unknown.";
+ verifyGetByName(host, host);
+ }
+
+ @Test
+ public void testResolverGetByNameQualifiedWithDomain() {
+ verifyGetByName("unknown.domain.", "unknown.domain.");
+ }
+
+ @Test
+ public void testResolverGetByNameUnqualified() {
+ String host = "unknown";
+ verifyGetByName(host, host+".a.b.", host+".b.", host+".c.", host+".");
+ }
+
+ @Test
+ public void testResolverGetByNameUnqualifiedWithDomain() {
+ String host = "unknown.domain";
+ verifyGetByName(host, host+".", host+".a.b.", host+".b.", host+".c.");
+ }
+
+ // resolving of hosts
+
+ private InetAddress verifyResolve(String host, String ... searches) {
+ InetAddress addr = null;
+ try {
+ addr = resolver.getByName(host);
+ } catch (UnknownHostException e) {} // ignore
+ assertNotNull(addr);
+ assertBetterArrayEquals(searches, resolver.getHostSearches());
+ return addr;
+ }
+
+ private void
+ verifyInetAddress(InetAddress addr, String host, String ip) {
+ assertNotNull(addr);
+ assertEquals(host, addr.getHostName());
+ assertEquals(ip, addr.getHostAddress());
+ }
+
+ @Test
+ public void testResolverUnqualified() {
+ String host = "host";
+ InetAddress addr = verifyResolve(host, host+".a.b.");
+ verifyInetAddress(addr, "host.a.b", "1.1.1.1");
+ }
+
+ @Test
+ public void testResolverUnqualifiedWithDomain() {
+ String host = "host.a";
+ InetAddress addr = verifyResolve(host, host+".", host+".a.b.", host+".b.");
+ verifyInetAddress(addr, "host.a.b", "1.1.1.1");
+ }
+
+ @Test
+ public void testResolverUnqualifedFull() {
+ String host = "host.a.b";
+ InetAddress addr = verifyResolve(host, host+".");
+ verifyInetAddress(addr, host, "1.1.1.1");
+ }
+
+ @Test
+ public void testResolverQualifed() {
+ String host = "host.a.b.";
+ InetAddress addr = verifyResolve(host, host);
+ verifyInetAddress(addr, host, "1.1.1.1");
+ }
+
+ // localhost
+
+ @Test
+ public void testResolverLoopback() {
+ String host = "Localhost";
+ InetAddress addr = verifyResolve(host); // no lookup should occur
+ verifyInetAddress(addr, "Localhost", "127.0.0.1");
+ }
+
+ @Test
+ public void testResolverIP() {
+ String host = "1.1.1.1";
+ InetAddress addr = verifyResolve(host); // no lookup should occur for ips
+ verifyInetAddress(addr, host, host);
+ }
+
+ //
+
+ @Test
+ public void testCanonicalUriWithPort() {
+ URI uri;
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host:123"), 456);
+ assertEquals("scheme://host.a.b:123", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host:123/"), 456);
+ assertEquals("scheme://host.a.b:123/", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host:123/path"), 456);
+ assertEquals("scheme://host.a.b:123/path", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host:123/path?q#frag"), 456);
+ assertEquals("scheme://host.a.b:123/path?q#frag", uri.toString());
+ }
+
+ @Test
+ public void testCanonicalUriWithDefaultPort() {
+ URI uri;
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host"), 123);
+ assertEquals("scheme://host.a.b:123", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host/"), 123);
+ assertEquals("scheme://host.a.b:123/", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host/path"), 123);
+ assertEquals("scheme://host.a.b:123/path", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme://host/path?q#frag"), 123);
+ assertEquals("scheme://host.a.b:123/path?q#frag", uri.toString());
+ }
+
+ @Test
+ public void testCanonicalUriWithPath() {
+ URI uri;
+
+ uri = NetUtils.getCanonicalUri(URI.create("path"), 2);
+ assertEquals("path", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("/path"), 2);
+ assertEquals("/path", uri.toString());
+ }
+
+ @Test
+ public void testCanonicalUriWithNoAuthority() {
+ URI uri;
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme:/"), 2);
+ assertEquals("scheme:/", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme:/path"), 2);
+ assertEquals("scheme:/path", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme:///"), 2);
+ assertEquals("scheme:///", uri.toString());
+
+ uri = NetUtils.getCanonicalUri(URI.create("scheme:///path"), 2);
+ assertEquals("scheme:///path", uri.toString());
+ }
+
+ @Test
+ public void testCanonicalUriWithNoHost() {
+ URI uri = NetUtils.getCanonicalUri(URI.create("scheme://:123/path"), 2);
+ assertEquals("scheme://:123/path", uri.toString());
+ }
+
+ @Test
+ public void testCanonicalUriWithNoPortNoDefaultPort() {
+ URI uri = NetUtils.getCanonicalUri(URI.create("scheme://host/path"), -1);
+ assertEquals("scheme://host.a.b/path", uri.toString());
+ }
+
+ private <T> void assertBetterArrayEquals(T[] expect, T[]got) {
+ String expectStr = StringUtils.join(expect, ", ");
+ String gotStr = StringUtils.join(got, ", ");
+ assertEquals(expectStr, gotStr);
+ }
+}
\ No newline at end of file
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java Thu Jan 5 18:51:47 2012
@@ -418,9 +418,7 @@ public class TestDoAsEffectiveUser {
.getUserName()), new Text("SomeSuperUser"));
Token<TestTokenIdentifier> token = new Token<TestTokenIdentifier>(tokenId,
sm);
- Text host = new Text(addr.getAddress().getHostAddress() + ":"
- + addr.getPort());
- token.setService(host);
+ SecurityUtil.setTokenService(token, addr);
UserGroupInformation proxyUserUgi = UserGroupInformation
.createProxyUserForTesting(PROXY_USER_NAME, current, GROUP_NAMES);
proxyUserUgi.addToken(token);
@@ -476,9 +474,7 @@ public class TestDoAsEffectiveUser {
.getUserName()), new Text("SomeSuperUser"));
Token<TestTokenIdentifier> token = new Token<TestTokenIdentifier>(tokenId,
sm);
- Text host = new Text(addr.getAddress().getHostAddress() + ":"
- + addr.getPort());
- token.setService(host);
+ SecurityUtil.setTokenService(token, addr);
current.addToken(token);
String retVal = current.doAs(new PrivilegedExceptionAction<String>() {
@Override
Modified: hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java?rev=1227744&r1=1227743&r2=1227744&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java Thu Jan 5 18:51:47 2012
@@ -16,16 +16,19 @@
*/
package org.apache.hadoop.security;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import java.io.IOException;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URI;
import javax.security.auth.kerberos.KerberosPrincipal;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.security.token.Token;
import org.junit.Test;
import org.mockito.Mockito;
@@ -121,4 +124,213 @@ public class TestSecurityUtil {
assertEquals(null,
SecurityUtil.getHostFromPrincipal("service@realm"));
}
+
+ @Test
+ public void testBuildDTServiceName() {
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildDTServiceName(URI.create("test://LocalHost"), 123)
+ );
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildDTServiceName(URI.create("test://LocalHost:123"), 456)
+ );
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildDTServiceName(URI.create("test://127.0.0.1"), 123)
+ );
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildDTServiceName(URI.create("test://127.0.0.1:123"), 456)
+ );
+ }
+
+ @Test
+ public void testBuildTokenServiceSockAddr() {
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildTokenService(new InetSocketAddress("LocalHost", 123)).toString()
+ );
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildTokenService(new InetSocketAddress("127.0.0.1", 123)).toString()
+ );
+ // what goes in, comes out
+ assertEquals("127.0.0.1:123",
+ SecurityUtil.buildTokenService(NetUtils.createSocketAddr("127.0.0.1", 123)).toString()
+ );
+ }
+
+ @Test
+ public void testGoodHostsAndPorts() {
+ InetSocketAddress compare = NetUtils.createSocketAddrForHost("localhost", 123);
+ runGoodCases(compare, "localhost", 123);
+ runGoodCases(compare, "localhost:", 123);
+ runGoodCases(compare, "localhost:123", 456);
+ }
+
+ void runGoodCases(InetSocketAddress addr, String host, int port) {
+ assertEquals(addr, NetUtils.createSocketAddr(host, port));
+ assertEquals(addr, NetUtils.createSocketAddr("hdfs://"+host, port));
+ assertEquals(addr, NetUtils.createSocketAddr("hdfs://"+host+"/path", port));
+ }
+
+ @Test
+ public void testBadHostsAndPorts() {
+ runBadCases("", true);
+ runBadCases(":", false);
+ runBadCases("hdfs/", false);
+ runBadCases("hdfs:/", false);
+ runBadCases("hdfs://", true);
+ }
+
+ void runBadCases(String prefix, boolean validIfPosPort) {
+ runBadPortPermutes(prefix, false);
+ runBadPortPermutes(prefix+"*", false);
+ runBadPortPermutes(prefix+"localhost", validIfPosPort);
+ runBadPortPermutes(prefix+"localhost:-1", false);
+ runBadPortPermutes(prefix+"localhost:-123", false);
+ runBadPortPermutes(prefix+"localhost:xyz", false);
+ runBadPortPermutes(prefix+"localhost/xyz", validIfPosPort);
+ runBadPortPermutes(prefix+"localhost/:123", validIfPosPort);
+ runBadPortPermutes(prefix+":123", false);
+ runBadPortPermutes(prefix+":xyz", false);
+ }
+
+ void runBadPortPermutes(String arg, boolean validIfPosPort) {
+ int ports[] = { -123, -1, 123 };
+ boolean bad = false;
+ try {
+ NetUtils.createSocketAddr(arg);
+ } catch (IllegalArgumentException e) {
+ bad = true;
+ } finally {
+ assertTrue("should be bad: '"+arg+"'", bad);
+ }
+ for (int port : ports) {
+ if (validIfPosPort && port > 0) continue;
+
+ bad = false;
+ try {
+ NetUtils.createSocketAddr(arg, port);
+ } catch (IllegalArgumentException e) {
+ bad = true;
+ } finally {
+ assertTrue("should be bad: '"+arg+"' (default port:"+port+")", bad);
+ }
+ }
+ }
+
+ // check that the socket addr has:
+ // 1) the InetSocketAddress has the correct hostname, ie. exact host/ip given
+ // 2) the address is resolved, ie. has an ip
+ // 3,4) the socket's InetAddress has the same hostname, and the correct ip
+ // 5) the port is correct
+ private void
+ verifyValues(InetSocketAddress addr, String host, String ip, int port) {
+ assertTrue(!addr.isUnresolved());
+ // don't know what the standard resolver will return for hostname.
+ // should be host for host; host or ip for ip is ambiguous
+ if (!SecurityUtil.getTokenServiceUseIp()) {
+ assertEquals(host, addr.getHostName());
+ assertEquals(host, addr.getAddress().getHostName());
+ }
+ assertEquals(ip, addr.getAddress().getHostAddress());
+ assertEquals(port, addr.getPort());
+ }
+
+ // check:
+ // 1) buildTokenService honors use_ip setting
+ // 2) setTokenService & getService works
+ // 3) getTokenServiceAddr decodes to the identical socket addr
+ private void
+ verifyTokenService(InetSocketAddress addr, String host, String ip, int port, boolean useIp) {
+ //LOG.info("address:"+addr+" host:"+host+" ip:"+ip+" port:"+port);
+
+ SecurityUtil.setTokenServiceUseIp(useIp);
+ String serviceHost = useIp ? ip : host.toLowerCase();
+
+ Token token = new Token();
+ Text service = new Text(serviceHost+":"+port);
+
+ assertEquals(service, SecurityUtil.buildTokenService(addr));
+ SecurityUtil.setTokenService(token, addr);
+ assertEquals(service, token.getService());
+
+ InetSocketAddress serviceAddr = SecurityUtil.getTokenServiceAddr(token);
+ assertNotNull(serviceAddr);
+ verifyValues(serviceAddr, serviceHost, ip, port);
+ }
+
+ // check:
+ // 1) socket addr is created with fields set as expected
+ // 2) token service with ips
+ // 3) token service with the given host or ip
+ private void
+ verifyAddress(InetSocketAddress addr, String host, String ip, int port) {
+ verifyValues(addr, host, ip, port);
+ //LOG.info("test that token service uses ip");
+ verifyTokenService(addr, host, ip, port, true);
+ //LOG.info("test that token service uses host");
+ verifyTokenService(addr, host, ip, port, false);
+ }
+
+ // check:
+ // 1-4) combinations of host and port
+ // this will construct a socket addr, verify all the fields, build the
+ // service to verify the use_ip setting is honored, set the token service
+ // based on addr and verify the token service is set correctly, decode
+ // the token service and ensure all the fields of the decoded addr match
+ private void verifyServiceAddr(String host, String ip) {
+ InetSocketAddress addr;
+ int port = 123;
+
+ // test host, port tuple
+ //LOG.info("test tuple ("+host+","+port+")");
+ addr = NetUtils.createSocketAddrForHost(host, port);
+ verifyAddress(addr, host, ip, port);
+
+ // test authority with no default port
+ //LOG.info("test authority '"+host+":"+port+"'");
+ addr = NetUtils.createSocketAddr(host+":"+port);
+ verifyAddress(addr, host, ip, port);
+
+ // test authority with a default port, make sure default isn't used
+ //LOG.info("test authority '"+host+":"+port+"' with ignored default port");
+ addr = NetUtils.createSocketAddr(host+":"+port, port+1);
+ verifyAddress(addr, host, ip, port);
+
+ // test host-only authority, using port as default port
+ //LOG.info("test host:"+host+" port:"+port);
+ addr = NetUtils.createSocketAddr(host, port);
+ verifyAddress(addr, host, ip, port);
+ }
+
+ @Test
+ public void testSocketAddrWithName() {
+ String staticHost = "my";
+ NetUtils.addStaticResolution(staticHost, "localhost");
+ verifyServiceAddr("LocalHost", "127.0.0.1");
+ }
+
+ @Test
+ public void testSocketAddrWithIP() {
+ verifyServiceAddr("127.0.0.1", "127.0.0.1");
+ }
+
+ @Test
+ public void testSocketAddrWithNameToStaticName() {
+ String staticHost = "host1";
+ NetUtils.addStaticResolution(staticHost, "localhost");
+ verifyServiceAddr(staticHost, "127.0.0.1");
+ }
+
+ @Test
+ public void testSocketAddrWithNameToStaticIP() {
+ String staticHost = "host3";
+ NetUtils.addStaticResolution(staticHost, "255.255.255.255");
+ verifyServiceAddr(staticHost, "255.255.255.255");
+ }
+
+ // this is a bizarre case, but it's if a test tries to remap an ip address
+ @Test
+ public void testSocketAddrWithIPToStaticIP() {
+ String staticHost = "1.2.3.4";
+ NetUtils.addStaticResolution(staticHost, "255.255.255.255");
+ verifyServiceAddr(staticHost, "255.255.255.255");
+ }
}