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
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}