|
@@ -85,6 +85,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationResponse;
|
|
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationResponse;
|
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.UpdateApplicationPriorityRequest;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationAccessType;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationAccessType;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
|
import org.apache.hadoop.yarn.api.records.ApplicationReport;
|
|
@@ -122,6 +123,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoSchedule
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptsInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptsInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppPriority;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppQueue;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppQueue;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppState;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppState;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationStatisticsInfo;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationStatisticsInfo;
|
|
@@ -1047,6 +1049,120 @@ public class RMWebServices {
|
|
return Response.status(Status.OK).entity(ret).build();
|
|
return Response.status(Status.OK).entity(ret).build();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @GET
|
|
|
|
+ @Path("/apps/{appid}/priority")
|
|
|
|
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
|
|
+ public AppPriority getAppPriority(@Context HttpServletRequest hsr,
|
|
|
|
+ @PathParam("appid") String appId) throws AuthorizationException {
|
|
|
|
+ init();
|
|
|
|
+ UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true);
|
|
|
|
+ String userName = "UNKNOWN-USER";
|
|
|
|
+ if (callerUGI != null) {
|
|
|
|
+ userName = callerUGI.getUserName();
|
|
|
|
+ }
|
|
|
|
+ RMApp app = null;
|
|
|
|
+ try {
|
|
|
|
+ app = getRMAppForAppId(appId);
|
|
|
|
+ } catch (NotFoundException e) {
|
|
|
|
+ RMAuditLogger.logFailure(userName, AuditConstants.KILL_APP_REQUEST,
|
|
|
|
+ "UNKNOWN", "RMWebService",
|
|
|
|
+ "Trying to get state of an absent application " + appId);
|
|
|
|
+ throw e;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ AppPriority ret = new AppPriority();
|
|
|
|
+ ret.setPriority(
|
|
|
|
+ app.getApplicationSubmissionContext().getPriority().getPriority());
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @PUT
|
|
|
|
+ @Path("/apps/{appid}/priority")
|
|
|
|
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
|
|
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
|
|
+ public Response updateApplicationPriority(AppPriority targetPriority,
|
|
|
|
+ @Context HttpServletRequest hsr, @PathParam("appid") String appId)
|
|
|
|
+ throws AuthorizationException, YarnException, InterruptedException,
|
|
|
|
+ IOException {
|
|
|
|
+ init();
|
|
|
|
+ if (targetPriority == null) {
|
|
|
|
+ throw new YarnException("Target Priority cannot be null");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true);
|
|
|
|
+ if (callerUGI == null) {
|
|
|
|
+ throw new AuthorizationException(
|
|
|
|
+ "Unable to obtain user name, user not authenticated");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) {
|
|
|
|
+ return Response.status(Status.FORBIDDEN)
|
|
|
|
+ .entity("The default static user cannot carry out this operation.")
|
|
|
|
+ .build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String userName = callerUGI.getUserName();
|
|
|
|
+ RMApp app = null;
|
|
|
|
+ try {
|
|
|
|
+ app = getRMAppForAppId(appId);
|
|
|
|
+ } catch (NotFoundException e) {
|
|
|
|
+ RMAuditLogger.logFailure(userName, AuditConstants.KILL_APP_REQUEST,
|
|
|
|
+ "UNKNOWN", "RMWebService",
|
|
|
|
+ "Trying to move an absent application " + appId);
|
|
|
|
+ throw e;
|
|
|
|
+ }
|
|
|
|
+ Priority priority = app.getApplicationSubmissionContext().getPriority();
|
|
|
|
+ if (priority == null
|
|
|
|
+ || priority.getPriority() != targetPriority.getPriority()) {
|
|
|
|
+ return modifyApplicationPriority(app, callerUGI,
|
|
|
|
+ targetPriority.getPriority());
|
|
|
|
+ }
|
|
|
|
+ return Response.status(Status.OK).entity(targetPriority).build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Response modifyApplicationPriority(final RMApp app,
|
|
|
|
+ UserGroupInformation callerUGI, final int appPriority)
|
|
|
|
+ throws IOException, InterruptedException {
|
|
|
|
+ String userName = callerUGI.getUserName();
|
|
|
|
+ try {
|
|
|
|
+ callerUGI.doAs(new PrivilegedExceptionAction<Void>() {
|
|
|
|
+ @Override
|
|
|
|
+ public Void run() throws IOException, YarnException {
|
|
|
|
+ Priority priority = Priority.newInstance(appPriority);
|
|
|
|
+ UpdateApplicationPriorityRequest request =
|
|
|
|
+ UpdateApplicationPriorityRequest
|
|
|
|
+ .newInstance(app.getApplicationId(), priority);
|
|
|
|
+ rm.getClientRMService().updateApplicationPriority(request);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } catch (UndeclaredThrowableException ue) {
|
|
|
|
+ // if the root cause is a permissions issue
|
|
|
|
+ // bubble that up to the user
|
|
|
|
+ if (ue.getCause() instanceof YarnException) {
|
|
|
|
+ YarnException ye = (YarnException) ue.getCause();
|
|
|
|
+ if (ye.getCause() instanceof AccessControlException) {
|
|
|
|
+ String appId = app.getApplicationId().toString();
|
|
|
|
+ String msg = "Unauthorized attempt to change priority of appid "
|
|
|
|
+ + appId + " by remote user " + userName;
|
|
|
|
+ return Response.status(Status.FORBIDDEN).entity(msg).build();
|
|
|
|
+ } else if (ye.getMessage().startsWith("Application in")
|
|
|
|
+ && ye.getMessage().endsWith("state cannot be update priority.")) {
|
|
|
|
+ return Response.status(Status.BAD_REQUEST).entity(ye.getMessage())
|
|
|
|
+ .build();
|
|
|
|
+ } else {
|
|
|
|
+ throw ue;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ throw ue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ AppPriority ret = new AppPriority(
|
|
|
|
+ app.getApplicationSubmissionContext().getPriority().getPriority());
|
|
|
|
+ return Response.status(Status.OK).entity(ret).build();
|
|
|
|
+ }
|
|
|
|
+
|
|
@GET
|
|
@GET
|
|
@Path("/apps/{appid}/queue")
|
|
@Path("/apps/{appid}/queue")
|
|
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|