YARN-4746. yarn web services should convert parse failures of appId, appAttemptId and containerId to 400. Contributed by Bibin A Chundatt
This commit is contained in:
parent
da614ca5dc
commit
5092c94195
|
@ -122,8 +122,20 @@ public class ConverterUtils {
|
||||||
public static ApplicationId toApplicationId(RecordFactory recordFactory,
|
public static ApplicationId toApplicationId(RecordFactory recordFactory,
|
||||||
String appIdStr) {
|
String appIdStr) {
|
||||||
Iterator<String> it = _split(appIdStr).iterator();
|
Iterator<String> it = _split(appIdStr).iterator();
|
||||||
it.next(); // prefix. TODO: Validate application prefix
|
if (!it.next().equals(APPLICATION_PREFIX)) {
|
||||||
return toApplicationId(recordFactory, it);
|
throw new IllegalArgumentException("Invalid ApplicationId prefix: "
|
||||||
|
+ appIdStr + ". The valid ApplicationId should start with prefix "
|
||||||
|
+ APPLICATION_PREFIX);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return toApplicationId(recordFactory, it);
|
||||||
|
} catch (NumberFormatException n) {
|
||||||
|
throw new IllegalArgumentException("Invalid ApplicationId: " + appIdStr,
|
||||||
|
n);
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
throw new IllegalArgumentException("Invalid ApplicationId: " + appIdStr,
|
||||||
|
e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ApplicationId toApplicationId(RecordFactory recordFactory,
|
private static ApplicationId toApplicationId(RecordFactory recordFactory,
|
||||||
|
|
|
@ -33,9 +33,14 @@ import org.apache.hadoop.http.HttpConfig.Policy;
|
||||||
import org.apache.hadoop.http.HttpServer2;
|
import org.apache.hadoop.http.HttpServer2;
|
||||||
import org.apache.hadoop.net.NetUtils;
|
import org.apache.hadoop.net.NetUtils;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.conf.HAUtil;
|
import org.apache.hadoop.yarn.conf.HAUtil;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
||||||
|
import org.apache.hadoop.yarn.factories.RecordFactory;
|
||||||
|
import org.apache.hadoop.yarn.util.ConverterUtils;
|
||||||
import org.apache.hadoop.yarn.util.RMHAUtils;
|
import org.apache.hadoop.yarn.util.RMHAUtils;
|
||||||
|
import org.apache.hadoop.yarn.webapp.BadRequestException;
|
||||||
|
import org.apache.hadoop.yarn.webapp.NotFoundException;
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
@Evolving
|
@Evolving
|
||||||
|
@ -378,4 +383,21 @@ public class WebAppUtils {
|
||||||
}
|
}
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ApplicationId parseApplicationId(RecordFactory recordFactory,
|
||||||
|
String appId) {
|
||||||
|
if (appId == null || appId.isEmpty()) {
|
||||||
|
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
||||||
|
}
|
||||||
|
ApplicationId aid = null;
|
||||||
|
try {
|
||||||
|
aid = ConverterUtils.toApplicationId(recordFactory, appId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BadRequestException(e);
|
||||||
|
}
|
||||||
|
if (aid == null) {
|
||||||
|
throw new NotFoundException("app with id " + appId + " not found");
|
||||||
|
}
|
||||||
|
return aid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,7 +429,12 @@ public class WebServices {
|
||||||
if (appId == null || appId.isEmpty()) {
|
if (appId == null || appId.isEmpty()) {
|
||||||
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
||||||
}
|
}
|
||||||
ApplicationId aid = ConverterUtils.toApplicationId(appId);
|
ApplicationId aid = null;
|
||||||
|
try {
|
||||||
|
aid = ConverterUtils.toApplicationId(appId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BadRequestException(e);
|
||||||
|
}
|
||||||
if (aid == null) {
|
if (aid == null) {
|
||||||
throw new NotFoundException("appId is null");
|
throw new NotFoundException("appId is null");
|
||||||
}
|
}
|
||||||
|
@ -442,8 +447,12 @@ public class WebServices {
|
||||||
throw new NotFoundException("appAttemptId, " + appAttemptId
|
throw new NotFoundException("appAttemptId, " + appAttemptId
|
||||||
+ ", is empty or null");
|
+ ", is empty or null");
|
||||||
}
|
}
|
||||||
ApplicationAttemptId aaid =
|
ApplicationAttemptId aaid = null;
|
||||||
ConverterUtils.toApplicationAttemptId(appAttemptId);
|
try {
|
||||||
|
aaid = ConverterUtils.toApplicationAttemptId(appAttemptId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BadRequestException(e);
|
||||||
|
}
|
||||||
if (aaid == null) {
|
if (aaid == null) {
|
||||||
throw new NotFoundException("appAttemptId is null");
|
throw new NotFoundException("appAttemptId is null");
|
||||||
}
|
}
|
||||||
|
@ -455,7 +464,12 @@ public class WebServices {
|
||||||
throw new NotFoundException("containerId, " + containerId
|
throw new NotFoundException("containerId, " + containerId
|
||||||
+ ", is empty or null");
|
+ ", is empty or null");
|
||||||
}
|
}
|
||||||
ContainerId cid = ConverterUtils.toContainerId(containerId);
|
ContainerId cid = null;
|
||||||
|
try {
|
||||||
|
cid = ConverterUtils.toContainerId(containerId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BadRequestException(e);
|
||||||
|
}
|
||||||
if (cid == null) {
|
if (cid == null) {
|
||||||
throw new NotFoundException("containerId is null");
|
throw new NotFoundException("containerId is null");
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ import org.apache.hadoop.yarn.util.ConverterUtils;
|
||||||
import org.apache.hadoop.yarn.webapp.BadRequestException;
|
import org.apache.hadoop.yarn.webapp.BadRequestException;
|
||||||
import org.apache.hadoop.yarn.webapp.NotFoundException;
|
import org.apache.hadoop.yarn.webapp.NotFoundException;
|
||||||
import org.apache.hadoop.yarn.webapp.WebApp;
|
import org.apache.hadoop.yarn.webapp.WebApp;
|
||||||
|
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
@ -143,10 +144,7 @@ public class NMWebServices {
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||||
public AppInfo getNodeApp(@PathParam("appid") String appId) {
|
public AppInfo getNodeApp(@PathParam("appid") String appId) {
|
||||||
init();
|
init();
|
||||||
ApplicationId id = ConverterUtils.toApplicationId(recordFactory, appId);
|
ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId);
|
||||||
if (id == null) {
|
|
||||||
throw new NotFoundException("app with id " + appId + " not found");
|
|
||||||
}
|
|
||||||
Application app = this.nmContext.getApplications().get(id);
|
Application app = this.nmContext.getApplications().get(id);
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new NotFoundException("app with id " + appId + " not found");
|
throw new NotFoundException("app with id " + appId + " not found");
|
||||||
|
|
|
@ -565,11 +565,14 @@ public class TestNMWebServicesApps extends JerseyTestBase {
|
||||||
String type = exception.getString("exception");
|
String type = exception.getString("exception");
|
||||||
String classname = exception.getString("javaClassName");
|
String classname = exception.getString("javaClassName");
|
||||||
WebServicesTestUtils.checkStringMatch("exception message",
|
WebServicesTestUtils.checkStringMatch("exception message",
|
||||||
"For input string: \"foo\"", message);
|
"java.lang.IllegalArgumentException: Invalid ApplicationId prefix: "
|
||||||
|
+ "app_foo_0000. The valid ApplicationId should start with prefix"
|
||||||
|
+ " application",
|
||||||
|
message);
|
||||||
WebServicesTestUtils.checkStringMatch("exception type",
|
WebServicesTestUtils.checkStringMatch("exception type",
|
||||||
"NumberFormatException", type);
|
"BadRequestException", type);
|
||||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||||
"java.lang.NumberFormatException", classname);
|
"org.apache.hadoop.yarn.webapp.BadRequestException", classname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -662,14 +662,7 @@ public class RMWebServices extends WebServices {
|
||||||
public AppInfo getApp(@Context HttpServletRequest hsr,
|
public AppInfo getApp(@Context HttpServletRequest hsr,
|
||||||
@PathParam("appid") String appId) {
|
@PathParam("appid") String appId) {
|
||||||
init();
|
init();
|
||||||
if (appId == null || appId.isEmpty()) {
|
ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId);
|
||||||
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
|
||||||
}
|
|
||||||
ApplicationId id;
|
|
||||||
id = ConverterUtils.toApplicationId(recordFactory, appId);
|
|
||||||
if (id == null) {
|
|
||||||
throw new NotFoundException("appId is null");
|
|
||||||
}
|
|
||||||
RMApp app = rm.getRMContext().getRMApps().get(id);
|
RMApp app = rm.getRMContext().getRMApps().get(id);
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new NotFoundException("app with id: " + appId + " not found");
|
throw new NotFoundException("app with id: " + appId + " not found");
|
||||||
|
@ -684,14 +677,7 @@ public class RMWebServices extends WebServices {
|
||||||
@PathParam("appid") String appId) {
|
@PathParam("appid") String appId) {
|
||||||
|
|
||||||
init();
|
init();
|
||||||
if (appId == null || appId.isEmpty()) {
|
ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId);
|
||||||
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
|
||||||
}
|
|
||||||
ApplicationId id;
|
|
||||||
id = ConverterUtils.toApplicationId(recordFactory, appId);
|
|
||||||
if (id == null) {
|
|
||||||
throw new NotFoundException("appId is null");
|
|
||||||
}
|
|
||||||
RMApp app = rm.getRMContext().getRMApps().get(id);
|
RMApp app = rm.getRMContext().getRMApps().get(id);
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new NotFoundException("app with id: " + appId + " not found");
|
throw new NotFoundException("app with id: " + appId + " not found");
|
||||||
|
@ -1303,19 +1289,7 @@ public class RMWebServices extends WebServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RMApp getRMAppForAppId(String appId) {
|
private RMApp getRMAppForAppId(String appId) {
|
||||||
|
ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId);
|
||||||
if (appId == null || appId.isEmpty()) {
|
|
||||||
throw new NotFoundException("appId, " + appId + ", is empty or null");
|
|
||||||
}
|
|
||||||
ApplicationId id;
|
|
||||||
try {
|
|
||||||
id = ConverterUtils.toApplicationId(recordFactory, appId);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new NotFoundException("appId is invalid");
|
|
||||||
}
|
|
||||||
if (id == null) {
|
|
||||||
throw new NotFoundException("appId is invalid");
|
|
||||||
}
|
|
||||||
RMApp app = rm.getRMContext().getRMApps().get(id);
|
RMApp app = rm.getRMContext().getRMApps().get(id);
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new NotFoundException("app with id: " + appId + " not found");
|
throw new NotFoundException("app with id: " + appId + " not found");
|
||||||
|
|
|
@ -1194,11 +1194,13 @@ public class TestRMWebServicesApps extends JerseyTestBase {
|
||||||
String type = exception.getString("exception");
|
String type = exception.getString("exception");
|
||||||
String classname = exception.getString("javaClassName");
|
String classname = exception.getString("javaClassName");
|
||||||
WebServicesTestUtils.checkStringMatch("exception message",
|
WebServicesTestUtils.checkStringMatch("exception message",
|
||||||
"For input string: \"invalid\"", message);
|
"java.lang.IllegalArgumentException: Invalid ApplicationId:"
|
||||||
|
+ " application_invalid_12",
|
||||||
|
message);
|
||||||
WebServicesTestUtils.checkStringMatch("exception type",
|
WebServicesTestUtils.checkStringMatch("exception type",
|
||||||
"NumberFormatException", type);
|
"BadRequestException", type);
|
||||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||||
"java.lang.NumberFormatException", classname);
|
"org.apache.hadoop.yarn.webapp.BadRequestException", classname);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
rm.stop();
|
rm.stop();
|
||||||
|
@ -1500,15 +1502,17 @@ public class TestRMWebServicesApps extends JerseyTestBase {
|
||||||
public void testInvalidAppAttempts() throws JSONException, Exception {
|
public void testInvalidAppAttempts() throws JSONException, Exception {
|
||||||
rm.start();
|
rm.start();
|
||||||
MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048);
|
MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048);
|
||||||
rm.submitApp(CONTAINER_MB);
|
RMApp app = rm.submitApp(CONTAINER_MB);
|
||||||
amNodeManager.nodeHeartbeat(true);
|
amNodeManager.nodeHeartbeat(true);
|
||||||
WebResource r = resource();
|
WebResource r = resource();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
r.path("ws").path("v1").path("cluster").path("apps")
|
r.path("ws").path("v1").path("cluster").path("apps")
|
||||||
.path("application_invalid_12").accept(MediaType.APPLICATION_JSON)
|
.path(app.getApplicationId().toString()).path("appattempts")
|
||||||
|
.path("appattempt_invalid_12_000001")
|
||||||
|
.accept(MediaType.APPLICATION_JSON)
|
||||||
.get(JSONObject.class);
|
.get(JSONObject.class);
|
||||||
fail("should have thrown exception on invalid appid");
|
fail("should have thrown exception on invalid appAttempt");
|
||||||
} catch (UniformInterfaceException ue) {
|
} catch (UniformInterfaceException ue) {
|
||||||
ClientResponse response = ue.getResponse();
|
ClientResponse response = ue.getResponse();
|
||||||
|
|
||||||
|
@ -1521,11 +1525,13 @@ public class TestRMWebServicesApps extends JerseyTestBase {
|
||||||
String type = exception.getString("exception");
|
String type = exception.getString("exception");
|
||||||
String classname = exception.getString("javaClassName");
|
String classname = exception.getString("javaClassName");
|
||||||
WebServicesTestUtils.checkStringMatch("exception message",
|
WebServicesTestUtils.checkStringMatch("exception message",
|
||||||
"For input string: \"invalid\"", message);
|
"java.lang.IllegalArgumentException: Invalid AppAttemptId:"
|
||||||
|
+ " appattempt_invalid_12_000001",
|
||||||
|
message);
|
||||||
WebServicesTestUtils.checkStringMatch("exception type",
|
WebServicesTestUtils.checkStringMatch("exception type",
|
||||||
"NumberFormatException", type);
|
"BadRequestException", type);
|
||||||
WebServicesTestUtils.checkStringMatch("exception classname",
|
WebServicesTestUtils.checkStringMatch("exception classname",
|
||||||
"java.lang.NumberFormatException", classname);
|
"org.apache.hadoop.yarn.webapp.BadRequestException", classname);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
rm.stop();
|
rm.stop();
|
||||||
|
|
|
@ -568,17 +568,21 @@ public class TestRMWebServicesAppsModification extends JerseyTestBase {
|
||||||
MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048);
|
MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048);
|
||||||
amNodeManager.nodeHeartbeat(true);
|
amNodeManager.nodeHeartbeat(true);
|
||||||
String[] testAppIds = { "application_1391705042196_0001", "random_string" };
|
String[] testAppIds = { "application_1391705042196_0001", "random_string" };
|
||||||
for (String testAppId : testAppIds) {
|
for (int i = 0; i < testAppIds.length; i++) {
|
||||||
AppState info = new AppState("KILLED");
|
AppState info = new AppState("KILLED");
|
||||||
ClientResponse response =
|
ClientResponse response =
|
||||||
this.constructWebResource("apps", testAppId, "state")
|
this.constructWebResource("apps", testAppIds[i], "state")
|
||||||
.accept(MediaType.APPLICATION_XML)
|
.accept(MediaType.APPLICATION_XML)
|
||||||
.entity(info, MediaType.APPLICATION_XML).put(ClientResponse.class);
|
.entity(info, MediaType.APPLICATION_XML).put(ClientResponse.class);
|
||||||
if (!isAuthenticationEnabled()) {
|
if (!isAuthenticationEnabled()) {
|
||||||
assertEquals(Status.UNAUTHORIZED, response.getClientResponseStatus());
|
assertEquals(Status.UNAUTHORIZED, response.getClientResponseStatus());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
|
if (i == 0) {
|
||||||
|
assertEquals(Status.NOT_FOUND, response.getClientResponseStatus());
|
||||||
|
} else {
|
||||||
|
assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rm.stop();
|
rm.stop();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue