diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java index 834bb03fac7..ec4b86bdebe 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java @@ -20,30 +20,34 @@ import java.io.File; import java.io.IOException; -import java.net.URI; +import java.net.HttpURLConnection; +import java.net.URL; import java.text.MessageFormat; import java.util.List; import java.util.Map; -import javax.ws.rs.core.HttpHeaders; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import com.google.common.base.Preconditions; +import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; +import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; import org.apache.commons.codec.binary.Base64; import com.google.common.base.Strings; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; -import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.client.AuthenticatedURL; +import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.yarn.api.ApplicationConstants; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; import org.apache.hadoop.yarn.client.api.AppAdminClient; import org.apache.hadoop.yarn.client.api.YarnClient; -import org.apache.hadoop.yarn.client.util.YarnClientUtils; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.service.api.records.Component; @@ -56,7 +60,6 @@ import org.apache.hadoop.yarn.service.conf.RestApiConstants; import org.apache.hadoop.yarn.service.utils.ServiceApiUtil; import org.apache.hadoop.yarn.util.RMHAUtils; -import org.eclipse.jetty.util.UrlEncoded; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -91,6 +94,39 @@ public ApiServiceClient(Configuration c) throws Exception { super.serviceInit(configuration); } + private Client createClient() { + return new Client( + new URLConnectionClientHandler(new HttpURLConnectionFactory() { + @Override public HttpURLConnection getHttpURLConnection(URL url) + throws IOException { + AuthenticatedURL.Token token = new AuthenticatedURL.Token(); + AuthenticatedURL aUrl; + SSLFactory clientSslFactory; + HttpURLConnection connection; + try { + if (YarnConfiguration.useHttps(getConfig())) { + clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, + getConfig()); + clientSslFactory.init(); + SSLSocketFactory sslSocketF = clientSslFactory + .createSSLSocketFactory(); + + aUrl = new AuthenticatedURL(null, clientSslFactory); + connection = aUrl.openConnection(url, token); + HttpsURLConnection httpsConn = (HttpsURLConnection) connection; + httpsConn.setSSLSocketFactory(sslSocketF); + } else { + aUrl = new AuthenticatedURL(); + connection = aUrl.openConnection(url, token); + } + } catch (Exception e) { + throw new IOException(e); + } + return connection; + } + }), getClientConfig()); + } + /** * Calculate Resource Manager address base on working REST API. */ @@ -105,34 +141,18 @@ String getRMWebAddress() { rmAddress = conf .get("yarn.resourcemanager.webapp.https.address"); } - boolean useKerberos = UserGroupInformation.isSecurityEnabled(); + List rmServers = getRMHAWebAddresses(conf); for (String host : rmServers) { try { - Client client = Client.create(); + Client client = createClient(); client.setFollowRedirects(false); StringBuilder sb = new StringBuilder(); sb.append(scheme) .append(host) .append(path); - if (!useKerberos) { - try { - String username = UserGroupInformation.getCurrentUser().getShortUserName(); - sb.append("?user.name=") - .append(username); - } catch (IOException e) { - LOG.debug("Fail to resolve username: {}", e); - } - } Builder builder = client .resource(sb.toString()).type(MediaType.APPLICATION_JSON); - if (useKerberos) { - String[] server = host.split(":"); - String challenge = YarnClientUtils.generateToken(server[0]); - builder.header(HttpHeaders.AUTHORIZATION, "Negotiate " + - challenge); - LOG.debug("Authorization: Negotiate {}", challenge); - } ClientResponse test = builder.get(ClientResponse.class); if (test.getStatus() == 200) { rmAddress = host; @@ -167,7 +187,6 @@ public String getServicePath(String appName) throws IOException { api.append("/") .append(appName); } - appendUserNameIfRequired(api); return api.toString(); } @@ -178,7 +197,6 @@ private String getInstancesPath(String appName) throws IOException { api.append(url) .append("/app/v1/services/").append(appName).append("/") .append(RestApiConstants.COMP_INSTANCES); - appendUserNameIfRequired(api); return api.toString(); } @@ -206,22 +224,9 @@ private String getComponentsPath(String appName) throws IOException { api.append(url) .append("/app/v1/services/").append(appName).append("/") .append(RestApiConstants.COMPONENTS); - appendUserNameIfRequired(api); return api.toString(); } - private void appendUserNameIfRequired(StringBuilder builder) - throws IOException { - Configuration conf = getConfig(); - if (conf.get("hadoop.http.authentication.type") - .equalsIgnoreCase("simple")) { - String username = UserGroupInformation.getCurrentUser() - .getShortUserName(); - builder.append("?user.name=").append(UrlEncoded - .encodeString(username)); - } - } - public Builder getApiClient() throws IOException { return getApiClient(getServicePath(null)); } @@ -233,23 +238,12 @@ public Builder getApiClient() throws IOException { * @return * @throws IOException */ - public Builder getApiClient(String requestPath) - throws IOException { - Client client = Client.create(getClientConfig()); + public Builder getApiClient(String requestPath) throws IOException { + Client client = createClient(); client.setChunkedEncodingSize(null); - Builder builder = client - .resource(requestPath).type(MediaType.APPLICATION_JSON); - if (UserGroupInformation.isSecurityEnabled()) { - try { - URI url = new URI(requestPath); - String challenge = YarnClientUtils.generateToken(url.getHost()); - builder.header(HttpHeaders.AUTHORIZATION, "Negotiate " + challenge); - } catch (Exception e) { - throw new IOException(e); - } - } - return builder - .accept("application/json;charset=utf-8"); + Builder builder = client.resource(requestPath) + .type(MediaType.APPLICATION_JSON); + return builder.accept("application/json;charset=utf-8"); } private ClientConfig getClientConfig() { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java index 0ffeb456c85..6292a7aba18 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java @@ -311,13 +311,4 @@ public void testComponentsUpgrade() { } } - @Test - public void testNoneSecureApiClient() throws IOException { - String url = asc.getServicePath("/foobar"); - assertTrue("User.name flag is missing in service path.", - url.contains("user.name")); - assertTrue("User.name flag is not matching JVM user.", - url.contains(System.getProperty("user.name"))); - } - } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSecureApiServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSecureApiServiceClient.java index 1ec8d41bbaf..50e4fdb9449 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSecureApiServiceClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSecureApiServiceClient.java @@ -174,15 +174,4 @@ public void testHttpSpnegoChallenge() throws Exception { assertNotNull(challenge); } - @Test - public void testAuthorizationHeader() throws Exception { - UserGroupInformation.loginUserFromKeytab(clientPrincipal, keytabFile - .getCanonicalPath()); - String rmAddress = asc.getRMWebAddress(); - if (TestServlet.isHeaderExist()) { - assertEquals(rmAddress, "http://localhost:8088"); - } else { - fail("Did not see Authorization header."); - } - } }