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.api.records;
020    
021    import java.text.NumberFormat;
022    
023    import org.apache.hadoop.classification.InterfaceAudience.Private;
024    import org.apache.hadoop.classification.InterfaceAudience.Public;
025    import org.apache.hadoop.classification.InterfaceStability.Stable;
026    import org.apache.hadoop.classification.InterfaceStability.Unstable;
027    import 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
040    public 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    }