YARN-9956. Improved connection error message for YARN ApiServerClient.
Contributed by Prabhu Joseph
This commit is contained in:
parent
dd2607e3ec
commit
d81d45ff2f
|
@ -44,6 +44,7 @@ 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.HAUtil;
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||
import org.apache.hadoop.yarn.service.api.records.Component;
|
||||
|
@ -94,7 +95,7 @@ public class ApiServiceClient extends AppAdminClient {
|
|||
/**
|
||||
* Calculate Resource Manager address base on working REST API.
|
||||
*/
|
||||
String getRMWebAddress() {
|
||||
String getRMWebAddress() throws IOException {
|
||||
Configuration conf = getConfig();
|
||||
String scheme = "http://";
|
||||
String path = "/app/v1/services/version";
|
||||
|
@ -105,43 +106,50 @@ public class ApiServiceClient extends AppAdminClient {
|
|||
rmAddress = conf
|
||||
.get("yarn.resourcemanager.webapp.https.address");
|
||||
}
|
||||
boolean useKerberos = UserGroupInformation.isSecurityEnabled();
|
||||
List<String> rmServers = getRMHAWebAddresses(conf);
|
||||
for (String host : rmServers) {
|
||||
try {
|
||||
Client client = Client.create();
|
||||
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);
|
||||
|
||||
if (HAUtil.isHAEnabled(conf)) {
|
||||
boolean useKerberos = UserGroupInformation.isSecurityEnabled();
|
||||
List<String> rmServers = getRMHAWebAddresses(conf);
|
||||
StringBuilder diagnosticsMsg = new StringBuilder();
|
||||
for (String host : rmServers) {
|
||||
try {
|
||||
Client client = Client.create();
|
||||
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) {
|
||||
return scheme + host;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.info("Fail to connect to: " + host);
|
||||
LOG.debug("Root cause: ", e);
|
||||
diagnosticsMsg.append("Error connecting to " + host
|
||||
+ " due to " + e.getMessage() + "\n");
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.info("Fail to connect to: "+host);
|
||||
LOG.debug("Root cause: {}", e);
|
||||
}
|
||||
throw new IOException(diagnosticsMsg.toString());
|
||||
}
|
||||
return scheme+rmAddress;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
|
@ -117,6 +118,27 @@ public class TestApiServiceClient {
|
|||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRMWebAddress() throws Exception {
|
||||
Configuration conf = new Configuration();
|
||||
conf.setBoolean(YarnConfiguration.RM_HA_ENABLED, true);
|
||||
conf.set(YarnConfiguration.RM_HA_IDS, "rm1");
|
||||
conf.set(YarnConfiguration.RM_HA_ID, "rm1");
|
||||
conf.set("yarn.resourcemanager.webapp.address.rm1", "localhost:0");
|
||||
ApiServiceClient asc1 = new ApiServiceClient(conf);
|
||||
boolean exceptionCaught = false;
|
||||
String diagnosticsMsg = null;
|
||||
try {
|
||||
String rmWebAddress = asc1.getRMWebAddress();
|
||||
} catch (IOException e){
|
||||
exceptionCaught = true;
|
||||
diagnosticsMsg = e.getMessage();
|
||||
}
|
||||
assertTrue("ApiServiceClient failed to throw exception", exceptionCaught);
|
||||
assertTrue("Exception Message does not match",
|
||||
diagnosticsMsg.contains("Error connecting to localhost:0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunch() {
|
||||
String fileName = "target/test-classes/example-app.json";
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.apache.hadoop.security.SecurityUtil;
|
|||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.apache.hadoop.security.SaslRpcServer.QualityOfProtection;
|
||||
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
|
||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||
import org.apache.hadoop.yarn.client.util.YarnClientUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -152,6 +153,7 @@ public class TestSecureApiServiceClient extends KerberosSecurityTestcase {
|
|||
rmServers.add("localhost:8088");
|
||||
testConf.set("yarn.resourcemanager.webapp.address",
|
||||
"localhost:8088");
|
||||
testConf.setBoolean(YarnConfiguration.RM_HA_ENABLED, true);
|
||||
asc = new ApiServiceClient() {
|
||||
@Override
|
||||
List<String> getRMHAWebAddresses(Configuration conf) {
|
||||
|
|
|
@ -247,7 +247,7 @@ public abstract class YarnClientUtils {
|
|||
StandardCharsets.US_ASCII);
|
||||
} catch (GSSException | IllegalAccessException
|
||||
| NoSuchFieldException | ClassNotFoundException e) {
|
||||
LOG.error("Error: {}", e);
|
||||
LOG.error("Error: ", e);
|
||||
throw new AuthenticationException(e);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue