From 547cb53e8ae2f19b55f9de7670b91b009d8f3bdd Mon Sep 17 00:00:00 2001 From: Carlo Curino Date: Wed, 7 Jun 2017 13:41:06 -0700 Subject: [PATCH] YARN-6634. [API] Refactor ResourceManager WebServices to make API explicit. (Giovanni Matteo Fumarola via curino) --- .../resourcemanager/webapp/RMWSConsts.java | 202 ++++ .../webapp/RMWebServiceProtocol.java | 635 ++++++++++++ .../resourcemanager/webapp/RMWebServices.java | 937 +++++++++--------- 3 files changed, 1279 insertions(+), 495 deletions(-) create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWSConsts.java create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServiceProtocol.java diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWSConsts.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWSConsts.java new file mode 100644 index 00000000000..23d4bb1f9ce --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWSConsts.java @@ -0,0 +1,202 @@ +/** + * 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.yarn.server.resourcemanager.webapp; + +/** + * Constants for {@code RMWebServiceProtocol}. + */ +public final class RMWSConsts { + + public static final String EMPTY = ""; + public static final String ANY = "*"; + + public static final String FORWARDED_FOR = "X-Forwarded-For"; + + // ----------------Paths for RMWebServiceProtocol---------------- + + /** Path for {@code RMWebServiceProtocol}. */ + public static final String RM_WEB_SERVICE_PATH = "/ws/v1/cluster"; + + /** Path for {@code RMWebServiceProtocol#getClusterInfo}. */ + public static final String INFO = "/info"; + + /** Path for {@code RMWebServiceProtocol#getClusterMetricsInfo}. */ + public static final String METRICS = "/metrics"; + + /** Path for {@code RMWebServiceProtocol#getSchedulerInfo}. */ + public static final String SCHEDULER = "/scheduler"; + + /** Path for {@code RMWebServiceProtocol#dumpSchedulerLogs}. */ + public static final String SCHEDULER_LOGS = "/scheduler/logs"; + + /** Path for {@code RMWebServiceProtocol#getNodes}. */ + public static final String NODES = "/nodes"; + + /** Path for {@code RMWebServiceProtocol#getNode}. */ + public static final String NODES_NODEID = "/nodes/{nodeId}"; + + /** + * Path for {@code RMWebServiceProtocol#getApps} and + * {@code RMWebServiceProtocol#getApp}. + */ + public static final String APPS = "/apps"; + + /** Path for {@code RMWebServiceProtocol#getActivities}. */ + public static final String SCHEDULER_ACTIVITIES = "/scheduler/activities"; + + /** Path for {@code RMWebServiceProtocol#getAppActivities}. */ + public static final String SCHEDULER_APP_ACTIVITIES = + "/scheduler/app-activities"; + + /** Path for {@code RMWebServiceProtocol#getAppStatistics}. */ + public static final String APP_STATISTICS = "/appstatistics"; + + /** Path for {@code RMWebServiceProtocol#getApp}. */ + public static final String APPS_APPID = "/apps/{appid}"; + + /** Path for {@code RMWebServiceProtocol#getAppAttempts}. */ + public static final String APPS_APPID_APPATTEMPTS = + "/apps/{appid}/appattempts"; + + /** Path for {@code WebServices#getAppAttempt}. */ + public static final String APPS_APPID_APPATTEMPTS_APPATTEMPTID = + "/apps/{appid}/appattempts/{appattemptid}"; + + /** Path for {@code WebServices#getContainers}. */ + public static final String APPS_APPID_APPATTEMPTS_APPATTEMPTID_CONTAINERS = + "/apps/{appid}/appattempts/{appattemptid}/containers"; + + /** Path for {@code RMWebServiceProtocol#getNodeToLabels}. */ + public static final String GET_NODE_TO_LABELS = "/get-node-to-labels"; + + /** Path for {@code RMWebServiceProtocol#getLabelsToNodes}. */ + public static final String LABEL_MAPPINGS = "/label-mappings"; + + /** Path for {@code RMWebServiceProtocol#replaceLabelsOnNodes}. */ + public static final String REPLACE_NODE_TO_LABELS = "/replace-node-to-labels"; + + /** Path for {@code RMWebServiceProtocol#replaceLabelsOnNode}. */ + public static final String NODES_NODEID_REPLACE_LABELS = + "/nodes/{nodeId}/replace-labels"; + + /** Path for {@code RMWebServiceProtocol#getClusterNodeLabels}. */ + public static final String GET_NODE_LABELS = "/get-node-labels"; + + /** Path for {@code RMWebServiceProtocol#addToClusterNodeLabels}. */ + public static final String ADD_NODE_LABELS = "/add-node-labels"; + + /** Path for {@code RMWebServiceProtocol#removeFromCluserNodeLabels}. */ + public static final String REMOVE_NODE_LABELS = "/remove-node-labels"; + + /** Path for {@code RMWebServiceProtocol#getLabelsOnNode}. */ + public static final String NODES_NODEID_GETLABELS = + "/nodes/{nodeId}/get-labels"; + + /** + * Path for {@code RMWebServiceProtocol#getAppPriority} and + * {@code RMWebServiceProtocol#updateApplicationPriority}. + */ + public static final String APPS_APPID_PRIORITY = "/apps/{appid}/priority"; + + /** + * Path for {@code RMWebServiceProtocol#getAppQueue} and + * {@code RMWebServiceProtocol#updateAppQueue}. + */ + public static final String APPS_APPID_QUEUE = "/apps/{appid}/queue"; + + /** Path for {@code RMWebServiceProtocol#createNewApplication}. */ + public static final String APPS_NEW_APPLICATION = "/apps/new-application"; + + /** + * Path for {@code RMWebServiceProtocol#getAppState} and + * {@code RMWebServiceProtocol#updateAppState}. + */ + public static final String APPS_APPID_STATE = "/apps/{appid}/state"; + + /** + * Path for {@code RMWebServiceProtocol#postDelegationToken} and + * {@code RMWebServiceProtocol#cancelDelegationToken}. + */ + public static final String DELEGATION_TOKEN = "/delegation-token"; + + /** Path for {@code RMWebServiceProtocol#postDelegationTokenExpiration}. */ + public static final String DELEGATION_TOKEN_EXPIRATION = + "/delegation-token/expiration"; + + /** Path for {@code RMWebServiceProtocol#createNewReservation}. */ + public static final String RESERVATION_NEW = "/reservation/new-reservation"; + + /** Path for {@code RMWebServiceProtocol#submitReservation}. */ + public static final String RESERVATION_SUBMIT = "/reservation/submit"; + + /** Path for {@code RMWebServiceProtocol#updateReservation}. */ + public static final String RESERVATION_UPDATE = "/reservation/update"; + + /** Path for {@code RMWebServiceProtocol#deleteReservation}. */ + public static final String RESERVATION_DELETE = "/reservation/delete"; + + /** Path for {@code RMWebServiceProtocol#listReservation}. */ + public static final String RESERVATION_LIST = "/reservation/list"; + + /** Path for {@code RMWebServiceProtocol#getAppTimeout}. */ + public static final String APPS_TIMEOUTS_TYPE = + "/apps/{appid}/timeouts/{type}"; + + /** + * Path for {@code RMWebServiceProtocol#getAppTimeouts}. + */ + public static final String APPS_TIMEOUTS = "/apps/{appid}/timeouts"; + + /** + * Path for {@code RMWebServiceProtocol#updateApplicationTimeout}. + */ + public static final String APPS_TIMEOUT = "/apps/{appid}/timeout"; + + // ----------------QueryParams for RMWebServiceProtocol---------------- + + public static final String TIME = "time"; + public static final String STATES = "states"; + public static final String NODEID = "nodeId"; + public static final String STATE = "state"; + public static final String FINAL_STATUS = "finalStatus"; + public static final String USER = "user"; + public static final String QUEUE = "queue"; + public static final String LIMIT = "limit"; + public static final String STARTED_TIME_BEGIN = "startedTimeBegin"; + public static final String STARTED_TIME_END = "startedTimeEnd"; + public static final String FINISHED_TIME_BEGIN = "finishedTimeBegin"; + public static final String FINISHED_TIME_END = "finishedTimeEnd"; + public static final String APPLICATION_TYPES = "applicationTypes"; + public static final String APPLICATION_TAGS = "applicationTags"; + public static final String APP_ID = "appId"; + public static final String MAX_TIME = "maxTime"; + public static final String APPATTEMPTID = "appattemptid"; + public static final String APPID = "appid"; + public static final String LABELS = "labels"; + public static final String RESERVATION_ID = "reservation-id"; + public static final String START_TIME = "start-time"; + public static final String END_TIME = "end-time"; + public static final String INCLUDE_RESOURCE = "include-resource-allocations"; + public static final String TYPE = "type"; + + private RMWSConsts() { + // not called + } + +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServiceProtocol.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServiceProtocol.java new file mode 100644 index 00000000000..6dd9c418c8c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServiceProtocol.java @@ -0,0 +1,635 @@ +/** + * 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.yarn.server.resourcemanager.webapp; + +import java.io.IOException; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Response; + +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceStability.Evolving; +import org.apache.hadoop.security.authorize.AuthorizationException; +import org.apache.hadoop.yarn.api.ApplicationBaseProtocol; +import org.apache.hadoop.yarn.api.ApplicationClientProtocol; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.server.api.ResourceManagerAdministrationProtocol; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ActivitiesInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppActivitiesInfo; +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.AppPriority; +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.AppTimeoutInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppTimeoutsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationStatisticsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationSubmissionContextInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.DelegationToken; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.LabelsToNodesInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeLabelsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsEntryList; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodesInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ReservationDeleteRequestInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ReservationSubmissionRequestInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ReservationUpdateRequestInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerTypeInfo; + +/** + *

+ * The protocol between clients and the ResourceManager to + * submit/abort jobs and to get information on applications, cluster metrics, + * nodes, queues, ACLs and reservations via REST calls. + *

+ * + * The WebService is reachable by using {@link RMWSConsts#RM_WEB_SERVICE_PATH} + */ +@Private +@Evolving +public interface RMWebServiceProtocol { + + /** + * This method retrieves the cluster information, and it is reachable by using + * {@link RMWSConsts#INFO}. + * + * @return the cluster information + */ + ClusterInfo get(); + + /** + * This method retrieves the cluster information, and it is reachable by using + * {@link RMWSConsts#INFO}. + * + * @return the cluster information + */ + ClusterInfo getClusterInfo(); + + /** + * This method retrieves the cluster metrics information, and it is reachable + * by using {@link RMWSConsts#METRICS}. + * + * @see ApplicationClientProtocol#getClusterMetrics + * @return the cluster metrics information + */ + ClusterMetricsInfo getClusterMetricsInfo(); + + /** + * This method retrieves the current scheduler status, and it is reachable by + * using {@link RMWSConsts#SCHEDULER}. + * + * @return the current scheduler status + */ + SchedulerTypeInfo getSchedulerInfo(); + + /** + * This method dumps the scheduler logs for the time got in input, and it is + * reachable by using {@link RMWSConsts#SCHEDULER_LOGS}. + * + * @param time the period of time + * @param hsr the servlet request + * @return the result of the operation + * @throws IOException when it cannot create dump log file + */ + String dumpSchedulerLogs(String time, HttpServletRequest hsr) + throws IOException; + + /** + * This method retrieves all the nodes information in the cluster, and it is + * reachable by using {@link RMWSConsts#NODES}. + * + * @see ApplicationClientProtocol#getClusterNodes + * @param states the states we want to filter + * @return all nodes in the cluster. If the states param is given, returns all + * nodes that are in the comma-separated list of states + */ + NodesInfo getNodes(String states); + + /** + * This method retrieves a specific node information, and it is reachable by + * using {@link RMWSConsts#NODES_NODEID}. + * + * @param nodeId the node we want to retrieve the information + * @return the information about the node in input + */ + NodeInfo getNode(String nodeId); + + /** + * This method retrieves all the app reports in the cluster, and it is + * reachable by using {@link RMWSConsts#APPS}. + * + * @see ApplicationClientProtocol#getApplications + * @param hsr the servlet request + * @param stateQuery right now the stateQuery is deprecated + * @param statesQuery filter the result by states + * @param finalStatusQuery filter the result by final states + * @param userQuery filter the result by user + * @param queueQuery filter the result by queue + * @param count set a limit of the result + * @param startedBegin filter the result by started begin time + * @param startedEnd filter the result by started end time + * @param finishBegin filter the result by finish begin time + * @param finishEnd filter the result by finish end time + * @param applicationTypes filter the result by types + * @param applicationTags filter the result by tags + * @return all apps in the cluster + */ + @SuppressWarnings("checkstyle:parameternumber") + AppsInfo getApps(HttpServletRequest hsr, String stateQuery, + Set statesQuery, String finalStatusQuery, String userQuery, + String queueQuery, String count, String startedBegin, String startedEnd, + String finishBegin, String finishEnd, Set applicationTypes, + Set applicationTags); + + /** + * This method retrieve all the activities in a specific node, and it is + * reachable by using {@link RMWSConsts#SCHEDULER_ACTIVITIES}. + * + * @param hsr the servlet request + * @param nodeId the node we want to retrieve the activities + * @return all the activities in the specific node + */ + ActivitiesInfo getActivities(HttpServletRequest hsr, String nodeId); + + /** + * This method retrieves all the activities for a specific app for a specific + * period of time, and it is reachable by using + * {@link RMWSConsts#SCHEDULER_APP_ACTIVITIES}. + * + * @param hsr the servlet request + * @param appId the applicationId we want to retrieve the activities + * @param time for how long we want to retrieve the activities + * @return all the activities about a specific app for a specific time + */ + AppActivitiesInfo getAppActivities(HttpServletRequest hsr, String appId, + String time); + + /** + * This method retrieves all the statistics for a specific app, and it is + * reachable by using {@link RMWSConsts#APP_STATISTICS}. + * + * @param hsr the servlet request + * @param stateQueries filter the result by states + * @param typeQueries filter the result by type names + * @return the application's statistics for specific states and types + */ + ApplicationStatisticsInfo getAppStatistics(HttpServletRequest hsr, + Set stateQueries, Set typeQueries); + + /** + * This method retrieves the report for a specific app, and it is reachable by + * using {@link RMWSConsts#APPS_APPID}. + * + * @see ApplicationClientProtocol#getApplicationReport + * @param hsr the servlet request + * @param appId the Id of the application we want the report + * @return the app report for a specific application + */ + AppInfo getApp(HttpServletRequest hsr, String appId); + + /** + * This method retrieves the state for a specific app, and it is reachable by + * using {@link RMWSConsts#APPS_APPID_STATE}. + * + * @param hsr the servlet request + * @param appId the Id of the application we want the state + * @return the state for a specific application + * @throws AuthorizationException if the user is not authorized + */ + AppState getAppState(HttpServletRequest hsr, String appId) + throws AuthorizationException; + + /** + * This method updates the state of the app in input, and it is reachable by + * using {@link RMWSConsts#APPS_APPID_STATE}. + * + * @param targetState the target state for the app + * @param hsr the servlet request + * @param appId the Id of the application we want to update the state + * @return Response containing the status code + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws YarnException if app does not exist + * @throws InterruptedException if interrupted + * @throws IOException if doAs action throws an IOException + */ + Response updateAppState(AppState targetState, HttpServletRequest hsr, + String appId) throws AuthorizationException, YarnException, + InterruptedException, IOException; + + /** + * This method retrieves all the node labels with the respective nodes in the + * cluster, and it is reachable by using + * {@link RMWSConsts#GET_NODE_TO_LABELS}. + * + * @see ApplicationClientProtocol#getNodeToLabels + * @param hsr the servlet request + * @return all the nodes within a node label + * @throws IOException if an IOException happened + */ + NodeToLabelsInfo getNodeToLabels(HttpServletRequest hsr) throws IOException; + + /** + * This method retrieves all the node within multiple node labels in the + * cluster, and it is reachable by using {@link RMWSConsts#LABEL_MAPPINGS}. + * + * @see ApplicationClientProtocol#getLabelsToNodes + * @param labels filter the result by node labels + * @return all the nodes within multiple node labels + * @throws IOException if an IOException happened + */ + LabelsToNodesInfo getLabelsToNodes(Set labels) throws IOException; + + /** + * This method replaces all the node labels for specific nodes, and it is + * reachable by using {@link RMWSConsts#REPLACE_NODE_TO_LABELS}. + * + * @see ResourceManagerAdministrationProtocol#replaceLabelsOnNode + * @param newNodeToLabels the list of new labels + * @param hsr the servlet request + * @return Response containing the status code + * @throws Exception if an exception happened + */ + Response replaceLabelsOnNodes(NodeToLabelsEntryList newNodeToLabels, + HttpServletRequest hsr) throws Exception; + + /** + * This method replaces all the node labels for specific node, and it is + * reachable by using {@link RMWSConsts#NODES_NODEID_REPLACE_LABELS}. + * + * @see ResourceManagerAdministrationProtocol#replaceLabelsOnNode + * @param newNodeLabelsName the list of new labels + * @param hsr the servlet request + * @param nodeId the node we want to replace the node labels + * @return Response containing the status code + * @throws Exception if an exception happened + */ + Response replaceLabelsOnNode(Set newNodeLabelsName, + HttpServletRequest hsr, String nodeId) throws Exception; + + /** + * This method retrieves all the node labels in the cluster, and it is + * reachable by using {@link RMWSConsts#GET_NODE_LABELS}. + * + * @see ApplicationClientProtocol#getClusterNodeLabels + * @param hsr the servlet request + * @return all the node labels in the cluster + * @throws IOException if an IOException happened + */ + NodeLabelsInfo getClusterNodeLabels(HttpServletRequest hsr) + throws IOException; + + /** + * This method adds specific node labels for specific nodes, and it is + * reachable by using {@link RMWSConsts#ADD_NODE_LABELS}. + * + * @see ResourceManagerAdministrationProtocol#addToClusterNodeLabels + * @param newNodeLabels the node labels to add + * @param hsr the servlet request + * @return Response containing the status code + * @throws Exception in case of bad request + */ + Response addToClusterNodeLabels(NodeLabelsInfo newNodeLabels, + HttpServletRequest hsr) throws Exception; + + /** + * This method removes all the node labels for specific nodes, and it is + * reachable by using {@link RMWSConsts#REMOVE_NODE_LABELS}. + * + * @see ResourceManagerAdministrationProtocol#removeFromClusterNodeLabels + * @param oldNodeLabels the node labels to remove + * @param hsr the servlet request + * @return Response containing the status code + * @throws Exception in case of bad request + */ + Response removeFromCluserNodeLabels(Set oldNodeLabels, + HttpServletRequest hsr) throws Exception; + + /** + * This method retrieves all the node labels for specific node, and it is + * reachable by using {@link RMWSConsts#NODES_NODEID_GETLABELS}. + * + * @param hsr the servlet request + * @param nodeId the node we want to get all the node labels + * @return all the labels for a specific node. + * @throws IOException if an IOException happened + */ + NodeLabelsInfo getLabelsOnNode(HttpServletRequest hsr, String nodeId) + throws IOException; + + /** + * This method retrieves the priority for a specific app, and it is reachable + * by using {@link RMWSConsts#APPS_APPID_PRIORITY}. + * + * @param hsr the servlet request + * @param appId the app we want to get the priority + * @return the priority for a specific application + * @throws AuthorizationException in case of the user is not authorized + */ + AppPriority getAppPriority(HttpServletRequest hsr, String appId) + throws AuthorizationException; + + /** + * This method updates the priority for a specific application, and it is + * reachable by using {@link RMWSConsts#APPS_APPID_PRIORITY}. + * + * @param targetPriority the priority we want to set for the app + * @param hsr the servlet request + * @param appId the application we want to update its priority + * @return Response containing the status code + * @throws AuthorizationException if the user is not authenticated + * @throws YarnException if the target is null + * @throws IOException if the update fails. + * @throws InterruptedException if interrupted. + */ + Response updateApplicationPriority(AppPriority targetPriority, + HttpServletRequest hsr, String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException; + + /** + * This method retrieves the queue for a specific app, and it is reachable by + * using {@link RMWSConsts#APPS_APPID_QUEUE}. + * + * @param hsr the servlet request + * @param appId the application we want to retrieve its queue + * @return the Queue for a specific application. + * @throws AuthorizationException if the user is not authenticated + */ + AppQueue getAppQueue(HttpServletRequest hsr, String appId) + throws AuthorizationException; + + /** + * This method updates the queue for a specific application, and it is + * reachable by using {@link RMWSConsts#APPS_APPID_QUEUE}. + * + * @param targetQueue the queue we want to set + * @param hsr the servlet request + * @param appId the application we want to change its queue + * @return Response containing the status code + * @throws AuthorizationException if the user is not authenticated + * @throws YarnException if the app is not found + * @throws IOException if the update fails. + * @throws InterruptedException if interrupted. + */ + Response updateAppQueue(AppQueue targetQueue, HttpServletRequest hsr, + String appId) throws AuthorizationException, YarnException, + InterruptedException, IOException; + + /** + * Generates a new ApplicationId which is then sent to the client. This method + * is reachable by using {@link RMWSConsts#APPS_NEW_APPLICATION}. + * + * @see ApplicationClientProtocol#getNewApplication + * + * @param hsr the servlet request + * @return Response containing the app id and the maximum resource + * capabilities + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws IOException if the creation fails + * @throws InterruptedException if interrupted + */ + Response createNewApplication(HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * Function to submit an app to the RM. This method is reachable by using + * {@link RMWSConsts#APPS}. + * + * @see ApplicationClientProtocol#submitApplication + * + * @param newApp structure containing information to construct the + * ApplicationSubmissionContext + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws IOException if the submission failed + * @throws InterruptedException if interrupted + */ + Response submitApplication(ApplicationSubmissionContextInfo newApp, + HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * This method posts a delegation token from the client, and it is reachable + * by using {@link RMWSConsts#DELEGATION_TOKEN}. + * + * @see ApplicationBaseProtocol#getDelegationToken + * @param tokenData the token to delegate + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if Kerberos auth failed + * @throws IOException if the delegation failed + * @throws InterruptedException if interrupted + * @throws Exception in case of bad request + */ + Response postDelegationToken(DelegationToken tokenData, + HttpServletRequest hsr) throws AuthorizationException, IOException, + InterruptedException, Exception; + + /** + * This method updates the expiration for a delegation token from the client, + * and it is reachable by using + * {@link RMWSConsts#DELEGATION_TOKEN_EXPIRATION}. + * + * @see ApplicationBaseProtocol#renewDelegationToken + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if Kerberos auth failed + * @throws IOException if the delegation failed + * @throws Exception in case of bad request + */ + Response postDelegationTokenExpiration(HttpServletRequest hsr) + throws AuthorizationException, IOException, Exception; + + /** + * This method cancel the delegation token from the client, and it is + * reachable by using {@link RMWSConsts#DELEGATION_TOKEN}. + * + * @see ApplicationBaseProtocol#cancelDelegationToken + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if Kerberos auth failed + * @throws IOException if the delegation failed + * @throws InterruptedException if interrupted + * @throws Exception in case of bad request + */ + Response cancelDelegationToken(HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException, + Exception; + + /** + * Generates a new ReservationId which is then sent to the client. This method + * is reachable by using {@link RMWSConsts#RESERVATION_NEW}. + * + * @see ApplicationClientProtocol#getNewReservation + * + * @param hsr the servlet request + * @return Response containing the app id and the maximum resource + * capabilities + * @throws AuthorizationException if the user is not authorized to invoke this + * method. + * @throws IOException if creation failed + * @throws InterruptedException if interrupted + */ + Response createNewReservation(HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * Function to submit a Reservation to the RM.This method is reachable by + * using {@link RMWSConsts#RESERVATION_SUBMIT}. + * + * @see ApplicationClientProtocol#submitReservation + * + * @param resContext provides information to construct the + * ReservationSubmissionRequest + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws IOException if creation failed + * @throws InterruptedException if interrupted + */ + Response submitReservation(ReservationSubmissionRequestInfo resContext, + HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * Function to update a Reservation to the RM. This method is reachable by + * using {@link RMWSConsts#RESERVATION_UPDATE}. + * + * @see ApplicationClientProtocol#updateReservation + * + * @param resContext provides information to construct the + * ReservationUpdateRequest + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws IOException if the operation failed + * @throws InterruptedException if interrupted + */ + Response updateReservation(ReservationUpdateRequestInfo resContext, + HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * Function to delete a Reservation to the RM. This method is reachable by + * using {@link RMWSConsts#RESERVATION_DELETE}. + * + * @see ApplicationClientProtocol#deleteReservation + * + * @param resContext provides information to construct the + * ReservationDeleteRequest + * @param hsr the servlet request + * @return Response containing the status code + * @throws AuthorizationException when the user group information cannot be + * retrieved. + * @throws IOException when a {@link ReservationDeleteRequest} cannot be + * created from the {@link ReservationDeleteRequestInfo}. This + * exception is also thrown on + * {@code ClientRMService.deleteReservation} invokation failure. + * @throws InterruptedException if doAs action throws an InterruptedException. + */ + Response deleteReservation(ReservationDeleteRequestInfo resContext, + HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException; + + /** + * Function to retrieve a list of all the reservations. This method is + * reachable by using {@link RMWSConsts#RESERVATION_LIST}. + * + * @see ApplicationClientProtocol#listReservations + * @param queue filter the result by queue + * @param reservationId filter the result by reservationId + * @param startTime filter the result by start time + * @param endTime filter the result by end time + * @param includeResourceAllocations true if the resource allocation should be + * in the result, false otherwise + * @param hsr the servlet request + * @return Response containing the status code + * @throws Exception in case of bad request + */ + Response listReservation(String queue, String reservationId, long startTime, + long endTime, boolean includeResourceAllocations, HttpServletRequest hsr) + throws Exception; + + /** + * This method retrieves the timeout information for a specific app with a + * specific type, and it is reachable by using + * {@link RMWSConsts#APPS_TIMEOUTS_TYPE}. + * + * @param hsr the servlet request + * @param appId the application we want to get the timeout + * @param type the type of the timeouts + * @return the timeout for a specific application with a specific type. + * @throws AuthorizationException if the user is not authorized + */ + AppTimeoutInfo getAppTimeout(HttpServletRequest hsr, String appId, + String type) throws AuthorizationException; + + /** + * This method retrieves the timeout information for a specific app, and it is + * reachable by using {@link RMWSConsts#APPS_TIMEOUTS}. + * + * @param hsr the servlet request + * @param appId the application we want to get the timeouts + * @return the timeouts for a specific application + * @throws AuthorizationException if the user is not authorized + */ + AppTimeoutsInfo getAppTimeouts(HttpServletRequest hsr, String appId) + throws AuthorizationException; + + /** + * This method updates the timeout information for a specific app, and it is + * reachable by using {@link RMWSConsts#APPS_TIMEOUT}. + * + * @see ApplicationClientProtocol#updateApplicationTimeouts + * @param appTimeout the appTimeoutInfo + * @param hsr the servlet request + * @param appId the application we want to update + * @return Response containing the status code + * @throws AuthorizationException if the user is not authorized to invoke this + * method + * @throws YarnException in case of bad request + * @throws IOException if the operation failed + * @throws InterruptedException if interrupted + */ + Response updateApplicationTimeout(AppTimeoutInfo appTimeout, + HttpServletRequest hsr, String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException; + + /** + * This method retrieves all the attempts information for a specific app, and + * it is reachable by using {@link RMWSConsts#APPS_APPID_APPATTEMPTS}. + * + * @see ApplicationBaseProtocol#getApplicationAttempts + * @param hsr the servlet request + * @param appId the application we want to get the attempts + * @return all the attempts info for a specific application + */ + AppAttemptsInfo getAppAttempts(HttpServletRequest hsr, String appId); +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java index bd0602b5eac..acfb2b89bbf 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java @@ -204,18 +204,26 @@ import com.google.inject.Inject; import com.google.inject.Singleton; @Singleton -@Path("/ws/v1/cluster") -public class RMWebServices extends WebServices { +@Path(RMWSConsts.RM_WEB_SERVICE_PATH) +public class RMWebServices extends WebServices implements RMWebServiceProtocol { + private static final Log LOG = LogFactory.getLog(RMWebServices.class.getName()); - private static final String EMPTY = ""; - private static final String ANY = "*"; + private final ResourceManager rm; - private static RecordFactory recordFactory = RecordFactoryProvider - .getRecordFactory(null); + private static RecordFactory recordFactory = + RecordFactoryProvider.getRecordFactory(null); private final Configuration conf; private @Context HttpServletResponse response; + // -------Default values of QueryParams for RMWebServiceProtocol-------- + + public static final String DEFAULT_QUEUE = "default"; + public static final String DEFAULT_RESERVATION_ID = ""; + public static final String DEFAULT_START_TIME = "0"; + public static final String DEFAULT_END_TIME = "-1"; + public static final String DEFAULT_INCLUDE_RESOURCE = "false"; + @VisibleForTesting boolean isCentralizedNodeLabelConfiguration = true; @@ -241,15 +249,15 @@ public class RMWebServices extends WebServices { // Check for the authorization. UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); List forwardedAddresses = null; - String forwardedFor = hsr.getHeader("X-Forwarded-For"); + String forwardedFor = hsr.getHeader(RMWSConsts.FORWARDED_FOR); if (forwardedFor != null) { forwardedAddresses = Arrays.asList(forwardedFor.split(",")); } if (callerUGI != null && !(this.rm.getApplicationACLsManager().checkAccess(callerUGI, - ApplicationAccessType.VIEW_APP, app.getUser(), - app.getApplicationId()) || - this.rm.getQueueACLsManager().checkAccess(callerUGI, + ApplicationAccessType.VIEW_APP, app.getUser(), + app.getApplicationId()) + || this.rm.getQueueACLsManager().checkAccess(callerUGI, QueueACL.ADMINISTER_QUEUE, app, hsr.getRemoteAddr(), forwardedAddresses))) { return false; @@ -258,39 +266,43 @@ public class RMWebServices extends WebServices { } private void init() { - //clear content type + // clear content type response.setContentType(null); } @GET @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public ClusterInfo get() { return getClusterInfo(); } @GET - @Path("/info") + @Path(RMWSConsts.INFO) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public ClusterInfo getClusterInfo() { init(); return new ClusterInfo(this.rm); } @GET - @Path("/metrics") + @Path(RMWSConsts.METRICS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public ClusterMetricsInfo getClusterMetricsInfo() { init(); return new ClusterMetricsInfo(this.rm); } @GET - @Path("/scheduler") + @Path(RMWSConsts.SCHEDULER) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public SchedulerTypeInfo getSchedulerInfo() { init(); ResourceScheduler rs = rm.getResourceScheduler(); @@ -298,8 +310,7 @@ public class RMWebServices extends WebServices { if (rs instanceof CapacityScheduler) { CapacityScheduler cs = (CapacityScheduler) rs; CSQueue root = cs.getRootQueue(); - sinfo = - new CapacitySchedulerInfo(root, cs); + sinfo = new CapacitySchedulerInfo(root, cs); } else if (rs instanceof FairScheduler) { FairScheduler fs = (FairScheduler) rs; sinfo = new FairSchedulerInfo(fs); @@ -312,10 +323,11 @@ public class RMWebServices extends WebServices { } @POST - @Path("/scheduler/logs") + @Path(RMWSConsts.SCHEDULER_LOGS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) - public String dumpSchedulerLogs(@FormParam("time") String time, + @Override + public String dumpSchedulerLogs(@FormParam(RMWSConsts.TIME) String time, @Context HttpServletRequest hsr) throws IOException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); @@ -345,52 +357,51 @@ public class RMWebServices extends WebServices { return "Capacity scheduler logs are being created."; } - /** - * Returns all nodes in the cluster. If the states param is given, returns - * all nodes that are in the comma-separated list of states. - */ @GET - @Path("/nodes") + @Path(RMWSConsts.NODES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) - public NodesInfo getNodes(@QueryParam("states") String states) { + @Override + public NodesInfo getNodes(@QueryParam(RMWSConsts.STATES) String states) { init(); ResourceScheduler sched = this.rm.getResourceScheduler(); if (sched == null) { throw new NotFoundException("Null ResourceScheduler instance"); } - + EnumSet acceptedStates; if (states == null) { acceptedStates = EnumSet.allOf(NodeState.class); } else { acceptedStates = EnumSet.noneOf(NodeState.class); for (String stateStr : states.split(",")) { - acceptedStates.add( - NodeState.valueOf(StringUtils.toUpperCase(stateStr))); + acceptedStates + .add(NodeState.valueOf(StringUtils.toUpperCase(stateStr))); } } - - Collection rmNodes = RMServerUtils.queryRMNodes( - this.rm.getRMContext(), acceptedStates); + + Collection rmNodes = + RMServerUtils.queryRMNodes(this.rm.getRMContext(), acceptedStates); NodesInfo nodesInfo = new NodesInfo(); for (RMNode rmNode : rmNodes) { NodeInfo nodeInfo = new NodeInfo(rmNode, sched); - if (EnumSet.of(NodeState.LOST, NodeState.DECOMMISSIONED, NodeState.REBOOTED) + if (EnumSet + .of(NodeState.LOST, NodeState.DECOMMISSIONED, NodeState.REBOOTED) .contains(rmNode.getState())) { - nodeInfo.setNodeHTTPAddress(EMPTY); + nodeInfo.setNodeHTTPAddress(RMWSConsts.EMPTY); } nodesInfo.add(nodeInfo); } - + return nodesInfo; } @GET - @Path("/nodes/{nodeId}") + @Path(RMWSConsts.NODES_NODEID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) - public NodeInfo getNode(@PathParam("nodeId") String nodeId) { + @Override + public NodeInfo getNode(@PathParam(RMWSConsts.NODEID) String nodeId) { init(); if (nodeId == null || nodeId.isEmpty()) { throw new NotFoundException("nodeId, " + nodeId + ", is empty or null"); @@ -411,28 +422,29 @@ public class RMWebServices extends WebServices { } NodeInfo nodeInfo = new NodeInfo(ni, sched); if (isInactive) { - nodeInfo.setNodeHTTPAddress(EMPTY); + nodeInfo.setNodeHTTPAddress(RMWSConsts.EMPTY); } return nodeInfo; } @GET - @Path("/apps") + @Path(RMWSConsts.APPS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppsInfo getApps(@Context HttpServletRequest hsr, - @QueryParam("state") String stateQuery, - @QueryParam("states") Set statesQuery, - @QueryParam("finalStatus") String finalStatusQuery, - @QueryParam("user") String userQuery, - @QueryParam("queue") String queueQuery, - @QueryParam("limit") String count, - @QueryParam("startedTimeBegin") String startedBegin, - @QueryParam("startedTimeEnd") String startedEnd, - @QueryParam("finishedTimeBegin") String finishBegin, - @QueryParam("finishedTimeEnd") String finishEnd, - @QueryParam("applicationTypes") Set applicationTypes, - @QueryParam("applicationTags") Set applicationTags) { + @QueryParam(RMWSConsts.STATE) String stateQuery, + @QueryParam(RMWSConsts.STATES) Set statesQuery, + @QueryParam(RMWSConsts.FINAL_STATUS) String finalStatusQuery, + @QueryParam(RMWSConsts.USER) String userQuery, + @QueryParam(RMWSConsts.QUEUE) String queueQuery, + @QueryParam(RMWSConsts.LIMIT) String count, + @QueryParam(RMWSConsts.STARTED_TIME_BEGIN) String startedBegin, + @QueryParam(RMWSConsts.STARTED_TIME_END) String startedEnd, + @QueryParam(RMWSConsts.FINISHED_TIME_BEGIN) String finishBegin, + @QueryParam(RMWSConsts.FINISHED_TIME_END) String finishEnd, + @QueryParam(RMWSConsts.APPLICATION_TYPES) Set applicationTypes, + @QueryParam(RMWSConsts.APPLICATION_TAGS) Set applicationTags) { boolean checkCount = false; boolean checkStart = false; boolean checkEnd = false; @@ -460,7 +472,8 @@ public class RMWebServices extends WebServices { checkStart = true; sBegin = Long.parseLong(startedBegin); if (sBegin < 0) { - throw new BadRequestException("startedTimeBegin must be greater than 0"); + throw new BadRequestException( + "startedTimeBegin must be greater than 0"); } } if (startedEnd != null && !startedEnd.isEmpty()) { @@ -563,8 +576,8 @@ public class RMWebServices extends WebServices { List appReports = null; try { - appReports = rm.getClientRMService() - .getApplications(request, false).getApplicationList(); + appReports = rm.getClientRMService().getApplications(request, false) + .getApplicationList(); } catch (YarnException e) { LOG.error("Unable to retrieve apps from ClientRMService", e); throw new YarnRuntimeException( @@ -588,19 +601,20 @@ public class RMWebServices extends WebServices { } } - AppInfo app = new AppInfo(rm, rmapp, - hasAccess(rmapp, hsr), WebAppUtils.getHttpSchemePrefix(conf)); + AppInfo app = new AppInfo(rm, rmapp, hasAccess(rmapp, hsr), + WebAppUtils.getHttpSchemePrefix(conf)); allApps.add(app); } return allApps; } @GET - @Path("/scheduler/activities") + @Path(RMWSConsts.SCHEDULER_ACTIVITIES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public ActivitiesInfo getActivities(@Context HttpServletRequest hsr, - @QueryParam("nodeId") String nodeId) { + @QueryParam(RMWSConsts.NODEID) String nodeId) { YarnScheduler scheduler = rm.getRMContext().getScheduler(); if (scheduler instanceof AbstractYarnScheduler) { @@ -636,10 +650,12 @@ public class RMWebServices extends WebServices { boolean correctNodeId = false; for (FiCaSchedulerNode node : nodeList) { - if ((portName.equals("") && node.getRMNode().getHostName().equals( - hostName)) || (!portName.equals("") && node.getRMNode() - .getHostName().equals(hostName) && String.valueOf( - node.getRMNode().getCommandPort()).equals(portName))) { + if ((portName.equals("") + && node.getRMNode().getHostName().equals(hostName)) + || (!portName.equals("") + && node.getRMNode().getHostName().equals(hostName) + && String.valueOf(node.getRMNode().getCommandPort()) + .equals(portName))) { correctNodeId = true; nodeId = node.getNodeID().toString(); break; @@ -665,11 +681,13 @@ public class RMWebServices extends WebServices { } @GET - @Path("/scheduler/app-activities") + @Path(RMWSConsts.SCHEDULER_APP_ACTIVITIES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppActivitiesInfo getAppActivities(@Context HttpServletRequest hsr, - @QueryParam("appId") String appId, @QueryParam("maxTime") String time) { + @QueryParam(RMWSConsts.APP_ID) String appId, + @QueryParam(RMWSConsts.MAX_TIME) String time) { YarnScheduler scheduler = rm.getRMContext().getScheduler(); if (scheduler instanceof AbstractYarnScheduler) { @@ -683,7 +701,7 @@ public class RMWebServices extends WebServices { return new AppActivitiesInfo(errMessage, appId); } - if(appId == null) { + if (appId == null) { String errMessage = "Must provide an application Id"; return new AppActivitiesInfo(errMessage, null); } @@ -716,13 +734,14 @@ public class RMWebServices extends WebServices { } @GET - @Path("/appstatistics") + @Path(RMWSConsts.APP_STATISTICS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public ApplicationStatisticsInfo getAppStatistics( @Context HttpServletRequest hsr, - @QueryParam("states") Set stateQueries, - @QueryParam("applicationTypes") Set typeQueries) { + @QueryParam(RMWSConsts.STATES) Set stateQueries, + @QueryParam(RMWSConsts.APPLICATION_TYPES) Set typeQueries) { init(); // parse the params and build the scoreboard @@ -731,7 +750,7 @@ public class RMWebServices extends WebServices { Set types = parseQueries(typeQueries, false); // if no types, counts the applications of any types if (types.size() == 0) { - types.add(ANY); + types.add(RMWSConsts.ANY); } else if (types.size() != 1) { throw new BadRequestException("# of applicationTypes = " + types.size() + ", we temporarily support at most one applicationType"); @@ -752,10 +771,9 @@ public class RMWebServices extends WebServices { for (RMApp rmapp : apps.values()) { YarnApplicationState state = rmapp.createApplicationState(); String type = StringUtils.toLowerCase(rmapp.getApplicationType().trim()); - if (states.contains( - StringUtils.toLowerCase(state.toString()))) { - if (types.contains(ANY)) { - countApp(scoreboard, state, ANY); + if (states.contains(StringUtils.toLowerCase(state.toString()))) { + if (types.contains(RMWSConsts.ANY)) { + countApp(scoreboard, state, RMWSConsts.ANY); } else if (types.contains(type)) { countApp(scoreboard, state, type); } @@ -764,10 +782,10 @@ public class RMWebServices extends WebServices { // fill the response object ApplicationStatisticsInfo appStatInfo = new ApplicationStatisticsInfo(); - for (Map.Entry> partScoreboard - : scoreboard.entrySet()) { - for (Map.Entry statEntry - : partScoreboard.getValue().entrySet()) { + for (Map.Entry> partScoreboard : scoreboard + .entrySet()) { + for (Map.Entry statEntry : partScoreboard.getValue() + .entrySet()) { StatisticsItemInfo statItem = new StatisticsItemInfo( partScoreboard.getKey(), statEntry.getKey(), statEntry.getValue()); appStatInfo.add(statItem); @@ -777,9 +795,9 @@ public class RMWebServices extends WebServices { } private static Map> buildScoreboard( - Set states, Set types) { - Map> scoreboard - = new HashMap>(); + Set states, Set types) { + Map> scoreboard = + new HashMap>(); // default states will result in enumerating all YarnApplicationStates assert !states.isEmpty(); for (String state : states) { @@ -804,11 +822,12 @@ public class RMWebServices extends WebServices { } @GET - @Path("/apps/{appid}") + @Path(RMWSConsts.APPS_APPID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppInfo getApp(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) { + @PathParam(RMWSConsts.APPID) String appId) { init(); ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId); RMApp app = rm.getRMContext().getRMApps().get(id); @@ -819,11 +838,12 @@ public class RMWebServices extends WebServices { } @GET - @Path("/apps/{appid}/appattempts") + @Path(RMWSConsts.APPS_APPID_APPATTEMPTS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppAttemptsInfo getAppAttempts(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) { + @PathParam(RMWSConsts.APPID) String appId) { init(); ApplicationId id = WebAppUtils.parseApplicationId(recordFactory, appId); @@ -843,25 +863,27 @@ public class RMWebServices extends WebServices { } @GET - @Path("/apps/{appid}/appattempts/{appattemptid}") + @Path(RMWSConsts.APPS_APPID_APPATTEMPTS_APPATTEMPTID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override - public org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo getAppAttempt(@Context HttpServletRequest req, - @Context HttpServletResponse res, @PathParam("appid") String appId, - @PathParam("appattemptid") String appAttemptId) { + public org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo getAppAttempt( + @Context HttpServletRequest req, @Context HttpServletResponse res, + @PathParam(RMWSConsts.APPID) String appId, + @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId) { init(res); return super.getAppAttempt(req, res, appId, appAttemptId); } @GET - @Path("/apps/{appid}/appattempts/{appattemptid}/containers") + @Path(RMWSConsts.APPS_APPID_APPATTEMPTS_APPATTEMPTID_CONTAINERS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override public ContainersInfo getContainers(@Context HttpServletRequest req, - @Context HttpServletResponse res, @PathParam("appid") String appId, - @PathParam("appattemptid") String appAttemptId) { + @Context HttpServletResponse res, + @PathParam(RMWSConsts.APPID) String appId, + @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId) { init(res); return super.getContainers(req, res, appId, appAttemptId); } @@ -872,8 +894,9 @@ public class RMWebServices extends WebServices { MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override public ContainerInfo getContainer(@Context HttpServletRequest req, - @Context HttpServletResponse res, @PathParam("appid") String appId, - @PathParam("appattemptid") String appAttemptId, + @Context HttpServletResponse res, + @PathParam(RMWSConsts.APPID) String appId, + @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId, @PathParam("containerid") String containerId) { init(res); return super.getContainer(req, res, appId, appAttemptId, containerId); @@ -883,8 +906,9 @@ public class RMWebServices extends WebServices { @Path("/apps/{appid}/state") @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppState getAppState(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) throws AuthorizationException { + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); String userName = ""; @@ -896,8 +920,8 @@ public class RMWebServices extends WebServices { app = getRMAppForAppId(appId); } catch (NotFoundException e) { RMAuditLogger.logFailure(userName, AuditConstants.GET_APP_STATE, - "UNKNOWN", "RMWebService", - "Trying to get state of an absent application " + appId); + "UNKNOWN", "RMWebService", + "Trying to get state of an absent application " + appId); throw e; } @@ -912,14 +936,15 @@ public class RMWebServices extends WebServices { // to 202 @PUT - @Path("/apps/{appid}/state") + @Path(RMWSConsts.APPS_APPID_STATE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response updateAppState(AppState targetState, - @Context HttpServletRequest hsr, @PathParam("appid") String appId) - throws AuthorizationException, YarnException, InterruptedException, - IOException { + @Context HttpServletRequest hsr, + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); @@ -939,8 +964,8 @@ public class RMWebServices extends WebServices { app = getRMAppForAppId(appId); } catch (NotFoundException e) { RMAuditLogger.logFailure(userName, AuditConstants.KILL_APP_REQUEST, - "UNKNOWN", "RMWebService", "Trying to kill an absent application " - + appId); + "UNKNOWN", "RMWebService", + "Trying to kill an absent application " + appId); throw e; } @@ -948,12 +973,13 @@ public class RMWebServices extends WebServices { // user is attempting to change state. right we only // allow users to kill the app - if (targetState.getState().equals(YarnApplicationState.KILLED.toString())) { + if (targetState.getState() + .equals(YarnApplicationState.KILLED.toString())) { return killApp(app, callerUGI, hsr, targetState.getDiagnostics()); } - throw new BadRequestException("Only '" - + YarnApplicationState.KILLED.toString() - + "' is allowed as a target state."); + throw new BadRequestException( + "Only '" + YarnApplicationState.KILLED.toString() + + "' is allowed as a target state."); } AppState ret = new AppState(); @@ -961,19 +987,20 @@ public class RMWebServices extends WebServices { return Response.status(Status.OK).entity(ret).build(); } - + @GET - @Path("/get-node-to-labels") + @Path(RMWSConsts.GET_NODE_TO_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr) throws IOException { init(); NodeToLabelsInfo ntl = new NodeToLabelsInfo(); HashMap ntlMap = ntl.getNodeToLabels(); - Map> nodeIdToLabels = rm.getRMContext() - .getNodeLabelManager().getNodeLabelsInfo(); + Map> nodeIdToLabels = + rm.getRMContext().getNodeLabelManager().getNodeLabelsInfo(); for (Map.Entry> nitle : nodeIdToLabels.entrySet()) { List labels = new ArrayList(nitle.getValue()); @@ -984,11 +1011,12 @@ public class RMWebServices extends WebServices { } @GET - @Path("/label-mappings") + @Path(RMWSConsts.LABEL_MAPPINGS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public LabelsToNodesInfo getLabelsToNodes( - @QueryParam("labels") Set labels) throws IOException { + @QueryParam(RMWSConsts.LABELS) Set labels) throws IOException { init(); LabelsToNodesInfo lts = new LabelsToNodesInfo(); @@ -1007,17 +1035,19 @@ public class RMWebServices extends WebServices { for (NodeId nodeId : entry.getValue()) { nodeIdStrList.add(nodeId.toString()); } - ltsMap.put(new NodeLabelInfo(entry.getKey()), new NodeIDsInfo( - nodeIdStrList)); + ltsMap.put(new NodeLabelInfo(entry.getKey()), + new NodeIDsInfo(nodeIdStrList)); } return lts; } @POST - @Path("/replace-node-to-labels") + @Path(RMWSConsts.REPLACE_NODE_TO_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) - public Response replaceLabelsOnNodes(final NodeToLabelsEntryList newNodeToLabels, + @Override + public Response replaceLabelsOnNodes( + final NodeToLabelsEntryList newNodeToLabels, @Context HttpServletRequest hsr) throws IOException { Map> nodeIdToLabels = new HashMap>(); @@ -1032,9 +1062,10 @@ public class RMWebServices extends WebServices { } @POST - @Path("/nodes/{nodeId}/replace-labels") + @Path(RMWSConsts.NODES_NODEID_REPLACE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response replaceLabelsOnNode( @QueryParam("labels") Set newNodeLabelsName, @Context HttpServletRequest hsr, @PathParam("nodeId") String nodeId) @@ -1053,21 +1084,19 @@ public class RMWebServices extends WebServices { String operation) throws IOException { init(); - NodeLabelsUtils.verifyCentralizedNodeLabelConfEnabled( - "replaceLabelsOnNode", isCentralizedNodeLabelConfiguration); + NodeLabelsUtils.verifyCentralizedNodeLabelConfEnabled("replaceLabelsOnNode", + isCentralizedNodeLabelConfiguration); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - String msg = - "Unable to obtain user name, user not authenticated for" - + " post to ..." + operation; + String msg = "Unable to obtain user name, user not authenticated for" + + " post to ..." + operation; throw new AuthorizationException(msg); } if (!rm.getRMContext().getNodeLabelManager().checkAccess(callerUGI)) { - String msg = - "User " + callerUGI.getShortUserName() + " not authorized" - + " for post to ..." + operation; + String msg = "User " + callerUGI.getShortUserName() + " not authorized" + + " for post to ..." + operation; throw new AuthorizationException(msg); } try { @@ -1081,58 +1110,60 @@ public class RMWebServices extends WebServices { } @GET - @Path("/get-node-labels") + @Path(RMWSConsts.GET_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) - public NodeLabelsInfo getClusterNodeLabels(@Context HttpServletRequest hsr) - throws IOException { + @Override + public NodeLabelsInfo getClusterNodeLabels(@Context HttpServletRequest hsr) + throws IOException { init(); - List nodeLabels = rm.getRMContext().getNodeLabelManager() - .getClusterNodeLabels(); + List nodeLabels = + rm.getRMContext().getNodeLabelManager().getClusterNodeLabels(); NodeLabelsInfo ret = new NodeLabelsInfo(nodeLabels); return ret; } - + @POST - @Path("/add-node-labels") + @Path(RMWSConsts.ADD_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response addToClusterNodeLabels(final NodeLabelsInfo newNodeLabels, - @Context HttpServletRequest hsr) - throws Exception { + @Context HttpServletRequest hsr) throws Exception { init(); - + UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { String msg = "Unable to obtain user name, user not authenticated for" - + " post to .../add-node-labels"; + + " post to .../add-node-labels"; throw new AuthorizationException(msg); } if (!rm.getRMContext().getNodeLabelManager().checkAccess(callerUGI)) { String msg = "User " + callerUGI.getShortUserName() + " not authorized" - + " for post to .../add-node-labels "; + + " for post to .../add-node-labels "; throw new AuthorizationException(msg); } - + try { rm.getRMContext().getNodeLabelManager() .addToCluserNodeLabels(newNodeLabels.getNodeLabels()); } catch (IOException e) { throw new BadRequestException(e); } - + return Response.status(Status.OK).build(); } - + @POST - @Path("/remove-node-labels") + @Path(RMWSConsts.REMOVE_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response removeFromCluserNodeLabels( - @QueryParam("labels") Set oldNodeLabels, + @QueryParam(RMWSConsts.LABELS) Set oldNodeLabels, @Context HttpServletRequest hsr) throws Exception { init(); @@ -1157,18 +1188,19 @@ public class RMWebServices extends WebServices { return Response.status(Status.OK).build(); } - + @GET - @Path("/nodes/{nodeId}/get-labels") + @Path(RMWSConsts.NODES_NODEID_GETLABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public NodeLabelsInfo getLabelsOnNode(@Context HttpServletRequest hsr, - @PathParam("nodeId") String nodeId) throws IOException { + @PathParam(RMWSConsts.NODEID) String nodeId) throws IOException { init(); NodeId nid = ConverterUtils.toNodeIdWithDefaultPort(nodeId); - List labels = new ArrayList(rm.getRMContext() - .getNodeLabelManager().getLabelsInfoByNode(nid)); + List labels = new ArrayList( + rm.getRMContext().getNodeLabelManager().getLabelsInfoByNode(nid)); return new NodeLabelsInfo(labels); } @@ -1183,20 +1215,19 @@ public class RMWebServices extends WebServices { final ApplicationId appid = app.getApplicationId(); KillApplicationResponse resp = null; try { - resp = - callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public KillApplicationResponse run() throws IOException, - YarnException { - KillApplicationRequest req = - KillApplicationRequest.newInstance(appid); - if (diagnostic != null) { - req.setDiagnostics(diagnostic); - } - return rm.getClientRMService().forceKillApplication(req); + resp = callerUGI + .doAs(new PrivilegedExceptionAction() { + @Override + public KillApplicationResponse run() + throws IOException, YarnException { + KillApplicationRequest req = + KillApplicationRequest.newInstance(appid); + if (diagnostic != null) { + req.setDiagnostics(diagnostic); } - }); + return rm.getClientRMService().forceKillApplication(req); + } + }); } catch (UndeclaredThrowableException ue) { // if the root cause is a permissions issue // bubble that up to the user @@ -1204,9 +1235,8 @@ public class RMWebServices extends WebServices { YarnException ye = (YarnException) ue.getCause(); if (ye.getCause() instanceof AccessControlException) { String appId = app.getApplicationId().toString(); - String msg = - "Unauthorized attempt to kill appid " + appId - + " by remote user " + userName; + String msg = "Unauthorized attempt to kill appid " + appId + + " by remote user " + userName; return Response.status(Status.FORBIDDEN).entity(msg).build(); } else { throw ue; @@ -1221,20 +1251,21 @@ public class RMWebServices extends WebServices { if (resp.getIsKillCompleted()) { RMAuditLogger.logSuccess(userName, AuditConstants.KILL_APP_REQUEST, - "RMWebService", app.getApplicationId()); + "RMWebService", app.getApplicationId()); } else { return Response.status(Status.ACCEPTED).entity(ret) - .header(HttpHeaders.LOCATION, hsr.getRequestURL()).build(); + .header(HttpHeaders.LOCATION, hsr.getRequestURL()).build(); } return Response.status(Status.OK).entity(ret).build(); } @GET - @Path("/apps/{appid}/priority") + @Path(RMWSConsts.APPS_APPID_PRIORITY) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppPriority getAppPriority(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) throws AuthorizationException { + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); String userName = "UNKNOWN-USER"; @@ -1252,21 +1283,21 @@ public class RMWebServices extends WebServices { } AppPriority ret = new AppPriority(); - ret.setPriority( - app.getApplicationPriority().getPriority()); + ret.setPriority(app.getApplicationPriority().getPriority()); return ret; } @PUT - @Path("/apps/{appid}/priority") + @Path(RMWSConsts.APPS_APPID_PRIORITY) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response updateApplicationPriority(AppPriority targetPriority, - @Context HttpServletRequest hsr, @PathParam("appid") String appId) - throws AuthorizationException, YarnException, InterruptedException, - IOException { + @Context HttpServletRequest hsr, + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException { init(); if (targetPriority == null) { throw new YarnException("Target Priority cannot be null"); @@ -1305,7 +1336,7 @@ public class RMWebServices extends WebServices { private Response modifyApplicationPriority(final RMApp app, UserGroupInformation callerUGI, final int appPriority) - throws IOException, InterruptedException { + throws IOException, InterruptedException { String userName = callerUGI.getUserName(); try { callerUGI.doAs(new PrivilegedExceptionAction() { @@ -1340,17 +1371,18 @@ public class RMWebServices extends WebServices { throw ue; } } - AppPriority ret = new AppPriority( - app.getApplicationPriority().getPriority()); + AppPriority ret = + new AppPriority(app.getApplicationPriority().getPriority()); return Response.status(Status.OK).entity(ret).build(); } @GET - @Path("/apps/{appid}/queue") + @Path(RMWSConsts.APPS_APPID_QUEUE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppQueue getAppQueue(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) throws AuthorizationException { + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); String userName = "UNKNOWN-USER"; @@ -1362,8 +1394,8 @@ public class RMWebServices extends WebServices { app = getRMAppForAppId(appId); } catch (NotFoundException e) { RMAuditLogger.logFailure(userName, AuditConstants.GET_APP_QUEUE, - "UNKNOWN", "RMWebService", - "Trying to get queue of an absent application " + appId); + "UNKNOWN", "RMWebService", + "Trying to get queue of an absent application " + appId); throw e; } @@ -1374,14 +1406,15 @@ public class RMWebServices extends WebServices { } @PUT - @Path("/apps/{appid}/queue") + @Path(RMWSConsts.APPS_APPID_QUEUE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response updateAppQueue(AppQueue targetQueue, - @Context HttpServletRequest hsr, @PathParam("appid") String appId) - throws AuthorizationException, YarnException, InterruptedException, - IOException { + @Context HttpServletRequest hsr, + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); @@ -1401,8 +1434,8 @@ public class RMWebServices extends WebServices { app = getRMAppForAppId(appId); } catch (NotFoundException e) { RMAuditLogger.logFailure(userName, AuditConstants.MOVE_APP_REQUEST, - "UNKNOWN", "RMWebService", "Trying to move an absent application " - + appId); + "UNKNOWN", "RMWebService", + "Trying to move an absent application " + appId); throw e; } @@ -1427,18 +1460,16 @@ public class RMWebServices extends WebServices { final ApplicationId appid = app.getApplicationId(); final String reqTargetQueue = targetQueue; try { - callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws IOException, - YarnException { - MoveApplicationAcrossQueuesRequest req = - MoveApplicationAcrossQueuesRequest.newInstance(appid, + callerUGI.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws IOException, YarnException { + MoveApplicationAcrossQueuesRequest req = + MoveApplicationAcrossQueuesRequest.newInstance(appid, reqTargetQueue); - rm.getClientRMService().moveApplicationAcrossQueues(req); - return null; - } - }); + rm.getClientRMService().moveApplicationAcrossQueues(req); + return null; + } + }); } catch (UndeclaredThrowableException ue) { // if the root cause is a permissions issue // bubble that up to the user @@ -1446,14 +1477,13 @@ public class RMWebServices extends WebServices { YarnException ye = (YarnException) ue.getCause(); if (ye.getCause() instanceof AccessControlException) { String appId = app.getApplicationId().toString(); - String msg = - "Unauthorized attempt to move appid " + appId - + " by remote user " + userName; + String msg = "Unauthorized attempt to move appid " + appId + + " by remote user " + userName; return Response.status(Status.FORBIDDEN).entity(msg).build(); } else if (ye.getMessage().startsWith("App in") && ye.getMessage().endsWith("state cannot be moved.")) { return Response.status(Status.BAD_REQUEST).entity(ye.getMessage()) - .build(); + .build(); } else { throw ue; } @@ -1496,32 +1526,22 @@ public class RMWebServices extends WebServices { private boolean isStaticUser(UserGroupInformation callerUGI) { String staticUser = conf.get(CommonConfigurationKeys.HADOOP_HTTP_STATIC_USER, - CommonConfigurationKeys.DEFAULT_HADOOP_HTTP_STATIC_USER); + CommonConfigurationKeys.DEFAULT_HADOOP_HTTP_STATIC_USER); return staticUser.equals(callerUGI.getUserName()); } - /** - * Generates a new ApplicationId which is then sent to the client - * - * @param hsr - * the servlet request - * @return Response containing the app id and the maximum resource - * capabilities - * @throws AuthorizationException - * @throws IOException - * @throws InterruptedException - */ @POST - @Path("/apps/new-application") + @Path(RMWSConsts.APPS_NEW_APPLICATION) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response createNewApplication(@Context HttpServletRequest hsr) throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -1536,33 +1556,21 @@ public class RMWebServices extends WebServices { // reuse the code in ClientRMService to create new app // get the new app id and submit app // set location header with new app location - /** - * Function to submit an app to the RM - * - * @param newApp - * structure containing information to construct the - * ApplicationSubmissionContext - * @param hsr - * the servlet request - * @return Response containing the status code - * @throws AuthorizationException - * @throws IOException - * @throws InterruptedException - */ @POST - @Path("/apps") + @Path(RMWSConsts.APPS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response submitApplication(ApplicationSubmissionContextInfo newApp, - @Context HttpServletRequest hsr) throws AuthorizationException, - IOException, InterruptedException { + @Context HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { @@ -1578,13 +1586,13 @@ public class RMWebServices extends WebServices { try { callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public SubmitApplicationResponse run() throws IOException, - YarnException { - return rm.getClientRMService().submitApplication(req); - } - }); + .doAs(new PrivilegedExceptionAction() { + @Override + public SubmitApplicationResponse run() + throws IOException, YarnException { + return rm.getClientRMService().submitApplication(req); + } + }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { throw new BadRequestException(ue.getCause().getMessage()); @@ -1595,7 +1603,7 @@ public class RMWebServices extends WebServices { String url = hsr.getRequestURL() + "/" + newApp.getApplicationId(); return Response.status(Status.ACCEPTED).header(HttpHeaders.LOCATION, url) - .build(); + .build(); } /** @@ -1618,7 +1626,7 @@ public class RMWebServices extends WebServices { } NewApplication appId = new NewApplication(resp.getApplicationId().toString(), - new ResourceInfo(resp.getMaximumResourceCapability())); + new ResourceInfo(resp.getMaximumResourceCapability())); return appId; } @@ -1626,8 +1634,7 @@ public class RMWebServices extends WebServices { * Create the actual ApplicationSubmissionContext to be submitted to the RM * from the information provided by the user. * - * @param newApp - * the information provided by the user + * @param newApp the information provided by the user * @return returns the constructed ApplicationSubmissionContext * @throws IOException */ @@ -1644,28 +1651,27 @@ public class RMWebServices extends WebServices { } catch (Exception e) { throw new BadRequestException(error); } - ApplicationSubmissionContext appContext = - ApplicationSubmissionContext.newInstance(appid, - newApp.getApplicationName(), newApp.getQueue(), - Priority.newInstance(newApp.getPriority()), - createContainerLaunchContext(newApp), newApp.getUnmanagedAM(), - newApp.getCancelTokensWhenComplete(), newApp.getMaxAppAttempts(), - createAppSubmissionContextResource(newApp), - newApp.getApplicationType(), - newApp.getKeepContainersAcrossApplicationAttempts(), - newApp.getAppNodeLabelExpression(), - newApp.getAMContainerNodeLabelExpression()); + ApplicationSubmissionContext appContext = ApplicationSubmissionContext + .newInstance(appid, newApp.getApplicationName(), newApp.getQueue(), + Priority.newInstance(newApp.getPriority()), + createContainerLaunchContext(newApp), newApp.getUnmanagedAM(), + newApp.getCancelTokensWhenComplete(), newApp.getMaxAppAttempts(), + createAppSubmissionContextResource(newApp), + newApp.getApplicationType(), + newApp.getKeepContainersAcrossApplicationAttempts(), + newApp.getAppNodeLabelExpression(), + newApp.getAMContainerNodeLabelExpression()); appContext.setApplicationTags(newApp.getApplicationTags()); appContext.setAttemptFailuresValidityInterval( newApp.getAttemptFailuresValidityInterval()); if (newApp.getLogAggregationContextInfo() != null) { - appContext.setLogAggregationContext(createLogAggregationContext( - newApp.getLogAggregationContextInfo())); + appContext.setLogAggregationContext( + createLogAggregationContext(newApp.getLogAggregationContextInfo())); } String reservationIdStr = newApp.getReservationId(); if (reservationIdStr != null && !reservationIdStr.isEmpty()) { - ReservationId reservationId = ReservationId.parseReservationId( - reservationIdStr); + ReservationId reservationId = + ReservationId.parseReservationId(reservationIdStr); appContext.setReservationID(reservationId); } return appContext; @@ -1674,20 +1680,19 @@ public class RMWebServices extends WebServices { protected Resource createAppSubmissionContextResource( ApplicationSubmissionContextInfo newApp) throws BadRequestException { if (newApp.getResource().getvCores() > rm.getConfig().getInt( - YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES, - YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES)) { + YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES, + YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES)) { String msg = "Requested more cores than configured max"; throw new BadRequestException(msg); } if (newApp.getResource().getMemorySize() > rm.getConfig().getInt( - YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_MB, - YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB)) { + YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_MB, + YarnConfiguration.DEFAULT_RM_SCHEDULER_MAXIMUM_ALLOCATION_MB)) { String msg = "Requested more memory than configured max"; throw new BadRequestException(msg); } - Resource r = - Resource.newInstance(newApp.getResource().getMemorySize(), newApp - .getResource().getvCores()); + Resource r = Resource.newInstance(newApp.getResource().getMemorySize(), + newApp.getResource().getvCores()); return r; } @@ -1696,21 +1701,20 @@ public class RMWebServices extends WebServices { * ApplicationSubmissionContext. This function takes the user information and * generates the ByteBuffer structures required by the ContainerLaunchContext * - * @param newApp - * the information provided by the user + * @param newApp the information provided by the user * @return created context * @throws BadRequestException * @throws IOException */ protected ContainerLaunchContext createContainerLaunchContext( - ApplicationSubmissionContextInfo newApp) throws BadRequestException, - IOException { + ApplicationSubmissionContextInfo newApp) + throws BadRequestException, IOException { // create container launch context HashMap hmap = new HashMap(); for (Map.Entry entry : newApp - .getContainerLaunchContextInfo().getAuxillaryServiceData().entrySet()) { + .getContainerLaunchContextInfo().getAuxillaryServiceData().entrySet()) { if (entry.getValue().isEmpty() == false) { Base64 decoder = new Base64(0, null, true); byte[] data = decoder.decode(entry.getValue()); @@ -1720,27 +1724,23 @@ public class RMWebServices extends WebServices { HashMap hlr = new HashMap(); for (Map.Entry entry : newApp - .getContainerLaunchContextInfo().getResources().entrySet()) { + .getContainerLaunchContextInfo().getResources().entrySet()) { LocalResourceInfo l = entry.getValue(); - LocalResource lr = - LocalResource.newInstance( - URL.fromURI(l.getUrl()), l.getType(), - l.getVisibility(), l.getSize(), l.getTimestamp()); + LocalResource lr = LocalResource.newInstance(URL.fromURI(l.getUrl()), + l.getType(), l.getVisibility(), l.getSize(), l.getTimestamp()); hlr.put(entry.getKey(), lr); } DataOutputBuffer out = new DataOutputBuffer(); - Credentials cs = - createCredentials(newApp.getContainerLaunchContextInfo() - .getCredentials()); + Credentials cs = createCredentials( + newApp.getContainerLaunchContextInfo().getCredentials()); cs.writeTokenStorageToStream(out); ByteBuffer tokens = ByteBuffer.wrap(out.getData()); - ContainerLaunchContext ctx = - ContainerLaunchContext.newInstance(hlr, newApp - .getContainerLaunchContextInfo().getEnvironment(), newApp - .getContainerLaunchContextInfo().getCommands(), hmap, tokens, newApp - .getContainerLaunchContextInfo().getAcls()); + ContainerLaunchContext ctx = ContainerLaunchContext.newInstance(hlr, + newApp.getContainerLaunchContextInfo().getEnvironment(), + newApp.getContainerLaunchContextInfo().getCommands(), hmap, tokens, + newApp.getContainerLaunchContextInfo().getAcls()); return ctx; } @@ -1749,20 +1749,21 @@ public class RMWebServices extends WebServices { * Generate a Credentials object from the information in the CredentialsInfo * object. * - * @param credentials - * the CredentialsInfo provided by the user. + * @param credentials the CredentialsInfo provided by the user. * @return */ private Credentials createCredentials(CredentialsInfo credentials) { Credentials ret = new Credentials(); try { - for (Map.Entry entry : credentials.getTokens().entrySet()) { + for (Map.Entry entry : credentials.getTokens() + .entrySet()) { Text alias = new Text(entry.getKey()); Token token = new Token(); token.decodeFromUrlString(entry.getValue()); ret.addToken(alias, token); } - for (Map.Entry entry : credentials.getSecrets().entrySet()) { + for (Map.Entry entry : credentials.getSecrets() + .entrySet()) { Text alias = new Text(entry.getKey()); Base64 decoder = new Base64(0, null, true); byte[] secret = decoder.decode(entry.getValue()); @@ -1770,8 +1771,8 @@ public class RMWebServices extends WebServices { } } catch (IOException ie) { throw new BadRequestException( - "Could not parse credentials data; exception message = " - + ie.getMessage()); + "Could not parse credentials data; exception message = " + + ie.getMessage()); } return ret; } @@ -1787,14 +1788,13 @@ public class RMWebServices extends WebServices { String authType = hsr.getAuthType(); if (!KerberosAuthenticationHandler.TYPE.equalsIgnoreCase(authType)) { - String msg = - "Delegation token operations can only be carried out on a " - + "Kerberos authenticated channel. Expected auth type is " - + KerberosAuthenticationHandler.TYPE + ", got type " + authType; + String msg = "Delegation token operations can only be carried out on a " + + "Kerberos authenticated channel. Expected auth type is " + + KerberosAuthenticationHandler.TYPE + ", got type " + authType; throw new YarnException(msg); } - if (hsr - .getAttribute(DelegationTokenAuthenticationHandler.DELEGATION_TOKEN_UGI_ATTRIBUTE) != null) { + if (hsr.getAttribute( + DelegationTokenAuthenticationHandler.DELEGATION_TOKEN_UGI_ATTRIBUTE) != null) { String msg = "Delegation token operations cannot be carried out using delegation" + " token authentication."; @@ -1817,10 +1817,11 @@ public class RMWebServices extends WebServices { } @POST - @Path("/delegation-token") + @Path(RMWSConsts.DELEGATION_TOKEN) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response postDelegationToken(DelegationToken tokenData, @Context HttpServletRequest hsr) throws AuthorizationException, IOException, InterruptedException, Exception { @@ -1836,14 +1837,14 @@ public class RMWebServices extends WebServices { } @POST - @Path("/delegation-token/expiration") + @Path(RMWSConsts.DELEGATION_TOKEN_EXPIRATION) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response - postDelegationTokenExpiration(@Context HttpServletRequest hsr) - throws AuthorizationException, IOException, InterruptedException, - Exception { + @Override + public Response postDelegationTokenExpiration(@Context HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException, + Exception { init(); UserGroupInformation callerUGI; @@ -1866,35 +1867,33 @@ public class RMWebServices extends WebServices { final String renewer = tokenData.getRenewer(); GetDelegationTokenResponse resp; try { - resp = - callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public GetDelegationTokenResponse run() throws IOException, - YarnException { - GetDelegationTokenRequest createReq = - GetDelegationTokenRequest.newInstance(renewer); - return rm.getClientRMService().getDelegationToken(createReq); - } - }); + resp = callerUGI + .doAs(new PrivilegedExceptionAction() { + @Override + public GetDelegationTokenResponse run() + throws IOException, YarnException { + GetDelegationTokenRequest createReq = + GetDelegationTokenRequest.newInstance(renewer); + return rm.getClientRMService().getDelegationToken(createReq); + } + }); } catch (Exception e) { LOG.info("Create delegation token request failed", e); throw e; } Token tk = - new Token(resp.getRMDelegationToken() - .getIdentifier().array(), resp.getRMDelegationToken().getPassword() - .array(), new Text(resp.getRMDelegationToken().getKind()), new Text( - resp.getRMDelegationToken().getService())); + new Token( + resp.getRMDelegationToken().getIdentifier().array(), + resp.getRMDelegationToken().getPassword().array(), + new Text(resp.getRMDelegationToken().getKind()), + new Text(resp.getRMDelegationToken().getService())); RMDelegationTokenIdentifier identifier = tk.decodeIdentifier(); - long currentExpiration = - rm.getRMContext().getRMDelegationTokenSecretManager() - .getRenewDate(identifier); - DelegationToken respToken = - new DelegationToken(tk.encodeToUrlString(), renewer, identifier - .getOwner().toString(), tk.getKind().toString(), currentExpiration, - identifier.getMaxDate()); + long currentExpiration = rm.getRMContext() + .getRMDelegationTokenSecretManager().getRenewDate(identifier); + DelegationToken respToken = new DelegationToken(tk.encodeToUrlString(), + renewer, identifier.getOwner().toString(), tk.getKind().toString(), + currentExpiration, identifier.getMaxDate()); return Response.status(Status.OK).entity(respToken).build(); } @@ -1906,30 +1905,29 @@ public class RMWebServices extends WebServices { Token token = extractToken(tokenData.getToken()); - org.apache.hadoop.yarn.api.records.Token dToken = - BuilderUtils.newDelegationToken(token.getIdentifier(), token.getKind() - .toString(), token.getPassword(), token.getService().toString()); + org.apache.hadoop.yarn.api.records.Token dToken = BuilderUtils + .newDelegationToken(token.getIdentifier(), token.getKind().toString(), + token.getPassword(), token.getService().toString()); final RenewDelegationTokenRequest req = RenewDelegationTokenRequest.newInstance(dToken); RenewDelegationTokenResponse resp; try { - resp = - callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public RenewDelegationTokenResponse run() throws IOException, - YarnException { - return rm.getClientRMService().renewDelegationToken(req); - } - }); + resp = callerUGI + .doAs(new PrivilegedExceptionAction() { + @Override + public RenewDelegationTokenResponse run() throws YarnException { + return rm.getClientRMService().renewDelegationToken(req); + } + }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { if (ue.getCause().getCause() instanceof InvalidToken) { throw new BadRequestException(ue.getCause().getCause().getMessage()); - } else if (ue.getCause().getCause() instanceof org.apache.hadoop.security.AccessControlException) { + } else if (ue.getCause() + .getCause() instanceof org.apache.hadoop.security.AccessControlException) { return Response.status(Status.FORBIDDEN) - .entity(ue.getCause().getCause().getMessage()).build(); + .entity(ue.getCause().getCause().getMessage()).build(); } LOG.info("Renew delegation token request failed", ue); throw ue; @@ -1955,9 +1953,10 @@ public class RMWebServices extends WebServices { // since urls tend to get logged and anyone with access to // the logs can extract tokens which are meant to be secret @DELETE - @Path("/delegation-token") + @Path(RMWSConsts.DELEGATION_TOKEN) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response cancelDelegationToken(@Context HttpServletRequest hsr) throws AuthorizationException, IOException, InterruptedException, Exception { @@ -1972,28 +1971,29 @@ public class RMWebServices extends WebServices { Token token = extractToken(hsr); - org.apache.hadoop.yarn.api.records.Token dToken = - BuilderUtils.newDelegationToken(token.getIdentifier(), token.getKind() - .toString(), token.getPassword(), token.getService().toString()); + org.apache.hadoop.yarn.api.records.Token dToken = BuilderUtils + .newDelegationToken(token.getIdentifier(), token.getKind().toString(), + token.getPassword(), token.getService().toString()); final CancelDelegationTokenRequest req = CancelDelegationTokenRequest.newInstance(dToken); try { callerUGI - .doAs(new PrivilegedExceptionAction() { - @Override - public CancelDelegationTokenResponse run() throws IOException, - YarnException { - return rm.getClientRMService().cancelDelegationToken(req); - } - }); + .doAs(new PrivilegedExceptionAction() { + @Override + public CancelDelegationTokenResponse run() + throws IOException, YarnException { + return rm.getClientRMService().cancelDelegationToken(req); + } + }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { if (ue.getCause().getCause() instanceof InvalidToken) { throw new BadRequestException(ue.getCause().getCause().getMessage()); - } else if (ue.getCause().getCause() instanceof org.apache.hadoop.security.AccessControlException) { + } else if (ue.getCause() + .getCause() instanceof org.apache.hadoop.security.AccessControlException) { return Response.status(Status.FORBIDDEN) - .entity(ue.getCause().getCause().getMessage()).build(); + .entity(ue.getCause().getCause().getMessage()).build(); } LOG.info("Renew delegation token request failed", ue); throw ue; @@ -2012,9 +2012,8 @@ public class RMWebServices extends WebServices { HttpServletRequest request) { String encodedToken = request.getHeader(DELEGATION_TOKEN_HEADER); if (encodedToken == null) { - String msg = - "Header '" + DELEGATION_TOKEN_HEADER - + "' containing encoded token not found"; + String msg = "Header '" + DELEGATION_TOKEN_HEADER + + "' containing encoded token not found"; throw new BadRequestException(msg); } return extractToken(encodedToken); @@ -2032,28 +2031,18 @@ public class RMWebServices extends WebServices { return token; } - /** - * Generates a new ReservationId which is then sent to the client. - * - * @param hsr the servlet request - * @return Response containing the app id and the maximum resource - * capabilities - * @throws AuthorizationException if the user is not authorized - * to invoke this method. - * @throws IOException if creation fails. - * @throws InterruptedException if interrupted. - */ @POST - @Path("/reservation/new-reservation") + @Path(RMWSConsts.RESERVATION_NEW) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response createNewReservation(@Context HttpServletRequest hsr) - throws AuthorizationException, IOException, InterruptedException { + throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -2088,32 +2077,21 @@ public class RMWebServices extends WebServices { return reservationId; } - /** - * Function to submit a Reservation to the RM. - * - * @param resContext provides information to construct the - * ReservationSubmissionRequest - * @param hsr the servlet request - * @return Response containing the status code - * @throws AuthorizationException - * @throws IOException - * @throws InterruptedException - */ @POST - @Path("/reservation/submit") + @Path(RMWSConsts.RESERVATION_SUBMIT) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - public Response submitReservation( - ReservationSubmissionRequestInfo resContext, - @Context HttpServletRequest hsr) throws AuthorizationException, - IOException, InterruptedException { + @Override + public Response submitReservation(ReservationSubmissionRequestInfo resContext, + @Context HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -2126,11 +2104,11 @@ public class RMWebServices extends WebServices { try { callerUGI .doAs(new PrivilegedExceptionAction() { - @Override - public ReservationSubmissionResponse run() throws IOException, - YarnException { - return rm.getClientRMService().submitReservation(reservation); - } + @Override + public ReservationSubmissionResponse run() + throws IOException, YarnException { + return rm.getClientRMService().submitReservation(reservation); + } }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { @@ -2179,9 +2157,8 @@ public class RMWebServices extends WebServices { int numContainers = resReqInfo.getNumContainers(); int minConcurrency = resReqInfo.getMinConcurrency(); long duration = resReqInfo.getDuration(); - ReservationRequest rr = - ReservationRequest.newInstance(capability, numContainers, - minConcurrency, duration); + ReservationRequest rr = ReservationRequest.newInstance(capability, + numContainers, minConcurrency, duration); list.add(rr); } ReservationRequests reqs = ReservationRequests.newInstance(list, resInt); @@ -2189,40 +2166,29 @@ public class RMWebServices extends WebServices { ReservationDefinition.newInstance(resInfo.getArrival(), resInfo.getDeadline(), reqs, resInfo.getReservationName()); - ReservationId reservationId = ReservationId.parseReservationId(resContext - .getReservationId()); - ReservationSubmissionRequest request = - ReservationSubmissionRequest.newInstance(rDef, resContext.getQueue(), - reservationId); + ReservationId reservationId = + ReservationId.parseReservationId(resContext.getReservationId()); + ReservationSubmissionRequest request = ReservationSubmissionRequest + .newInstance(rDef, resContext.getQueue(), reservationId); return request; } - /** - * Function to update a Reservation to the RM. - * - * @param resContext provides information to construct the - * ReservationUpdateRequest - * @param hsr the servlet request - * @return Response containing the status code - * @throws AuthorizationException - * @throws IOException - * @throws InterruptedException - */ @POST - @Path("/reservation/update") + @Path(RMWSConsts.RESERVATION_UPDATE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response updateReservation(ReservationUpdateRequestInfo resContext, - @Context HttpServletRequest hsr) throws AuthorizationException, - IOException, InterruptedException { + @Context HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -2234,16 +2200,15 @@ public class RMWebServices extends WebServices { ReservationUpdateResponseInfo resRespInfo; try { - resRespInfo = - callerUGI.doAs( - new PrivilegedExceptionAction() { - @Override - public ReservationUpdateResponseInfo run() throws IOException, - YarnException { - rm.getClientRMService().updateReservation(reservation); - return new ReservationUpdateResponseInfo(); - } - }); + resRespInfo = callerUGI + .doAs(new PrivilegedExceptionAction() { + @Override + public ReservationUpdateResponseInfo run() + throws IOException, YarnException { + rm.getClientRMService().updateReservation(reservation); + return new ReservationUpdateResponseInfo(); + } + }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { throw new BadRequestException(ue.getCause().getMessage()); @@ -2293,51 +2258,35 @@ public class RMWebServices extends WebServices { int numContainers = resReqInfo.getNumContainers(); int minConcurrency = resReqInfo.getMinConcurrency(); long duration = resReqInfo.getDuration(); - ReservationRequest rr = - ReservationRequest.newInstance(capability, numContainers, - minConcurrency, duration); + ReservationRequest rr = ReservationRequest.newInstance(capability, + numContainers, minConcurrency, duration); list.add(rr); } ReservationRequests reqs = ReservationRequests.newInstance(list, resInt); ReservationDefinition rDef = ReservationDefinition.newInstance(resInfo.getArrival(), resInfo.getDeadline(), reqs, resInfo.getReservationName()); - ReservationUpdateRequest request = - ReservationUpdateRequest.newInstance(rDef, ReservationId - .parseReservationId(resContext.getReservationId())); + ReservationUpdateRequest request = ReservationUpdateRequest.newInstance( + rDef, ReservationId.parseReservationId(resContext.getReservationId())); return request; } - /** - * Function to delete a Reservation to the RM. - * - * @param resContext provides information to construct - * the ReservationDeleteRequest - * @param hsr the servlet request - * @return Response containing the status code - * @throws AuthorizationException when the user group information cannot be - * retrieved. - * @throws IOException when a {@link ReservationDeleteRequest} cannot be - * created from the {@link ReservationDeleteRequestInfo}. This - * exception is also thrown on - * {@code ClientRMService.deleteReservation} invokation failure. - * @throws InterruptedException if doAs action throws an InterruptedException. - */ @POST - @Path("/reservation/delete") + @Path(RMWSConsts.RESERVATION_DELETE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response deleteReservation(ReservationDeleteRequestInfo resContext, - @Context HttpServletRequest hsr) throws AuthorizationException, - IOException, InterruptedException { + @Context HttpServletRequest hsr) + throws AuthorizationException, IOException, InterruptedException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -2349,16 +2298,15 @@ public class RMWebServices extends WebServices { ReservationDeleteResponseInfo resRespInfo; try { - resRespInfo = - callerUGI.doAs( - new PrivilegedExceptionAction() { - @Override - public ReservationDeleteResponseInfo run() throws IOException, - YarnException { - rm.getClientRMService().deleteReservation(reservation); - return new ReservationDeleteResponseInfo(); - } - }); + resRespInfo = callerUGI + .doAs(new PrivilegedExceptionAction() { + @Override + public ReservationDeleteResponseInfo run() + throws IOException, YarnException { + rm.getClientRMService().deleteReservation(reservation); + return new ReservationDeleteResponseInfo(); + } + }); } catch (UndeclaredThrowableException ue) { if (ue.getCause() instanceof YarnException) { throw new BadRequestException(ue.getCause().getMessage()); @@ -2373,37 +2321,33 @@ public class RMWebServices extends WebServices { private ReservationDeleteRequest createReservationDeleteRequest( ReservationDeleteRequestInfo resContext) throws IOException { - ReservationDeleteRequest request = - ReservationDeleteRequest.newInstance(ReservationId - .parseReservationId(resContext.getReservationId())); + ReservationDeleteRequest request = ReservationDeleteRequest.newInstance( + ReservationId.parseReservationId(resContext.getReservationId())); return request; } - /** - * Function to retrieve a list of all the reservations. - */ @GET - @Path("/reservation/list") + @Path(RMWSConsts.RESERVATION_LIST) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public Response listReservation( - @QueryParam("queue") @DefaultValue("default") String queue, - @QueryParam("reservation-id") @DefaultValue("") String reservationId, - @QueryParam("start-time") @DefaultValue("0") long startTime, - @QueryParam("end-time") @DefaultValue("-1") long endTime, - @QueryParam("include-resource-allocations") @DefaultValue("false") - boolean includeResourceAllocations, @Context HttpServletRequest hsr) - throws Exception { + @QueryParam(RMWSConsts.QUEUE) @DefaultValue(DEFAULT_QUEUE) String queue, + @QueryParam(RMWSConsts.RESERVATION_ID) @DefaultValue(DEFAULT_RESERVATION_ID) String reservationId, + @QueryParam(RMWSConsts.START_TIME) @DefaultValue(DEFAULT_START_TIME) long startTime, + @QueryParam(RMWSConsts.END_TIME) @DefaultValue(DEFAULT_END_TIME) long endTime, + @QueryParam(RMWSConsts.INCLUDE_RESOURCE) @DefaultValue(DEFAULT_INCLUDE_RESOURCE) boolean includeResourceAllocations, + @Context HttpServletRequest hsr) throws Exception { init(); final ReservationListRequest request = ReservationListRequest.newInstance( - queue, reservationId, startTime, endTime, includeResourceAllocations); + queue, reservationId, startTime, endTime, includeResourceAllocations); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); if (callerUGI == null) { - throw new AuthorizationException("Unable to obtain user name, " - + "user not authenticated"); + throw new AuthorizationException( + "Unable to obtain user name, " + "user not authenticated"); } if (UserGroupInformation.isSecurityEnabled() && isStaticUser(callerUGI)) { String msg = "The default static user cannot carry out this operation."; @@ -2412,11 +2356,11 @@ public class RMWebServices extends WebServices { ReservationListResponse resRespInfo; try { - resRespInfo = callerUGI.doAs( - new PrivilegedExceptionAction() { + resRespInfo = callerUGI + .doAs(new PrivilegedExceptionAction() { @Override - public ReservationListResponse run() throws IOException, - YarnException { + public ReservationListResponse run() + throws IOException, YarnException { return rm.getClientRMService().listReservations(request); } }); @@ -2428,18 +2372,19 @@ public class RMWebServices extends WebServices { throw ue; } - ReservationListInfo resResponse = new ReservationListInfo(resRespInfo, - includeResourceAllocations); + ReservationListInfo resResponse = + new ReservationListInfo(resRespInfo, includeResourceAllocations); return Response.status(Status.OK).entity(resResponse).build(); } @GET - @Path("/apps/{appid}/timeouts/{type}") + @Path(RMWSConsts.APPS_TIMEOUTS_TYPE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppTimeoutInfo getAppTimeout(@Context HttpServletRequest hsr, - @PathParam("appid") String appId, @PathParam("type") String type) - throws AuthorizationException { + @PathParam(RMWSConsts.APPID) String appId, + @PathParam(RMWSConsts.TYPE) String type) throws AuthorizationException { init(); RMApp app = validateAppTimeoutRequest(hsr, appId); @@ -2478,11 +2423,12 @@ public class RMWebServices extends WebServices { } @GET - @Path("/apps/{appid}/timeouts") + @Path(RMWSConsts.APPS_TIMEOUTS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) + @Override public AppTimeoutsInfo getAppTimeouts(@Context HttpServletRequest hsr, - @PathParam("appid") String appId) throws AuthorizationException { + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException { init(); RMApp app = validateAppTimeoutRequest(hsr, appId); @@ -2532,14 +2478,15 @@ public class RMWebServices extends WebServices { } @PUT - @Path("/apps/{appid}/timeout") + @Path(RMWSConsts.APPS_TIMEOUT) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Override public Response updateApplicationTimeout(AppTimeoutInfo appTimeout, - @Context HttpServletRequest hsr, @PathParam("appid") String appId) - throws AuthorizationException, YarnException, InterruptedException, - IOException { + @Context HttpServletRequest hsr, + @PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException, + YarnException, InterruptedException, IOException { init(); UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true); @@ -2601,8 +2548,8 @@ public class RMWebServices extends WebServices { + " by remote user " + userName; return Response.status(Status.FORBIDDEN).entity(msg).build(); } else if (ye.getCause() instanceof ParseException) { - return Response.status(Status.BAD_REQUEST) - .entity(ye.getMessage()).build(); + return Response.status(Status.BAD_REQUEST).entity(ye.getMessage()) + .build(); } else { throw ue; }