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    }