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.ReservationDeleteRequest;
036import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse;
037import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest;
038import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse;
039import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest;
040import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateResponse;
041import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
042import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
043import org.apache.hadoop.yarn.api.records.ApplicationId;
044import org.apache.hadoop.yarn.api.records.ApplicationReport;
045import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
046import org.apache.hadoop.yarn.api.records.ContainerId;
047import org.apache.hadoop.yarn.api.records.ContainerReport;
048import org.apache.hadoop.yarn.api.records.NodeId;
049import org.apache.hadoop.yarn.api.records.NodeReport;
050import org.apache.hadoop.yarn.api.records.NodeState;
051import org.apache.hadoop.yarn.api.records.QueueInfo;
052import org.apache.hadoop.yarn.api.records.QueueUserACLInfo;
053import org.apache.hadoop.yarn.api.records.ReservationDefinition;
054import org.apache.hadoop.yarn.api.records.ReservationId;
055import org.apache.hadoop.yarn.api.records.Token;
056import org.apache.hadoop.yarn.api.records.YarnApplicationState;
057import org.apache.hadoop.yarn.api.records.YarnClusterMetrics;
058import org.apache.hadoop.yarn.client.api.impl.YarnClientImpl;
059import org.apache.hadoop.yarn.exceptions.ApplicationAttemptNotFoundException;
060import org.apache.hadoop.yarn.exceptions.ApplicationIdNotProvidedException;
061import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
062import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
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   * 
175   * @param appId
176   *          {@link ApplicationId} of the application that needs a report
177   * @return application report
178   * @throws YarnException
179   * @throws IOException
180   */
181  public abstract ApplicationReport getApplicationReport(ApplicationId appId)
182      throws YarnException, IOException;
183
184  /**
185   * Get the AMRM token of the application.
186   * <p>
187   * The AMRM token is required for AM to RM scheduling operations. For 
188   * managed Application Masters Yarn takes care of injecting it. For unmanaged
189   * Applications Masters, the token must be obtained via this method and set
190   * in the {@link org.apache.hadoop.security.UserGroupInformation} of the
191   * current user.
192   * <p>
193   * The AMRM token will be returned only if all the following conditions are
194   * met:
195   * <ul>
196   *   <li>the requester is the owner of the ApplicationMaster</li>
197   *   <li>the application master is an unmanaged ApplicationMaster</li>
198   *   <li>the application master is in ACCEPTED state</li>
199   * </ul>
200   * Else this method returns NULL.
201   *
202   * @param appId {@link ApplicationId} of the application to get the AMRM token
203   * @return the AMRM token if available
204   * @throws YarnException
205   * @throws IOException
206   */
207  public abstract org.apache.hadoop.security.token.Token<AMRMTokenIdentifier>
208      getAMRMToken(ApplicationId appId) throws YarnException, IOException;
209
210  /**
211   * <p>
212   * Get a report (ApplicationReport) of all Applications in the cluster.
213   * </p>
214   *
215   * <p>
216   * If the user does not have <code>VIEW_APP</code> access for an application
217   * then the corresponding report will be filtered as described in
218   * {@link #getApplicationReport(ApplicationId)}.
219   * </p>
220   *
221   * @return a list of reports of all running applications
222   * @throws YarnException
223   * @throws IOException
224   */
225  public abstract List<ApplicationReport> getApplications()
226      throws YarnException, IOException;
227
228  /**
229   * <p>
230   * Get a report (ApplicationReport) of Applications
231   * matching the given application types in the cluster.
232   * </p>
233   *
234   * <p>
235   * If the user does not have <code>VIEW_APP</code> access for an application
236   * then the corresponding report will be filtered as described in
237   * {@link #getApplicationReport(ApplicationId)}.
238   * </p>
239   *
240   * @param applicationTypes
241   * @return a list of reports of applications
242   * @throws YarnException
243   * @throws IOException
244   */
245  public abstract List<ApplicationReport> getApplications(
246      Set<String> applicationTypes) throws YarnException, IOException;
247
248  /**
249   * <p>
250   * Get a report (ApplicationReport) of Applications matching the given
251   * application states in the cluster.
252   * </p>
253   *
254   * <p>
255   * If the user does not have <code>VIEW_APP</code> access for an application
256   * then the corresponding report will be filtered as described in
257   * {@link #getApplicationReport(ApplicationId)}.
258   * </p>
259   *
260   * @param applicationStates
261   * @return a list of reports of applications
262   * @throws YarnException
263   * @throws IOException
264   */
265  public abstract List<ApplicationReport>
266      getApplications(EnumSet<YarnApplicationState> applicationStates)
267          throws YarnException, IOException;
268
269  /**
270   * <p>
271   * Get a report (ApplicationReport) of Applications matching the given
272   * application types and application states in the cluster.
273   * </p>
274   *
275   * <p>
276   * If the user does not have <code>VIEW_APP</code> access for an application
277   * then the corresponding report will be filtered as described in
278   * {@link #getApplicationReport(ApplicationId)}.
279   * </p>
280   *
281   * @param applicationTypes
282   * @param applicationStates
283   * @return a list of reports of applications
284   * @throws YarnException
285   * @throws IOException
286   */
287  public abstract List<ApplicationReport> getApplications(
288      Set<String> applicationTypes,
289      EnumSet<YarnApplicationState> applicationStates) throws YarnException,
290      IOException;
291
292  /**
293   * <p>
294   * Get metrics ({@link YarnClusterMetrics}) about the cluster.
295   * </p>
296   * 
297   * @return cluster metrics
298   * @throws YarnException
299   * @throws IOException
300   */
301  public abstract YarnClusterMetrics getYarnClusterMetrics() throws YarnException,
302      IOException;
303
304  /**
305   * <p>
306   * Get a report of nodes ({@link NodeReport}) in the cluster.
307   * </p>
308   * 
309   * @param states The {@link NodeState}s to filter on. If no filter states are
310   *          given, nodes in all states will be returned.
311   * @return A list of node reports
312   * @throws YarnException
313   * @throws IOException
314   */
315  public abstract List<NodeReport> getNodeReports(NodeState... states)
316      throws YarnException, IOException;
317
318  /**
319   * <p>
320   * Get a delegation token so as to be able to talk to YARN using those tokens.
321   * 
322   * @param renewer
323   *          Address of the renewer who can renew these tokens when needed by
324   *          securely talking to YARN.
325   * @return a delegation token ({@link Token}) that can be used to
326   *         talk to YARN
327   * @throws YarnException
328   * @throws IOException
329   */
330  public abstract Token getRMDelegationToken(Text renewer)
331      throws YarnException, IOException;
332
333  /**
334   * <p>
335   * Get information ({@link QueueInfo}) about a given <em>queue</em>.
336   * </p>
337   * 
338   * @param queueName
339   *          Name of the queue whose information is needed
340   * @return queue information
341   * @throws YarnException
342   *           in case of errors or if YARN rejects the request due to
343   *           access-control restrictions.
344   * @throws IOException
345   */
346  public abstract QueueInfo getQueueInfo(String queueName) throws YarnException,
347      IOException;
348
349  /**
350   * <p>
351   * Get information ({@link QueueInfo}) about all queues, recursively if there
352   * is a hierarchy
353   * </p>
354   * 
355   * @return a list of queue-information for all queues
356   * @throws YarnException
357   * @throws IOException
358   */
359  public abstract List<QueueInfo> getAllQueues() throws YarnException, IOException;
360
361  /**
362   * <p>
363   * Get information ({@link QueueInfo}) about top level queues.
364   * </p>
365   * 
366   * @return a list of queue-information for all the top-level queues
367   * @throws YarnException
368   * @throws IOException
369   */
370  public abstract List<QueueInfo> getRootQueueInfos() throws YarnException, IOException;
371
372  /**
373   * <p>
374   * Get information ({@link QueueInfo}) about all the immediate children queues
375   * of the given queue
376   * </p>
377   * 
378   * @param parent
379   *          Name of the queue whose child-queues' information is needed
380   * @return a list of queue-information for all queues who are direct children
381   *         of the given parent queue.
382   * @throws YarnException
383   * @throws IOException
384   */
385  public abstract List<QueueInfo> getChildQueueInfos(String parent) throws YarnException,
386      IOException;
387
388  /**
389   * <p>
390   * Get information about <em>acls</em> for <em>current user</em> on all the
391   * existing queues.
392   * </p>
393   * 
394   * @return a list of queue acls ({@link QueueUserACLInfo}) for
395   *         <em>current user</em>
396   * @throws YarnException
397   * @throws IOException
398   */
399  public abstract List<QueueUserACLInfo> getQueueAclsInfo() throws YarnException,
400      IOException;
401  
402  /**
403   * <p>
404   * Get a report of the given ApplicationAttempt.
405   * </p>
406   * 
407   * <p>
408   * In secure mode, <code>YARN</code> verifies access to the application, queue
409   * etc. before accepting the request.
410   * </p>
411   * 
412   * @param applicationAttemptId
413   *          {@link ApplicationAttemptId} of the application attempt that needs
414   *          a report
415   * @return application attempt report
416   * @throws YarnException
417   * @throws ApplicationAttemptNotFoundException if application attempt
418   *         not found
419   * @throws IOException
420   */
421  public abstract ApplicationAttemptReport getApplicationAttemptReport(
422      ApplicationAttemptId applicationAttemptId) throws YarnException, IOException;
423
424  /**
425   * <p>
426   * Get a report of all (ApplicationAttempts) of Application in the cluster.
427   * </p>
428   * 
429   * @param applicationId
430   * @return a list of reports for all application attempts for specified
431   *         application.
432   * @throws YarnException
433   * @throws IOException
434   */
435  public abstract List<ApplicationAttemptReport> getApplicationAttempts(
436      ApplicationId applicationId) throws YarnException, IOException;
437
438  /**
439   * <p>
440   * Get a report of the given Container.
441   * </p>
442   * 
443   * <p>
444   * In secure mode, <code>YARN</code> verifies access to the application, queue
445   * etc. before accepting the request.
446   * </p>
447   * 
448   * @param containerId
449   *          {@link ContainerId} of the container that needs a report
450   * @return container report
451   * @throws YarnException
452   * @throws ContainerNotFoundException if container not found.
453   * @throws IOException
454   */
455  public abstract ContainerReport getContainerReport(ContainerId containerId)
456      throws YarnException, IOException;
457
458  /**
459   * <p>
460   * Get a report of all (Containers) of ApplicationAttempt in the cluster.
461   * </p>
462   * 
463   * @param applicationAttemptId
464   * @return a list of reports of all containers for specified application
465   *         attempts
466   * @throws YarnException
467   * @throws IOException
468   */
469  public abstract List<ContainerReport> getContainers(
470      ApplicationAttemptId applicationAttemptId) throws YarnException,
471      IOException;
472  
473  /**
474   * <p>
475   * Attempts to move the given application to the given queue.
476   * </p>
477   * 
478   * @param appId
479   *    Application to move.
480   * @param queue
481   *    Queue to place it in to.
482   * @throws YarnException
483   * @throws IOException
484   */
485  public abstract void moveApplicationAcrossQueues(ApplicationId appId,
486      String queue) throws YarnException, IOException;
487
488  /**
489   * <p>
490   * The interface used by clients to submit a new reservation to the
491   * {@code ResourceManager}.
492   * </p>
493   * 
494   * <p>
495   * The client packages all details of its request in a
496   * {@link ReservationSubmissionRequest} object. This contains information
497   * about the amount of capacity, temporal constraints, and gang needs.
498   * Furthermore, the reservation might be composed of multiple stages, with
499   * ordering dependencies among them.
500   * </p>
501   * 
502   * <p>
503   * In order to respond, a new admission control component in the
504   * {@code ResourceManager} performs an analysis of the resources that have
505   * been committed over the period of time the user is requesting, verify that
506   * the user requests can be fulfilled, and that it respect a sharing policy
507   * (e.g., {@code CapacityOverTimePolicy}). Once it has positively determined
508   * that the ReservationRequest is satisfiable the {@code ResourceManager}
509   * answers with a {@link ReservationSubmissionResponse} that includes a
510   * {@link ReservationId}. Upon failure to find a valid allocation the response
511   * is an exception with the message detailing the reason of failure.
512   * </p>
513   * 
514   * <p>
515   * The semantics guarantees that the {@link ReservationId} returned,
516   * corresponds to a valid reservation existing in the time-range request by
517   * the user. The amount of capacity dedicated to such reservation can vary
518   * overtime, depending of the allocation that has been determined. But it is
519   * guaranteed to satisfy all the constraint expressed by the user in the
520   * {@link ReservationDefinition}
521   * </p>
522   * 
523   * @param request request to submit a new Reservation
524   * @return response contains the {@link ReservationId} on accepting the
525   *         submission
526   * @throws YarnException if the reservation cannot be created successfully
527   * @throws IOException
528   * 
529   */
530  @Public
531  @Unstable
532  public abstract ReservationSubmissionResponse submitReservation(
533      ReservationSubmissionRequest request) throws YarnException, IOException;
534
535  /**
536   * <p>
537   * The interface used by clients to update an existing Reservation. This is
538   * referred to as a re-negotiation process, in which a user that has
539   * previously submitted a Reservation.
540   * </p>
541   * 
542   * <p>
543   * The allocation is attempted by virtually substituting all previous
544   * allocations related to this Reservation with new ones, that satisfy the new
545   * {@link ReservationDefinition}. Upon success the previous allocation is
546   * atomically substituted by the new one, and on failure (i.e., if the system
547   * cannot find a valid allocation for the updated request), the previous
548   * allocation remains valid.
549   * </p>
550   * 
551   * @param request to update an existing Reservation (the
552   *          {@link ReservationUpdateRequest} should refer to an existing valid
553   *          {@link ReservationId})
554   * @return response empty on successfully updating the existing reservation
555   * @throws YarnException if the request is invalid or reservation cannot be
556   *           updated successfully
557   * @throws IOException
558   * 
559   */
560  @Public
561  @Unstable
562  public abstract ReservationUpdateResponse updateReservation(
563      ReservationUpdateRequest request) throws YarnException, IOException;
564
565  /**
566   * <p>
567   * The interface used by clients to remove an existing Reservation.
568   * </p>
569   * 
570   * @param request to remove an existing Reservation (the
571   *          {@link ReservationDeleteRequest} should refer to an existing valid
572   *          {@link ReservationId})
573   * @return response empty on successfully deleting the existing reservation
574   * @throws YarnException if the request is invalid or reservation cannot be
575   *           deleted successfully
576   * @throws IOException
577   * 
578   */
579  @Public
580  @Unstable
581  public abstract ReservationDeleteResponse deleteReservation(
582      ReservationDeleteRequest request) throws YarnException, IOException;
583  
584  /**
585   * <p>
586   * The interface used by client to get node to labels mappings in existing cluster
587   * </p>
588   * 
589   * @return node to labels mappings
590   * @throws YarnException
591   * @throws IOException
592   */
593  @Public
594  @Unstable
595  public abstract Map<NodeId, Set<String>> getNodeToLabels()
596      throws YarnException, IOException;
597
598  /**
599   * <p>
600   * The interface used by client to get labels to nodes mapping
601   * in existing cluster
602   * </p>
603   *
604   * @return node to labels mappings
605   * @throws YarnException
606   * @throws IOException
607   */
608  @Public
609  @Unstable
610  public abstract Map<String, Set<NodeId>> getLabelsToNodes()
611      throws YarnException, IOException;
612
613  /**
614   * <p>
615   * The interface used by client to get labels to nodes mapping
616   * for specified labels in existing cluster
617   * </p>
618   *
619   * @param labels labels for which labels to nodes mapping has to be retrieved
620   * @return labels to nodes mappings for specific labels
621   * @throws YarnException
622   * @throws IOException
623   */
624  @Public
625  @Unstable
626  public abstract Map<String, Set<NodeId>> getLabelsToNodes(Set<String> labels)
627      throws YarnException, IOException;
628
629  /**
630   * <p>
631   * The interface used by client to get node labels in the cluster
632   * </p>
633   *
634   * @return cluster node labels collection
635   * @throws YarnException
636   * @throws IOException
637   */
638  @Public
639  @Unstable
640  public abstract Set<String> getClusterNodeLabels()
641      throws YarnException, IOException;
642}