1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package org.apache.hadoop.yarn.server.applicationhistoryservice.webapp;
20 
21 import java.util.Collections;
22 import java.util.Set;
23 
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26 import javax.ws.rs.GET;
27 import javax.ws.rs.Path;
28 import javax.ws.rs.PathParam;
29 import javax.ws.rs.Produces;
30 import javax.ws.rs.QueryParam;
31 import javax.ws.rs.core.Context;
32 import javax.ws.rs.core.MediaType;
33 
34 import org.apache.hadoop.util.StringUtils;
35 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
36 import org.apache.hadoop.yarn.api.ApplicationBaseProtocol;
37 import org.apache.hadoop.yarn.server.webapp.WebServices;
38 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
39 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptsInfo;
40 import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
41 import org.apache.hadoop.yarn.server.webapp.dao.AppsInfo;
42 import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
43 import org.apache.hadoop.yarn.server.webapp.dao.ContainersInfo;
44 import org.apache.hadoop.yarn.webapp.BadRequestException;
45 
46 import com.google.inject.Inject;
47 import com.google.inject.Singleton;
48 
49 @Singleton
50 @Path("/ws/v1/applicationhistory")
51 public class AHSWebServices extends WebServices {
52 
53   @Inject
AHSWebServices(ApplicationBaseProtocol appBaseProt)54   public AHSWebServices(ApplicationBaseProtocol appBaseProt) {
55     super(appBaseProt);
56   }
57 
58   @GET
59   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
get(@ontext HttpServletRequest req, @Context HttpServletResponse res)60   public AppsInfo get(@Context HttpServletRequest req,
61       @Context HttpServletResponse res) {
62     return getApps(req, res, null, Collections.<String> emptySet(), null, null,
63       null, null, null, null, null, null, Collections.<String> emptySet());
64   }
65 
66   @GET
67   @Path("/apps")
68   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
69   @Override
getApps(@ontext HttpServletRequest req, @Context HttpServletResponse res, @QueryParam(R) String stateQuery, @QueryParam(R) Set<String> statesQuery, @QueryParam(R) String finalStatusQuery, @QueryParam(R) String userQuery, @QueryParam(R) String queueQuery, @QueryParam(R) String count, @QueryParam(R) String startedBegin, @QueryParam(R) String startedEnd, @QueryParam(R) String finishBegin, @QueryParam(R) String finishEnd, @QueryParam(R) Set<String> applicationTypes)70   public AppsInfo getApps(@Context HttpServletRequest req,
71       @Context HttpServletResponse res, @QueryParam("state") String stateQuery,
72       @QueryParam("states") Set<String> statesQuery,
73       @QueryParam("finalStatus") String finalStatusQuery,
74       @QueryParam("user") String userQuery,
75       @QueryParam("queue") String queueQuery,
76       @QueryParam("limit") String count,
77       @QueryParam("startedTimeBegin") String startedBegin,
78       @QueryParam("startedTimeEnd") String startedEnd,
79       @QueryParam("finishedTimeBegin") String finishBegin,
80       @QueryParam("finishedTimeEnd") String finishEnd,
81       @QueryParam("applicationTypes") Set<String> applicationTypes) {
82     init(res);
83     validateStates(stateQuery, statesQuery);
84     return super.getApps(req, res, stateQuery, statesQuery, finalStatusQuery,
85       userQuery, queueQuery, count, startedBegin, startedEnd, finishBegin,
86       finishEnd, applicationTypes);
87   }
88 
89   @GET
90   @Path("/apps/{appid}")
91   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
92   @Override
getApp(@ontext HttpServletRequest req, @Context HttpServletResponse res, @PathParam(R) String appId)93   public AppInfo getApp(@Context HttpServletRequest req,
94       @Context HttpServletResponse res, @PathParam("appid") String appId) {
95     init(res);
96     return super.getApp(req, res, appId);
97   }
98 
99   @GET
100   @Path("/apps/{appid}/appattempts")
101   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
102   @Override
getAppAttempts(@ontext HttpServletRequest req, @Context HttpServletResponse res, @PathParam(R) String appId)103   public AppAttemptsInfo getAppAttempts(@Context HttpServletRequest req,
104       @Context HttpServletResponse res, @PathParam("appid") String appId) {
105     init(res);
106     return super.getAppAttempts(req, res, appId);
107   }
108 
109   @GET
110   @Path("/apps/{appid}/appattempts/{appattemptid}")
111   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
112   @Override
getAppAttempt(@ontext HttpServletRequest req, @Context HttpServletResponse res, @PathParam(R) String appId, @PathParam(R) String appAttemptId)113   public AppAttemptInfo getAppAttempt(@Context HttpServletRequest req,
114       @Context HttpServletResponse res, @PathParam("appid") String appId,
115       @PathParam("appattemptid") String appAttemptId) {
116     init(res);
117     return super.getAppAttempt(req, res, appId, appAttemptId);
118   }
119 
120   @GET
121   @Path("/apps/{appid}/appattempts/{appattemptid}/containers")
122   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
123   @Override
getContainers(@ontext HttpServletRequest req, @Context HttpServletResponse res, @PathParam(R) String appId, @PathParam(R) String appAttemptId)124   public ContainersInfo getContainers(@Context HttpServletRequest req,
125       @Context HttpServletResponse res, @PathParam("appid") String appId,
126       @PathParam("appattemptid") String appAttemptId) {
127     init(res);
128     return super.getContainers(req, res, appId, appAttemptId);
129   }
130 
131   @GET
132   @Path("/apps/{appid}/appattempts/{appattemptid}/containers/{containerid}")
133   @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
134   @Override
getContainer(@ontext HttpServletRequest req, @Context HttpServletResponse res, @PathParam(R) String appId, @PathParam(R) String appAttemptId, @PathParam(R) String containerId)135   public ContainerInfo getContainer(@Context HttpServletRequest req,
136       @Context HttpServletResponse res, @PathParam("appid") String appId,
137       @PathParam("appattemptid") String appAttemptId,
138       @PathParam("containerid") String containerId) {
139     init(res);
140     return super.getContainer(req, res, appId, appAttemptId, containerId);
141   }
142 
143   private static void
validateStates(String stateQuery, Set<String> statesQuery)144       validateStates(String stateQuery, Set<String> statesQuery) {
145     // stateQuery is deprecated.
146     if (stateQuery != null && !stateQuery.isEmpty()) {
147       statesQuery.add(stateQuery);
148     }
149     Set<String> appStates = parseQueries(statesQuery, true);
150     for (String appState : appStates) {
151       switch (YarnApplicationState.valueOf(
152           StringUtils.toUpperCase(appState))) {
153         case FINISHED:
154         case FAILED:
155         case KILLED:
156           continue;
157         default:
158           throw new BadRequestException("Invalid application-state " + appState
159               + " specified. It should be a final state");
160       }
161     }
162   }
163 
164 }