001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.hadoop.yarn.client.api;
020
021 import java.io.IOException;
022 import java.util.EnumSet;
023 import java.util.List;
024 import java.util.Map;
025 import java.util.Set;
026
027 import org.apache.hadoop.classification.InterfaceAudience;
028 import org.apache.hadoop.classification.InterfaceAudience.Private;
029 import org.apache.hadoop.classification.InterfaceAudience.Public;
030 import org.apache.hadoop.classification.InterfaceStability;
031 import org.apache.hadoop.classification.InterfaceStability.Unstable;
032 import org.apache.hadoop.io.Text;
033 import org.apache.hadoop.service.AbstractService;
034 import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
035 import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
036 import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest;
037 import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse;
038 import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest;
039 import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse;
040 import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest;
041 import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateResponse;
042 import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
043 import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
044 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
045 import org.apache.hadoop.yarn.api.records.ApplicationId;
046 import org.apache.hadoop.yarn.api.records.ApplicationReport;
047 import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
048 import org.apache.hadoop.yarn.api.records.ContainerId;
049 import org.apache.hadoop.yarn.api.records.ContainerReport;
050 import org.apache.hadoop.yarn.api.records.NodeId;
051 import org.apache.hadoop.yarn.api.records.NodeReport;
052 import org.apache.hadoop.yarn.api.records.NodeState;
053 import org.apache.hadoop.yarn.api.records.QueueInfo;
054 import org.apache.hadoop.yarn.api.records.QueueUserACLInfo;
055 import org.apache.hadoop.yarn.api.records.ReservationDefinition;
056 import org.apache.hadoop.yarn.api.records.ReservationId;
057 import org.apache.hadoop.yarn.api.records.Token;
058 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
059 import org.apache.hadoop.yarn.api.records.YarnClusterMetrics;
060 import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl;
061 import org.apache.hadoop.yarn.exceptions.ApplicationIdNotProvidedException;
062 import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
063 import org.apache.hadoop.yarn.exceptions.YarnException;
064 import org.apache.hadoop.yarn.security.AMRMTokenIdentifier;
065
066 @InterfaceAudience.Public
067 @InterfaceStability.Stable
068 public abstract class YarnClient extends AbstractService {
069
070 /**
071 * Create a new instance of YarnClient.
072 */
073 @Public
074 public static YarnClient createYarnClient() {
075 YarnClient client = new YarnClientImpl();
076 return client;
077 }
078
079 @Private
080 protected YarnClient(String name) {
081 super(name);
082 }
083
084 /**
085 * <p>
086 * Obtain a {@link YarnClientApplication} for a new application,
087 * which in turn contains the {@link ApplicationSubmissionContext} and
088 * {@link org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse}
089 * objects.
090 * </p>
091 *
092 * @return {@link YarnClientApplication} built for a new application
093 * @throws YarnException
094 * @throws IOException
095 */
096 public abstract YarnClientApplication createApplication()
097 throws YarnException, IOException;
098
099 /**
100 * <p>
101 * Submit a new application to <code>YARN.</code> It is a blocking call - it
102 * will not return {@link ApplicationId} until the submitted application is
103 * submitted successfully and accepted by the ResourceManager.
104 * </p>
105 *
106 * <p>
107 * Users should provide an {@link ApplicationId} as part of the parameter
108 * {@link ApplicationSubmissionContext} when submitting a new application,
109 * otherwise it will throw the {@link ApplicationIdNotProvidedException}.
110 * </p>
111 *
112 * <p>This internally calls {@link ApplicationClientProtocol#submitApplication
113 * (SubmitApplicationRequest)}, and after that, it internally invokes
114 * {@link ApplicationClientProtocol#getApplicationReport
115 * (GetApplicationReportRequest)} and waits till it can make sure that the
116 * application gets properly submitted. If RM fails over or RM restart
117 * happens before ResourceManager saves the application's state,
118 * {@link ApplicationClientProtocol
119 * #getApplicationReport(GetApplicationReportRequest)} will throw
120 * the {@link ApplicationNotFoundException}. This API automatically resubmits
121 * the application with the same {@link ApplicationSubmissionContext} when it
122 * catches the {@link ApplicationNotFoundException}</p>
123 *
124 * @param appContext
125 * {@link ApplicationSubmissionContext} containing all the details
126 * needed to submit a new application
127 * @return {@link ApplicationId} of the accepted application
128 * @throws YarnException
129 * @throws IOException
130 * @see #createApplication()
131 */
132 public abstract ApplicationId submitApplication(
133 ApplicationSubmissionContext appContext) throws YarnException,
134 IOException;
135
136 /**
137 * <p>
138 * Kill an application identified by given ID.
139 * </p>
140 *
141 * @param applicationId
142 * {@link ApplicationId} of the application that needs to be killed
143 * @throws YarnException
144 * in case of errors or if YARN rejects the request due to
145 * access-control restrictions.
146 * @throws IOException
147 * @see #getQueueAclsInfo()
148 */
149 public abstract void killApplication(ApplicationId applicationId) throws YarnException,
150 IOException;
151
152 /**
153 * <p>
154 * Get a report of the given Application.
155 * </p>
156 *
157 * <p>
158 * In secure mode, <code>YARN</code> verifies access to the application, queue
159 * etc. before accepting the request.
160 * </p>
161 *
162 * <p>
163 * If the user does not have <code>VIEW_APP</code> access then the following
164 * fields in the report will be set to stubbed values:
165 * <ul>
166 * <li>host - set to "N/A"</li>
167 * <li>RPC port - set to -1</li>
168 * <li>client token - set to "N/A"</li>
169 * <li>diagnostics - set to "N/A"</li>
170 * <li>tracking URL - set to "N/A"</li>
171 * <li>original tracking URL - set to "N/A"</li>
172 * <li>resource usage report - all values are -1</li>
173 * </ul>
174 * </p>
175 *
176 * @param appId
177 * {@link ApplicationId} of the application that needs a report
178 * @return application report
179 * @throws YarnException
180 * @throws IOException
181 */
182 public abstract ApplicationReport getApplicationReport(ApplicationId appId)
183 throws YarnException, IOException;
184
185 /**
186 * Get the AMRM token of the application.
187 * <p/>
188 * The AMRM token is required for AM to RM scheduling operations. For
189 * managed Application Masters Yarn takes care of injecting it. For unmanaged
190 * Applications Masters, the token must be obtained via this method and set
191 * in the {@link org.apache.hadoop.security.UserGroupInformation} of the
192 * current user.
193 * <p/>
194 * The AMRM token will be returned only if all the following conditions are
195 * met:
196 * <li>
197 * <ul>the requester is the owner of the ApplicationMaster</ul>
198 * <ul>the application master is an unmanaged ApplicationMaster</ul>
199 * <ul>the application master is in ACCEPTED state</ul>
200 * </li>
201 * Else this method returns NULL.
202 *
203 * @param appId {@link ApplicationId} of the application to get the AMRM token
204 * @return the AMRM token if available
205 * @throws YarnException
206 * @throws IOException
207 */
208 public abstract org.apache.hadoop.security.token.Token<AMRMTokenIdentifier>
209 getAMRMToken(ApplicationId appId) throws YarnException, IOException;
210
211 /**
212 * <p>
213 * Get a report (ApplicationReport) of all Applications in the cluster.
214 * </p>
215 *
216 * <p>
217 * If the user does not have <code>VIEW_APP</code> access for an application
218 * then the corresponding report will be filtered as described in
219 * {@link #getApplicationReport(ApplicationId)}.
220 * </p>
221 *
222 * @return a list of reports of all running applications
223 * @throws YarnException
224 * @throws IOException
225 */
226 public abstract List<ApplicationReport> getApplications()
227 throws YarnException, IOException;
228
229 /**
230 * <p>
231 * Get a report (ApplicationReport) of Applications
232 * matching the given application types in the cluster.
233 * </p>
234 *
235 * <p>
236 * If the user does not have <code>VIEW_APP</code> access for an application
237 * then the corresponding report will be filtered as described in
238 * {@link #getApplicationReport(ApplicationId)}.
239 * </p>
240 *
241 * @param applicationTypes
242 * @return a list of reports of applications
243 * @throws YarnException
244 * @throws IOException
245 */
246 public abstract List<ApplicationReport> getApplications(
247 Set<String> applicationTypes) throws YarnException, IOException;
248
249 /**
250 * <p>
251 * Get a report (ApplicationReport) of Applications matching the given
252 * application states in the cluster.
253 * </p>
254 *
255 * <p>
256 * If the user does not have <code>VIEW_APP</code> access for an application
257 * then the corresponding report will be filtered as described in
258 * {@link #getApplicationReport(ApplicationId)}.
259 * </p>
260 *
261 * @param applicationStates
262 * @return a list of reports of applications
263 * @throws YarnException
264 * @throws IOException
265 */
266 public abstract List<ApplicationReport>
267 getApplications(EnumSet<YarnApplicationState> applicationStates)
268 throws YarnException, IOException;
269
270 /**
271 * <p>
272 * Get a report (ApplicationReport) of Applications matching the given
273 * application types and application states in the cluster.
274 * </p>
275 *
276 * <p>
277 * If the user does not have <code>VIEW_APP</code> access for an application
278 * then the corresponding report will be filtered as described in
279 * {@link #getApplicationReport(ApplicationId)}.
280 * </p>
281 *
282 * @param applicationTypes
283 * @param applicationStates
284 * @return a list of reports of applications
285 * @throws YarnException
286 * @throws IOException
287 */
288 public abstract List<ApplicationReport> getApplications(
289 Set<String> applicationTypes,
290 EnumSet<YarnApplicationState> applicationStates) throws YarnException,
291 IOException;
292
293 /**
294 * <p>
295 * Get metrics ({@link YarnClusterMetrics}) about the cluster.
296 * </p>
297 *
298 * @return cluster metrics
299 * @throws YarnException
300 * @throws IOException
301 */
302 public abstract YarnClusterMetrics getYarnClusterMetrics() throws YarnException,
303 IOException;
304
305 /**
306 * <p>
307 * Get a report of nodes ({@link NodeReport}) in the cluster.
308 * </p>
309 *
310 * @param states The {@link NodeState}s to filter on. If no filter states are
311 * given, nodes in all states will be returned.
312 * @return A list of node reports
313 * @throws YarnException
314 * @throws IOException
315 */
316 public abstract List<NodeReport> getNodeReports(NodeState... states)
317 throws YarnException, IOException;
318
319 /**
320 * <p>
321 * Get a delegation token so as to be able to talk to YARN using those tokens.
322 *
323 * @param renewer
324 * Address of the renewer who can renew these tokens when needed by
325 * securely talking to YARN.
326 * @return a delegation token ({@link Token}) that can be used to
327 * talk to YARN
328 * @throws YarnException
329 * @throws IOException
330 */
331 public abstract Token getRMDelegationToken(Text renewer)
332 throws YarnException, IOException;
333
334 /**
335 * <p>
336 * Get information ({@link QueueInfo}) about a given <em>queue</em>.
337 * </p>
338 *
339 * @param queueName
340 * Name of the queue whose information is needed
341 * @return queue information
342 * @throws YarnException
343 * in case of errors or if YARN rejects the request due to
344 * access-control restrictions.
345 * @throws IOException
346 */
347 public abstract QueueInfo getQueueInfo(String queueName) throws YarnException,
348 IOException;
349
350 /**
351 * <p>
352 * Get information ({@link QueueInfo}) about all queues, recursively if there
353 * is a hierarchy
354 * </p>
355 *
356 * @return a list of queue-information for all queues
357 * @throws YarnException
358 * @throws IOException
359 */
360 public abstract List<QueueInfo> getAllQueues() throws YarnException, IOException;
361
362 /**
363 * <p>
364 * Get information ({@link QueueInfo}) about top level queues.
365 * </p>
366 *
367 * @return a list of queue-information for all the top-level queues
368 * @throws YarnException
369 * @throws IOException
370 */
371 public abstract List<QueueInfo> getRootQueueInfos() throws YarnException, IOException;
372
373 /**
374 * <p>
375 * Get information ({@link QueueInfo}) about all the immediate children queues
376 * of the given queue
377 * </p>
378 *
379 * @param parent
380 * Name of the queue whose child-queues' information is needed
381 * @return a list of queue-information for all queues who are direct children
382 * of the given parent queue.
383 * @throws YarnException
384 * @throws IOException
385 */
386 public abstract List<QueueInfo> getChildQueueInfos(String parent) throws YarnException,
387 IOException;
388
389 /**
390 * <p>
391 * Get information about <em>acls</em> for <em>current user</em> on all the
392 * existing queues.
393 * </p>
394 *
395 * @return a list of queue acls ({@link QueueUserACLInfo}) for
396 * <em>current user</em>
397 * @throws YarnException
398 * @throws IOException
399 */
400 public abstract List<QueueUserACLInfo> getQueueAclsInfo() throws YarnException,
401 IOException;
402
403 /**
404 * <p>
405 * Get a report of the given ApplicationAttempt.
406 * </p>
407 *
408 * <p>
409 * In secure mode, <code>YARN</code> verifies access to the application, queue
410 * etc. before accepting the request.
411 * </p>
412 *
413 * @param applicationAttemptId
414 * {@link ApplicationAttemptId} of the application attempt that needs
415 * a report
416 * @return application attempt report
417 * @throws YarnException
418 * @throws {@link ApplicationAttemptNotFoundException} if application attempt
419 * not found
420 * @throws IOException
421 */
422 public abstract ApplicationAttemptReport getApplicationAttemptReport(
423 ApplicationAttemptId applicationAttemptId) throws YarnException, IOException;
424
425 /**
426 * <p>
427 * Get a report of all (ApplicationAttempts) of Application in the cluster.
428 * </p>
429 *
430 * @param applicationId
431 * @return a list of reports for all application attempts for specified
432 * application.
433 * @throws YarnException
434 * @throws IOException
435 */
436 public abstract List<ApplicationAttemptReport> getApplicationAttempts(
437 ApplicationId applicationId) throws YarnException, IOException;
438
439 /**
440 * <p>
441 * Get a report of the given Container.
442 * </p>
443 *
444 * <p>
445 * In secure mode, <code>YARN</code> verifies access to the application, queue
446 * etc. before accepting the request.
447 * </p>
448 *
449 * @param containerId
450 * {@link ContainerId} of the container that needs a report
451 * @return container report
452 * @throws YarnException
453 * @throws {@link ContainerNotFoundException} if container not found.
454 * @throws IOException
455 */
456 public abstract ContainerReport getContainerReport(ContainerId containerId)
457 throws YarnException, IOException;
458
459 /**
460 * <p>
461 * Get a report of all (Containers) of ApplicationAttempt in the cluster.
462 * </p>
463 *
464 * @param applicationAttemptId
465 * @return a list of reports of all containers for specified application
466 * attempts
467 * @throws YarnException
468 * @throws IOException
469 */
470 public abstract List<ContainerReport> getContainers(
471 ApplicationAttemptId applicationAttemptId) throws YarnException,
472 IOException;
473
474 /**
475 * <p>
476 * Attempts to move the given application to the given queue.
477 * </p>
478 *
479 * @param appId
480 * Application to move.
481 * @param queue
482 * Queue to place it in to.
483 * @throws YarnException
484 * @throws IOException
485 */
486 public abstract void moveApplicationAcrossQueues(ApplicationId appId,
487 String queue) throws YarnException, IOException;
488
489 /**
490 * <p>
491 * The interface used by clients to submit a new reservation to the
492 * {@code ResourceManager}.
493 * </p>
494 *
495 * <p>
496 * The client packages all details of its request in a
497 * {@link ReservationSubmissionRequest} object. This contains information
498 * about the amount of capacity, temporal constraints, and gang needs.
499 * Furthermore, the reservation might be composed of multiple stages, with
500 * ordering dependencies among them.
501 * </p>
502 *
503 * <p>
504 * In order to respond, a new admission control component in the
505 * {@code ResourceManager} performs an analysis of the resources that have
506 * been committed over the period of time the user is requesting, verify that
507 * the user requests can be fulfilled, and that it respect a sharing policy
508 * (e.g., {@code CapacityOverTimePolicy}). Once it has positively determined
509 * that the ReservationRequest is satisfiable the {@code ResourceManager}
510 * answers with a {@link ReservationSubmissionResponse} that includes a
511 * {@link ReservationId}. Upon failure to find a valid allocation the response
512 * is an exception with the message detailing the reason of failure.
513 * </p>
514 *
515 * <p>
516 * The semantics guarantees that the {@link ReservationId} returned,
517 * corresponds to a valid reservation existing in the time-range request by
518 * the user. The amount of capacity dedicated to such reservation can vary
519 * overtime, depending of the allocation that has been determined. But it is
520 * guaranteed to satisfy all the constraint expressed by the user in the
521 * {@link ReservationDefinition}
522 * </p>
523 *
524 * @param request request to submit a new Reservation
525 * @return response contains the {@link ReservationId} on accepting the
526 * submission
527 * @throws YarnException if the reservation cannot be created successfully
528 * @throws IOException
529 *
530 */
531 @Public
532 @Unstable
533 public abstract ReservationSubmissionResponse submitReservation(
534 ReservationSubmissionRequest request) throws YarnException, IOException;
535
536 /**
537 * <p>
538 * The interface used by clients to update an existing Reservation. This is
539 * referred to as a re-negotiation process, in which a user that has
540 * previously submitted a Reservation.
541 * </p>
542 *
543 * <p>
544 * The allocation is attempted by virtually substituting all previous
545 * allocations related to this Reservation with new ones, that satisfy the new
546 * {@link ReservationDefinition}. Upon success the previous allocation is
547 * atomically substituted by the new one, and on failure (i.e., if the system
548 * cannot find a valid allocation for the updated request), the previous
549 * allocation remains valid.
550 * </p>
551 *
552 * @param request to update an existing Reservation (the
553 * {@link ReservationUpdateRequest} should refer to an existing valid
554 * {@link ReservationId})
555 * @return response empty on successfully updating the existing reservation
556 * @throws YarnException if the request is invalid or reservation cannot be
557 * updated successfully
558 * @throws IOException
559 *
560 */
561 @Public
562 @Unstable
563 public abstract ReservationUpdateResponse updateReservation(
564 ReservationUpdateRequest request) throws YarnException, IOException;
565
566 /**
567 * <p>
568 * The interface used by clients to remove an existing Reservation.
569 * </p>
570 *
571 * @param request to remove an existing Reservation (the
572 * {@link ReservationDeleteRequest} should refer to an existing valid
573 * {@link ReservationId})
574 * @return response empty on successfully deleting the existing reservation
575 * @throws YarnException if the request is invalid or reservation cannot be
576 * deleted successfully
577 * @throws IOException
578 *
579 */
580 @Public
581 @Unstable
582 public abstract ReservationDeleteResponse deleteReservation(
583 ReservationDeleteRequest request) throws YarnException, IOException;
584
585 /**
586 * <p>
587 * The interface used by client to get node to labels mappings in existing cluster
588 * </p>
589 *
590 * @return node to labels mappings
591 * @throws YarnException
592 * @throws IOException
593 */
594 @Public
595 @Unstable
596 public abstract Map<NodeId, Set<String>> getNodeToLabels()
597 throws YarnException, IOException;
598
599 /**
600 * <p>
601 * The interface used by client to get node labels in the cluster
602 * </p>
603 *
604 * @return cluster node labels collection
605 * @throws YarnException
606 * @throws IOException
607 */
608 @Public
609 @Unstable
610 public abstract Set<String> getClusterNodeLabels()
611 throws YarnException, IOException;
612 }