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.api.records;
020
021import java.text.NumberFormat;
022
023import org.apache.hadoop.classification.InterfaceAudience.Private;
024import org.apache.hadoop.classification.InterfaceAudience.Public;
025import org.apache.hadoop.classification.InterfaceStability.Stable;
026import org.apache.hadoop.classification.InterfaceStability.Unstable;
027import org.apache.hadoop.yarn.util.Records;
028
029/**
030 * <p><code>ApplicationId</code> represents the <em>globally unique</em> 
031 * identifier for an application.</p>
032 * 
033 * <p>The globally unique nature of the identifier is achieved by using the 
034 * <em>cluster timestamp</em> i.e. start-time of the 
035 * <code>ResourceManager</code> along with a monotonically increasing counter
036 * for the application.</p>
037 */
038@Public
039@Stable
040public abstract class ApplicationId implements Comparable<ApplicationId> {
041
042  @Private
043  @Unstable
044  public static final String appIdStrPrefix = "application_";
045
046  @Private
047  @Unstable
048  public static ApplicationId newInstance(long clusterTimestamp, int id) {
049    ApplicationId appId = Records.newRecord(ApplicationId.class);
050    appId.setClusterTimestamp(clusterTimestamp);
051    appId.setId(id);
052    appId.build();
053    return appId;
054  }
055
056  /**
057   * Get the short integer identifier of the <code>ApplicationId</code>
058   * which is unique for all applications started by a particular instance
059   * of the <code>ResourceManager</code>.
060   * @return short integer identifier of the <code>ApplicationId</code>
061   */
062  @Public
063  @Stable
064  public abstract int getId();
065  
066  @Private
067  @Unstable
068  protected abstract void setId(int id);
069  
070  /**
071   * Get the <em>start time</em> of the <code>ResourceManager</code> which is 
072   * used to generate globally unique <code>ApplicationId</code>.
073   * @return <em>start time</em> of the <code>ResourceManager</code>
074   */
075  @Public
076  @Stable
077  public abstract long getClusterTimestamp();
078  
079  @Private
080  @Unstable
081  protected abstract void setClusterTimestamp(long clusterTimestamp);
082
083  protected abstract void build();
084  
085  static final ThreadLocal<NumberFormat> appIdFormat =
086    new ThreadLocal<NumberFormat>() {
087      @Override
088      public NumberFormat initialValue() {
089        NumberFormat fmt = NumberFormat.getInstance();
090        fmt.setGroupingUsed(false);
091        fmt.setMinimumIntegerDigits(4);
092        return fmt;
093      }
094    };
095
096  @Override
097  public int compareTo(ApplicationId other) {
098    if (this.getClusterTimestamp() - other.getClusterTimestamp() == 0) {
099      return this.getId() - other.getId();
100    } else {
101      return this.getClusterTimestamp() > other.getClusterTimestamp() ? 1 : 
102        this.getClusterTimestamp() < other.getClusterTimestamp() ? -1 : 0;
103    }
104  }
105
106  @Override
107  public String toString() {
108    return appIdStrPrefix + this.getClusterTimestamp() + "_"
109        + appIdFormat.get().format(getId());
110  }
111
112  @Override
113  public int hashCode() {
114    // Generated by eclipse.
115    final int prime = 371237;
116    int result = 6521;
117    long clusterTimestamp = getClusterTimestamp();
118    result = prime * result
119        + (int) (clusterTimestamp ^ (clusterTimestamp >>> 32));
120    result = prime * result + getId();
121    return result;
122  }
123
124  @Override
125  public boolean equals(Object obj) {
126    if (this == obj)
127      return true;
128    if (obj == null)
129      return false;
130    if (getClass() != obj.getClass())
131      return false;
132    ApplicationId other = (ApplicationId) obj;
133    if (this.getClusterTimestamp() != other.getClusterTimestamp())
134      return false;
135    if (this.getId() != other.getId())
136      return false;
137    return true;
138  }
139}