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
019package org.apache.hadoop.yarn.client.api;
020
021import java.io.IOException;
022import java.util.EnumSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.hadoop.classification.InterfaceAudience;
028import org.apache.hadoop.classification.InterfaceAudience.Private;
029import org.apache.hadoop.classification.InterfaceAudience.Public;
030import org.apache.hadoop.classification.InterfaceStability;
031import org.apache.hadoop.classification.InterfaceStability.Unstable;
032import org.apache.hadoop.io.Text;
033import org.apache.hadoop.service.AbstractService;
034import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
035import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
036import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest;
037import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse;
038import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest;
039import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse;
040import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest;
041import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateResponse;
042import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
043import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
044import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
045import org.apache.hadoop.yarn.api.records.ApplicationId;
046import org.apache.hadoop.yarn.api.records.ApplicationReport;
047import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
048import org.apache.hadoop.yarn.api.records.ContainerId;
049import org.apache.hadoop.yarn.api.records.ContainerReport;
050import org.apache.hadoop.yarn.api.records.NodeId;
051import org.apache.hadoop.yarn.api.records.NodeReport;
052import org.apache.hadoop.yarn.api.records.NodeState;
053import org.apache.hadoop.yarn.api.records.QueueInfo;
054import org.apache.hadoop.yarn.api.records.QueueUserACLInfo;
055import org.apache.hadoop.yarn.api.records.ReservationDefinition;
056import org.apache.hadoop.yarn.api.records.ReservationId;
057import org.apache.hadoop.yarn.api.records.Token;
058import org.apache.hadoop.yarn.api.records.YarnApplicationState;
059import org.apache.hadoop.yarn.api.records.YarnClusterMetrics;
060import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl;
061import org.apache.hadoop.yarn.exceptions.ApplicationIdNotProvidedException;
062import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
063import org.apache.hadoop.yarn.exceptions.YarnException;
064import org.apache.hadoop.yarn.security.AMRMTokenIdentifier;
065
066@InterfaceAudience.Public
067@InterfaceStability.Stable
068public 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 set of application types you are interested in
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 set of application states you are interested in
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 set of application types you are interested in
283   * @param applicationStates set of application states you are interested in
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 a report (ApplicationReport) of Applications matching the given users,
296   * queues, application types and application states in the cluster. If any of
297   * the params is set to null, it is not used when filtering.
298   * </p>
299   *
300   * <p>
301   * If the user does not have <code>VIEW_APP</code> access for an application
302   * then the corresponding report will be filtered as described in
303   * {@link #getApplicationReport(ApplicationId)}.
304   * </p>
305   *
306   * @param queues set of queues you are interested in
307   * @param users set of users you are interested in
308   * @param applicationTypes set of application types you are interested in
309   * @param applicationStates set of application states you are interested in
310   * @return a list of reports of applications
311   * @throws YarnException
312   * @throws IOException
313   */
314  public abstract List<ApplicationReport> getApplications(Set<String> queues,
315      Set<String> users, Set<String> applicationTypes,
316      EnumSet<YarnApplicationState> applicationStates) throws YarnException,
317      IOException;
318
319  /**
320   * <p>
321   * Get metrics ({@link YarnClusterMetrics}) about the cluster.
322   * </p>
323   * 
324   * @return cluster metrics
325   * @throws YarnException
326   * @throws IOException
327   */
328  public abstract YarnClusterMetrics getYarnClusterMetrics() throws YarnException,
329      IOException;
330
331  /**
332   * <p>
333   * Get a report of nodes ({@link NodeReport}) in the cluster.
334   * </p>
335   * 
336   * @param states The {@link NodeState}s to filter on. If no filter states are
337   *          given, nodes in all states will be returned.
338   * @return A list of node reports
339   * @throws YarnException
340   * @throws IOException
341   */
342  public abstract List<NodeReport> getNodeReports(NodeState... states)
343      throws YarnException, IOException;
344
345  /**
346   * <p>
347   * Get a delegation token so as to be able to talk to YARN using those tokens.
348   * 
349   * @param renewer
350   *          Address of the renewer who can renew these tokens when needed by
351   *          securely talking to YARN.
352   * @return a delegation token ({@link Token}) that can be used to
353   *         talk to YARN
354   * @throws YarnException
355   * @throws IOException
356   */
357  public abstract Token getRMDelegationToken(Text renewer)
358      throws YarnException, IOException;
359
360  /**
361   * <p>
362   * Get information ({@link QueueInfo}) about a given <em>queue</em>.
363   * </p>
364   * 
365   * @param queueName
366   *          Name of the queue whose information is needed
367   * @return queue information
368   * @throws YarnException
369   *           in case of errors or if YARN rejects the request due to
370   *           access-control restrictions.
371   * @throws IOException
372   */
373  public abstract QueueInfo getQueueInfo(String queueName) throws YarnException,
374      IOException;
375
376  /**
377   * <p>
378   * Get information ({@link QueueInfo}) about all queues, recursively if there
379   * is a hierarchy
380   * </p>
381   * 
382   * @return a list of queue-information for all queues
383   * @throws YarnException
384   * @throws IOException
385   */
386  public abstract List<QueueInfo> getAllQueues() throws YarnException, IOException;
387
388  /**
389   * <p>
390   * Get information ({@link QueueInfo}) about top level queues.
391   * </p>
392   * 
393   * @return a list of queue-information for all the top-level queues
394   * @throws YarnException
395   * @throws IOException
396   */
397  public abstract List<QueueInfo> getRootQueueInfos() throws YarnException, IOException;
398
399  /**
400   * <p>
401   * Get information ({@link QueueInfo}) about all the immediate children queues
402   * of the given queue
403   * </p>
404   * 
405   * @param parent
406   *          Name of the queue whose child-queues' information is needed
407   * @return a list of queue-information for all queues who are direct children
408   *         of the given parent queue.
409   * @throws YarnException
410   * @throws IOException
411   */
412  public abstract List<QueueInfo> getChildQueueInfos(String parent) throws YarnException,
413      IOException;
414
415  /**
416   * <p>
417   * Get information about <em>acls</em> for <em>current user</em> on all the
418   * existing queues.
419   * </p>
420   * 
421   * @return a list of queue acls ({@link QueueUserACLInfo}) for
422   *         <em>current user</em>
423   * @throws YarnException
424   * @throws IOException
425   */
426  public abstract List<QueueUserACLInfo> getQueueAclsInfo() throws YarnException,
427      IOException;
428  
429  /**
430   * <p>
431   * Get a report of the given ApplicationAttempt.
432   * </p>
433   * 
434   * <p>
435   * In secure mode, <code>YARN</code> verifies access to the application, queue
436   * etc. before accepting the request.
437   * </p>
438   * 
439   * @param applicationAttemptId
440   *          {@link ApplicationAttemptId} of the application attempt that needs
441   *          a report
442   * @return application attempt report
443   * @throws YarnException
444   * @throws {@link ApplicationAttemptNotFoundException} if application attempt
445   *         not found
446   * @throws IOException
447   */
448  public abstract ApplicationAttemptReport getApplicationAttemptReport(
449      ApplicationAttemptId applicationAttemptId) throws YarnException, IOException;
450
451  /**
452   * <p>
453   * Get a report of all (ApplicationAttempts) of Application in the cluster.
454   * </p>
455   * 
456   * @param applicationId application id of the app
457   * @return a list of reports for all application attempts for specified
458   *         application.
459   * @throws YarnException
460   * @throws IOException
461   */
462  public abstract List<ApplicationAttemptReport> getApplicationAttempts(
463      ApplicationId applicationId) throws YarnException, IOException;
464
465  /**
466   * <p>
467   * Get a report of the given Container.
468   * </p>
469   * 
470   * <p>
471   * In secure mode, <code>YARN</code> verifies access to the application, queue
472   * etc. before accepting the request.
473   * </p>
474   * 
475   * @param containerId
476   *          {@link ContainerId} of the container that needs a report
477   * @return container report
478   * @throws YarnException
479   * @throws {@link ContainerNotFoundException} if container not found.
480   * @throws IOException
481   */
482  public abstract ContainerReport getContainerReport(ContainerId containerId)
483      throws YarnException, IOException;
484
485  /**
486   * <p>
487   * Get a report of all (Containers) of ApplicationAttempt in the cluster.
488   * </p>
489   * 
490   * @param applicationAttemptId application attempt id
491   * @return a list of reports of all containers for specified application
492   *         attempts
493   * @throws YarnException
494   * @throws IOException
495   */
496  public abstract List<ContainerReport> getContainers(
497      ApplicationAttemptId applicationAttemptId) throws YarnException,
498      IOException;
499  
500  /**
501   * <p>
502   * Attempts to move the given application to the given queue.
503   * </p>
504   * 
505   * @param appId
506   *    Application to move.
507   * @param queue
508   *    Queue to place it in to.
509   * @throws YarnException
510   * @throws IOException
511   */
512  public abstract void moveApplicationAcrossQueues(ApplicationId appId,
513      String queue) throws YarnException, IOException;
514
515  /**
516   * <p>
517   * The interface used by clients to submit a new reservation to the
518   * {@code ResourceManager}.
519   * </p>
520   * 
521   * <p>
522   * The client packages all details of its request in a
523   * {@link ReservationSubmissionRequest} object. This contains information
524   * about the amount of capacity, temporal constraints, and gang needs.
525   * Furthermore, the reservation might be composed of multiple stages, with
526   * ordering dependencies among them.
527   * </p>
528   * 
529   * <p>
530   * In order to respond, a new admission control component in the
531   * {@code ResourceManager} performs an analysis of the resources that have
532   * been committed over the period of time the user is requesting, verify that
533   * the user requests can be fulfilled, and that it respect a sharing policy
534   * (e.g., {@code CapacityOverTimePolicy}). Once it has positively determined
535   * that the ReservationRequest is satisfiable the {@code ResourceManager}
536   * answers with a {@link ReservationSubmissionResponse} that includes a
537   * {@link ReservationId}. Upon failure to find a valid allocation the response
538   * is an exception with the message detailing the reason of failure.
539   * </p>
540   * 
541   * <p>
542   * The semantics guarantees that the {@link ReservationId} returned,
543   * corresponds to a valid reservation existing in the time-range request by
544   * the user. The amount of capacity dedicated to such reservation can vary
545   * overtime, depending of the allocation that has been determined. But it is
546   * guaranteed to satisfy all the constraint expressed by the user in the
547   * {@link ReservationDefinition}
548   * </p>
549   * 
550   * @param request request to submit a new Reservation
551   * @return response contains the {@link ReservationId} on accepting the
552   *         submission
553   * @throws YarnException if the reservation cannot be created successfully
554   * @throws IOException
555   * 
556   */
557  @Public
558  @Unstable
559  public abstract ReservationSubmissionResponse submitReservation(
560      ReservationSubmissionRequest request) throws YarnException, IOException;
561
562  /**
563   * <p>
564   * The interface used by clients to update an existing Reservation. This is
565   * referred to as a re-negotiation process, in which a user that has
566   * previously submitted a Reservation.
567   * </p>
568   * 
569   * <p>
570   * The allocation is attempted by virtually substituting all previous
571   * allocations related to this Reservation with new ones, that satisfy the new
572   * {@link ReservationDefinition}. Upon success the previous allocation is
573   * atomically substituted by the new one, and on failure (i.e., if the system
574   * cannot find a valid allocation for the updated request), the previous
575   * allocation remains valid.
576   * </p>
577   * 
578   * @param request to update an existing Reservation (the
579   *          {@link ReservationUpdateRequest} should refer to an existing valid
580   *          {@link ReservationId})
581   * @return response empty on successfully updating the existing reservation
582   * @throws YarnException if the request is invalid or reservation cannot be
583   *           updated successfully
584   * @throws IOException
585   * 
586   */
587  @Public
588  @Unstable
589  public abstract ReservationUpdateResponse updateReservation(
590      ReservationUpdateRequest request) throws YarnException, IOException;
591
592  /**
593   * <p>
594   * The interface used by clients to remove an existing Reservation.
595   * </p>
596   * 
597   * @param request to remove an existing Reservation (the
598   *          {@link ReservationDeleteRequest} should refer to an existing valid
599   *          {@link ReservationId})
600   * @return response empty on successfully deleting the existing reservation
601   * @throws YarnException if the request is invalid or reservation cannot be
602   *           deleted successfully
603   * @throws IOException
604   * 
605   */
606  @Public
607  @Unstable
608  public abstract ReservationDeleteResponse deleteReservation(
609      ReservationDeleteRequest request) throws YarnException, IOException;
610  
611  /**
612   * <p>
613   * The interface used by client to get node to labels mappings in existing cluster
614   * </p>
615   * 
616   * @return node to labels mappings
617   * @throws YarnException
618   * @throws IOException
619   */
620  @Public
621  @Unstable
622  public abstract Map<NodeId, Set<String>> getNodeToLabels()
623      throws YarnException, IOException;
624
625  /**
626   * <p>
627   * The interface used by client to get node labels in the cluster
628   * </p>
629   *
630   * @return cluster node labels collection
631   * @throws YarnException
632   * @throws IOException
633   */
634  @Public
635  @Unstable
636  public abstract Set<String> getClusterNodeLabels()
637      throws YarnException, IOException;
638}