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    package org.apache.hadoop.mapreduce;
019    
020    import java.io.DataInput;
021    import java.io.DataOutput;
022    import java.io.IOException;
023    import java.util.HashMap;
024    import java.util.Map;
025    import java.util.Map.Entry;
026    
027    import org.apache.hadoop.classification.InterfaceAudience;
028    import org.apache.hadoop.classification.InterfaceStability;
029    import org.apache.hadoop.io.Text;
030    import org.apache.hadoop.io.Writable;
031    import org.apache.hadoop.io.WritableFactories;
032    import org.apache.hadoop.io.WritableFactory;
033    import org.apache.hadoop.io.WritableUtils;
034    import org.apache.hadoop.security.authorize.AccessControlList;
035    
036    /**************************************************
037     * Describes the current status of a job.
038     **************************************************/
039    @InterfaceAudience.Public
040    @InterfaceStability.Evolving
041    public class JobStatus implements Writable, Cloneable {
042    
043      static {                                      // register a ctor
044        WritableFactories.setFactory
045          (JobStatus.class,
046           new WritableFactory() {
047             public Writable newInstance() { return new JobStatus(); }
048           });
049      }
050    
051      /**
052       * Current state of the job 
053       */
054      public static enum State {
055        RUNNING(1),
056        SUCCEEDED(2),
057        FAILED(3),
058        PREP(4),
059        KILLED(5);
060        
061        int value;
062        
063        State(int value) {
064          this.value = value;
065        }
066        
067        public int getValue() {
068          return value; 
069        }
070        
071      };
072      
073      private JobID jobid;
074      private float mapProgress;
075      private float reduceProgress;
076      private float cleanupProgress;
077      private float setupProgress;
078      private State runState;
079      private long startTime;
080      private String user;
081      private String queue;
082      private JobPriority priority;
083      private String schedulingInfo="NA";
084      private String failureInfo = "NA";
085    
086      private Map<JobACL, AccessControlList> jobACLs =
087          new HashMap<JobACL, AccessControlList>();
088    
089      private String jobName;
090      private String jobFile;
091      private long finishTime;
092      private boolean isRetired;
093      private String historyFile = "";
094      private String trackingUrl ="";
095      private int numUsedSlots;
096      private int numReservedSlots;
097      private int usedMem;
098      private int reservedMem;
099      private int neededMem;
100      private boolean isUber;
101        
102      /**
103       */
104      public JobStatus() {
105      }
106    
107      /**
108       * Create a job status object for a given jobid.
109       * @param jobid The jobid of the job
110       * @param setupProgress The progress made on the setup
111       * @param mapProgress The progress made on the maps
112       * @param reduceProgress The progress made on the reduces
113       * @param cleanupProgress The progress made on the cleanup
114       * @param runState The current state of the job
115       * @param jp Priority of the job.
116       * @param user userid of the person who submitted the job.
117       * @param jobName user-specified job name.
118       * @param jobFile job configuration file.
119       * @param trackingUrl link to the web-ui for details of the job.
120       */
121       public JobStatus(JobID jobid, float setupProgress, float mapProgress,
122                        float reduceProgress, float cleanupProgress,
123                        State runState, JobPriority jp, String user, String jobName, 
124                        String jobFile, String trackingUrl) {
125         this(jobid, setupProgress, mapProgress, reduceProgress, cleanupProgress, 
126             runState, jp, user, jobName, "default", jobFile, trackingUrl, false);
127       }
128    
129       /**
130        * Create a job status object for a given jobid.
131        * @param jobid The jobid of the job
132        * @param setupProgress The progress made on the setup
133        * @param mapProgress The progress made on the maps
134        * @param reduceProgress The progress made on the reduces
135        * @param cleanupProgress The progress made on the cleanup
136        * @param runState The current state of the job
137        * @param jp Priority of the job.
138        * @param user userid of the person who submitted the job.
139        * @param jobName user-specified job name.
140        * @param queue queue name
141        * @param jobFile job configuration file.
142        * @param trackingUrl link to the web-ui for details of the job.
143        */
144        public JobStatus(JobID jobid, float setupProgress, float mapProgress,
145                         float reduceProgress, float cleanupProgress,
146                         State runState, JobPriority jp,
147                         String user, String jobName, String queue,
148                         String jobFile, String trackingUrl) {
149          this(jobid, setupProgress, mapProgress, reduceProgress, cleanupProgress,
150              runState, jp, user, jobName, queue, jobFile, trackingUrl, false);
151        }
152    
153       /**
154        * Create a job status object for a given jobid.
155        * @param jobid The jobid of the job
156        * @param setupProgress The progress made on the setup
157        * @param mapProgress The progress made on the maps
158        * @param reduceProgress The progress made on the reduces
159        * @param cleanupProgress The progress made on the cleanup
160        * @param runState The current state of the job
161        * @param jp Priority of the job.
162        * @param user userid of the person who submitted the job.
163        * @param jobName user-specified job name.
164        * @param queue queue name
165        * @param jobFile job configuration file.
166        * @param trackingUrl link to the web-ui for details of the job.
167        * @param isUber Whether job running in uber mode
168        */
169        public JobStatus(JobID jobid, float setupProgress, float mapProgress,
170                         float reduceProgress, float cleanupProgress,
171                         State runState, JobPriority jp,
172                         String user, String jobName, String queue,
173                         String jobFile, String trackingUrl, boolean isUber) {
174          this.jobid = jobid;
175          this.setupProgress = setupProgress;
176          this.mapProgress = mapProgress;
177          this.reduceProgress = reduceProgress;
178          this.cleanupProgress = cleanupProgress;
179          this.runState = runState;
180          this.user = user;
181          this.queue = queue;
182          if (jp == null) {
183            throw new IllegalArgumentException("Job Priority cannot be null.");
184          }
185          priority = jp;
186          this.jobName = jobName;
187          this.jobFile = jobFile;
188          this.trackingUrl = trackingUrl;
189          this.isUber = isUber;
190        }
191    
192    
193      /**
194       * Sets the map progress of this job
195       * @param p The value of map progress to set to
196       */
197      protected synchronized void setMapProgress(float p) { 
198        this.mapProgress = (float) Math.min(1.0, Math.max(0.0, p)); 
199      }
200    
201      /**
202       * Sets the cleanup progress of this job
203       * @param p The value of cleanup progress to set to
204       */
205      protected synchronized void setCleanupProgress(float p) { 
206        this.cleanupProgress = (float) Math.min(1.0, Math.max(0.0, p)); 
207      }
208    
209      /**
210       * Sets the setup progress of this job
211       * @param p The value of setup progress to set to
212       */
213      protected synchronized void setSetupProgress(float p) { 
214        this.setupProgress = (float) Math.min(1.0, Math.max(0.0, p)); 
215      }
216    
217      /**
218       * Sets the reduce progress of this Job
219       * @param p The value of reduce progress to set to
220       */
221      protected synchronized void setReduceProgress(float p) { 
222        this.reduceProgress = (float) Math.min(1.0, Math.max(0.0, p)); 
223      }
224        
225      /**
226       * Set the priority of the job, defaulting to NORMAL.
227       * @param jp new job priority
228       */
229      protected synchronized void setPriority(JobPriority jp) {
230        if (jp == null) {
231          throw new IllegalArgumentException("Job priority cannot be null.");
232        }
233        priority = jp;
234      }
235      
236      /** 
237       * Set the finish time of the job
238       * @param finishTime The finishTime of the job
239       */
240      protected synchronized void setFinishTime(long finishTime) {
241        this.finishTime = finishTime;
242      }
243    
244      /**
245       * Set the job history file url for a completed job
246       */
247      protected synchronized void setHistoryFile(String historyFile) {
248        this.historyFile = historyFile;
249      }
250    
251      /**
252       * Set the link to the web-ui for details of the job.
253       */
254      protected synchronized void setTrackingUrl(String trackingUrl) {
255        this.trackingUrl = trackingUrl;
256      }
257    
258      /**
259       * Set the job retire flag to true.
260       */
261      protected synchronized void setRetired() {
262        this.isRetired = true;
263      }
264    
265      /**
266       * Change the current run state of the job.
267       */
268      protected synchronized void setState(State state) {
269        this.runState = state;
270      }
271    
272      /** 
273       * Set the start time of the job
274       * @param startTime The startTime of the job
275       */
276      protected synchronized void setStartTime(long startTime) { 
277        this.startTime = startTime;
278      }
279        
280      /**
281       * @param userName The username of the job
282       */
283      protected synchronized void setUsername(String userName) { 
284        this.user = userName;
285      }
286    
287      /**
288       * Used to set the scheduling information associated to a particular Job.
289       * 
290       * @param schedulingInfo Scheduling information of the job
291       */
292      protected synchronized void setSchedulingInfo(String schedulingInfo) {
293        this.schedulingInfo = schedulingInfo;
294      }
295    
296      /**
297       * Set the job acls.
298       * 
299       * @param acls {@link Map} from {@link JobACL} to {@link AccessControlList}
300       */
301      protected synchronized void setJobACLs(Map<JobACL, AccessControlList> acls) {
302        this.jobACLs = acls;
303      }
304    
305      /**
306       * Set queue name
307       * @param queue queue name
308       */
309      protected synchronized void setQueue(String queue) {
310        this.queue = queue;
311      }
312    
313      /**
314       * Set diagnostic information.
315       * @param failureInfo diagnostic information
316       */
317      protected synchronized void setFailureInfo(String failureInfo) {
318        this.failureInfo = failureInfo;
319      }
320      
321      /**
322       * Get queue name
323       * @return queue name
324       */
325      public synchronized String getQueue() {
326        return queue;
327      }
328    
329      /**
330       * @return Percentage of progress in maps 
331       */
332      public synchronized float getMapProgress() { return mapProgress; }
333        
334      /**
335       * @return Percentage of progress in cleanup 
336       */
337      public synchronized float getCleanupProgress() { return cleanupProgress; }
338        
339      /**
340       * @return Percentage of progress in setup 
341       */
342      public synchronized float getSetupProgress() { return setupProgress; }
343        
344      /**
345       * @return Percentage of progress in reduce 
346       */
347      public synchronized float getReduceProgress() { return reduceProgress; }
348        
349      /**
350       * @return running state of the job
351       */
352      public synchronized State getState() { return runState; }
353        
354      /**
355       * @return start time of the job
356       */
357      synchronized public long getStartTime() { return startTime;}
358    
359      @Override
360      public Object clone() {
361        try {
362          return super.clone();
363        } catch (CloneNotSupportedException cnse) {
364          // Shouldn't happen since we do implement Clonable
365          throw new InternalError(cnse.toString());
366        }
367      }
368      
369      /**
370       * @return The jobid of the Job
371       */
372      public JobID getJobID() { return jobid; }
373        
374      /**
375       * @return the username of the job
376       */
377      public synchronized String getUsername() { return this.user;}
378      
379      /**
380       * Gets the Scheduling information associated to a particular Job.
381       * @return the scheduling information of the job
382       */
383      public synchronized String getSchedulingInfo() {
384       return schedulingInfo;
385      }
386    
387      /**
388       * Get the job acls.
389       * 
390       * @return a {@link Map} from {@link JobACL} to {@link AccessControlList}
391       */
392      public synchronized Map<JobACL, AccessControlList> getJobACLs() {
393        return jobACLs;
394      }
395    
396      /**
397       * Return the priority of the job
398       * @return job priority
399       */
400       public synchronized JobPriority getPriority() { return priority; }
401      
402       /**
403        * Gets any available info on the reason of failure of the job.
404        * @return diagnostic information on why a job might have failed.
405        */
406       public synchronized String getFailureInfo() {
407         return this.failureInfo;
408       }
409    
410    
411      /**
412       * Returns true if the status is for a completed job.
413       */
414      public synchronized boolean isJobComplete() {
415        return (runState == JobStatus.State.SUCCEEDED || 
416                runState == JobStatus.State.FAILED || 
417                runState == JobStatus.State.KILLED);
418      }
419    
420      ///////////////////////////////////////
421      // Writable
422      ///////////////////////////////////////
423      public synchronized void write(DataOutput out) throws IOException {
424        jobid.write(out);
425        out.writeFloat(setupProgress);
426        out.writeFloat(mapProgress);
427        out.writeFloat(reduceProgress);
428        out.writeFloat(cleanupProgress);
429        WritableUtils.writeEnum(out, runState);
430        out.writeLong(startTime);
431        Text.writeString(out, user);
432        WritableUtils.writeEnum(out, priority);
433        Text.writeString(out, schedulingInfo);
434        out.writeLong(finishTime);
435        out.writeBoolean(isRetired);
436        Text.writeString(out, historyFile);
437        Text.writeString(out, jobName);
438        Text.writeString(out, trackingUrl);
439        Text.writeString(out, jobFile);
440        out.writeBoolean(isUber);
441    
442        // Serialize the job's ACLs
443        out.writeInt(jobACLs.size());
444        for (Entry<JobACL, AccessControlList> entry : jobACLs.entrySet()) {
445          WritableUtils.writeEnum(out, entry.getKey());
446          entry.getValue().write(out);
447        }
448      }
449    
450      public synchronized void readFields(DataInput in) throws IOException {
451        this.jobid = new JobID();
452        this.jobid.readFields(in);
453        this.setupProgress = in.readFloat();
454        this.mapProgress = in.readFloat();
455        this.reduceProgress = in.readFloat();
456        this.cleanupProgress = in.readFloat();
457        this.runState = WritableUtils.readEnum(in, State.class);
458        this.startTime = in.readLong();
459        this.user = Text.readString(in);
460        this.priority = WritableUtils.readEnum(in, JobPriority.class);
461        this.schedulingInfo = Text.readString(in);
462        this.finishTime = in.readLong();
463        this.isRetired = in.readBoolean();
464        this.historyFile = Text.readString(in);
465        this.jobName = Text.readString(in);
466        this.trackingUrl = Text.readString(in);
467        this.jobFile = Text.readString(in);
468        this.isUber = in.readBoolean();
469    
470        // De-serialize the job's ACLs
471        int numACLs = in.readInt();
472        for (int i = 0; i < numACLs; i++) {
473          JobACL aclType = WritableUtils.readEnum(in, JobACL.class);
474          AccessControlList acl = new AccessControlList(" ");
475          acl.readFields(in);
476          this.jobACLs.put(aclType, acl);
477        }
478      }
479    
480      /**
481       * Get the user-specified job name.
482       */
483      public String getJobName() {
484        return jobName;
485      }
486    
487      /**
488       * Get the configuration file for the job.
489       */
490      public String getJobFile() {
491        return jobFile;
492      }
493    
494      /**
495       * Get the link to the web-ui for details of the job.
496       */
497      public synchronized String getTrackingUrl() {
498        return trackingUrl;
499      }
500    
501      /**
502       * Get the finish time of the job.
503       */
504      public synchronized long getFinishTime() { 
505        return finishTime;
506      }
507    
508      /**
509       * Check whether the job has retired.
510       */
511      public synchronized boolean isRetired() {
512        return isRetired;
513      }
514    
515      /**
516       * @return the job history file name for a completed job. If job is not 
517       * completed or history file not available then return null.
518       */
519      public synchronized String getHistoryFile() {
520        return historyFile;
521      }
522    
523      /**
524       * @return number of used mapred slots
525       */
526      public int getNumUsedSlots() {
527        return numUsedSlots;
528      }
529    
530      /**
531       * @param n number of used mapred slots
532       */
533      public void setNumUsedSlots(int n) {
534        numUsedSlots = n;
535      }
536    
537      /**
538       * @return the number of reserved slots
539       */
540      public int getNumReservedSlots() {
541        return numReservedSlots;
542      }
543    
544      /**
545       * @param n the number of reserved slots
546       */
547      public void setNumReservedSlots(int n) {
548        this.numReservedSlots = n;
549      }
550    
551      /**
552       * @return the used memory
553       */
554      public int getUsedMem() {
555        return usedMem;
556      }
557    
558      /**
559       * @param m the used memory
560       */
561      public void setUsedMem(int m) {
562        this.usedMem = m;
563      }
564    
565      /**
566       * @return the reserved memory
567       */
568      public int getReservedMem() {
569        return reservedMem;
570     }
571    
572      /**
573       * @param r the reserved memory
574       */
575      public void setReservedMem(int r) {
576        this.reservedMem = r;
577      }
578    
579      /**
580       * @return the needed memory
581       */
582      public int getNeededMem() {
583      return neededMem;
584     }
585    
586      /**
587       * @param n the needed memory
588       */
589      public void setNeededMem(int n) {
590        this.neededMem = n;
591      }
592    
593      /**
594       * Whether job running in uber mode
595       * @return job in uber-mode
596       */
597      public synchronized boolean isUber() {
598        return isUber;
599      }
600      
601      /**
602       * Set uber-mode flag 
603       * @param isUber Whether job running in uber-mode
604       */
605      public synchronized void setUber(boolean isUber) {
606        this.isUber = isUber;
607      }
608      
609      public String toString() {
610        StringBuffer buffer = new StringBuffer();
611        buffer.append("job-id : " + jobid);
612        buffer.append("uber-mode : " + isUber);
613        buffer.append("map-progress : " + mapProgress);
614        buffer.append("reduce-progress : " + reduceProgress);
615        buffer.append("cleanup-progress : " + cleanupProgress);
616        buffer.append("setup-progress : " + setupProgress);
617        buffer.append("runstate : " + runState);
618        buffer.append("start-time : " + startTime);
619        buffer.append("user-name : " + user);
620        buffer.append("priority : " + priority);
621        buffer.append("scheduling-info : " + schedulingInfo);
622        buffer.append("num-used-slots" + numUsedSlots);
623        buffer.append("num-reserved-slots" + numReservedSlots);
624        buffer.append("used-mem" + usedMem);
625        buffer.append("reserved-mem" + reservedMem);
626        buffer.append("needed-mem" + neededMem);
627        return buffer.toString();
628      }
629    }