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.security.client;
020    
021    import java.io.DataInput;
022    import java.io.DataInputStream;
023    import java.io.DataOutput;
024    import java.io.IOException;
025    
026    import org.apache.hadoop.classification.InterfaceAudience.Public;
027    import org.apache.hadoop.classification.InterfaceStability.Evolving;
028    import org.apache.hadoop.io.Text;
029    import org.apache.hadoop.security.UserGroupInformation;
030    import org.apache.hadoop.security.token.TokenIdentifier;
031    import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
032    import org.apache.hadoop.yarn.api.records.impl.pb.ApplicationAttemptIdPBImpl;
033    import org.apache.hadoop.yarn.proto.YarnSecurityTokenProtos.ClientToAMTokenIdentifierProto;
034    
035    import com.google.protobuf.TextFormat;
036    
037    
038    @Public
039    @Evolving
040    public class ClientToAMTokenIdentifier extends TokenIdentifier {
041    
042      public static final Text KIND_NAME = new Text("YARN_CLIENT_TOKEN");
043    
044      private ClientToAMTokenIdentifierProto proto;
045    
046      // TODO: Add more information in the tokenID such that it is not
047      // transferrable, more secure etc.
048    
049      public ClientToAMTokenIdentifier() {
050      }
051    
052      public ClientToAMTokenIdentifier(ApplicationAttemptId id, String client) {
053        ClientToAMTokenIdentifierProto.Builder builder = 
054            ClientToAMTokenIdentifierProto.newBuilder();
055        if (id != null) {
056          builder.setAppAttemptId(((ApplicationAttemptIdPBImpl)id).getProto());
057        }
058        if (client != null) {
059          builder.setClientName(client);
060        }
061        proto = builder.build();
062      }
063    
064      public ApplicationAttemptId getApplicationAttemptID() {
065        if (!proto.hasAppAttemptId()) {
066          return null;
067        }
068        return new ApplicationAttemptIdPBImpl(proto.getAppAttemptId());
069      }
070    
071      public String getClientName() {
072        return proto.getClientName();
073      }
074    
075      public ClientToAMTokenIdentifierProto getProto() {
076        return proto;
077      }
078      
079      @Override
080      public void write(DataOutput out) throws IOException {
081        out.write(proto.toByteArray());
082      }
083    
084      @Override
085      public void readFields(DataInput in) throws IOException {
086        proto = ClientToAMTokenIdentifierProto.parseFrom((DataInputStream)in);
087      }
088    
089      @Override
090      public Text getKind() {
091        return KIND_NAME;
092      }
093    
094      @Override
095      public UserGroupInformation getUser() {
096        String clientName = getClientName();
097        if (clientName == null) {
098          return null;
099        }
100        return UserGroupInformation.createRemoteUser(clientName);
101      }
102      
103      @Override
104      public int hashCode() {
105        return getProto().hashCode();
106      }
107    
108      @Override
109      public boolean equals(Object other) {
110        if (other == null)
111          return false;
112        if (other.getClass().isAssignableFrom(this.getClass())) {
113          return this.getProto().equals(this.getClass().cast(other).getProto());
114        }
115        return false;
116      }
117    
118      @Override
119      public String toString() {
120        return TextFormat.shortDebugString(getProto());
121      }
122    }