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.security; 020 021import java.io.DataInput; 022import java.io.DataInputStream; 023import java.io.DataOutput; 024import java.io.IOException; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.apache.hadoop.classification.InterfaceAudience; 029import org.apache.hadoop.classification.InterfaceAudience.Public; 030import org.apache.hadoop.classification.InterfaceStability.Evolving; 031import org.apache.hadoop.io.Text; 032import org.apache.hadoop.security.UserGroupInformation; 033import org.apache.hadoop.security.token.Token; 034import org.apache.hadoop.security.token.TokenIdentifier; 035import org.apache.hadoop.yarn.api.records.ContainerId; 036import org.apache.hadoop.yarn.api.records.LogAggregationContext; 037import org.apache.hadoop.yarn.api.records.Priority; 038import org.apache.hadoop.yarn.api.records.Resource; 039import org.apache.hadoop.yarn.api.records.impl.pb.ContainerIdPBImpl; 040import org.apache.hadoop.yarn.api.records.impl.pb.LogAggregationContextPBImpl; 041import org.apache.hadoop.yarn.api.records.impl.pb.PriorityPBImpl; 042import org.apache.hadoop.yarn.api.records.impl.pb.ResourcePBImpl; 043import org.apache.hadoop.yarn.proto.YarnSecurityTokenProtos.ContainerTokenIdentifierProto; 044 045import com.google.protobuf.TextFormat; 046 047 048/** 049 * TokenIdentifier for a container. Encodes {@link ContainerId}, 050 * {@link Resource} needed by the container and the target NMs host-address. 051 * 052 */ 053@Public 054@Evolving 055public class ContainerTokenIdentifier extends TokenIdentifier { 056 057 private static Log LOG = LogFactory.getLog(ContainerTokenIdentifier.class); 058 059 public static final Text KIND = new Text("ContainerToken"); 060 061 private ContainerTokenIdentifierProto proto; 062 063 public ContainerTokenIdentifier(ContainerId containerID, 064 String hostName, String appSubmitter, Resource r, long expiryTimeStamp, 065 int masterKeyId, long rmIdentifier, Priority priority, long creationTime) { 066 this(containerID, hostName, appSubmitter, r, expiryTimeStamp, masterKeyId, 067 rmIdentifier, priority, creationTime, null); 068 } 069 070 public ContainerTokenIdentifier(ContainerId containerID, String hostName, 071 String appSubmitter, Resource r, long expiryTimeStamp, int masterKeyId, 072 long rmIdentifier, Priority priority, long creationTime, 073 LogAggregationContext logAggregationContext) { 074 ContainerTokenIdentifierProto.Builder builder = 075 ContainerTokenIdentifierProto.newBuilder(); 076 if (containerID != null) { 077 builder.setContainerId(((ContainerIdPBImpl)containerID).getProto()); 078 } 079 builder.setNmHostAddr(hostName); 080 builder.setAppSubmitter(appSubmitter); 081 if (r != null) { 082 builder.setResource(((ResourcePBImpl)r).getProto()); 083 } 084 builder.setExpiryTimeStamp(expiryTimeStamp); 085 builder.setMasterKeyId(masterKeyId); 086 builder.setRmIdentifier(rmIdentifier); 087 if (priority != null) { 088 builder.setPriority(((PriorityPBImpl)priority).getProto()); 089 } 090 builder.setCreationTime(creationTime); 091 092 if (logAggregationContext != null) { 093 builder.setLogAggregationContext( 094 ((LogAggregationContextPBImpl)logAggregationContext).getProto()); 095 } 096 proto = builder.build(); 097 } 098 099 /** 100 * Default constructor needed by RPC layer/SecretManager. 101 */ 102 public ContainerTokenIdentifier() { 103 } 104 105 public ContainerId getContainerID() { 106 if (!proto.hasContainerId()) { 107 return null; 108 } 109 return new ContainerIdPBImpl(proto.getContainerId()); 110 } 111 112 public String getApplicationSubmitter() { 113 return proto.getAppSubmitter(); 114 } 115 116 public String getNmHostAddress() { 117 return proto.getNmHostAddr(); 118 } 119 120 public Resource getResource() { 121 if (!proto.hasResource()) { 122 return null; 123 } 124 return new ResourcePBImpl(proto.getResource()); 125 } 126 127 public long getExpiryTimeStamp() { 128 return proto.getExpiryTimeStamp(); 129 } 130 131 public int getMasterKeyId() { 132 return proto.getMasterKeyId(); 133 } 134 135 public Priority getPriority() { 136 if (!proto.hasPriority()) { 137 return null; 138 } 139 return new PriorityPBImpl(proto.getPriority()); 140 } 141 142 public long getCreationTime() { 143 return proto.getCreationTime(); 144 } 145 /** 146 * Get the RMIdentifier of RM in which containers are allocated 147 * @return RMIdentifier 148 */ 149 public long getRMIdentifier() { 150 return proto.getRmIdentifier(); 151 } 152 153 public ContainerTokenIdentifierProto getProto() { 154 return proto; 155 } 156 157 public LogAggregationContext getLogAggregationContext() { 158 if (!proto.hasLogAggregationContext()) { 159 return null; 160 } 161 return new LogAggregationContextPBImpl(proto.getLogAggregationContext()); 162 } 163 164 @Override 165 public void write(DataOutput out) throws IOException { 166 LOG.debug("Writing ContainerTokenIdentifier to RPC layer: " + this); 167 out.write(proto.toByteArray()); 168 } 169 170 @Override 171 public void readFields(DataInput in) throws IOException { 172 proto = ContainerTokenIdentifierProto.parseFrom((DataInputStream)in); 173 } 174 175 @Override 176 public Text getKind() { 177 return KIND; 178 } 179 180 @Override 181 public UserGroupInformation getUser() { 182 String containerId = null; 183 if (proto.hasContainerId()) { 184 containerId = new ContainerIdPBImpl(proto.getContainerId()).toString(); 185 } 186 return UserGroupInformation.createRemoteUser( 187 containerId); 188 } 189 190 // TODO: Needed? 191 @InterfaceAudience.Private 192 public static class Renewer extends Token.TrivialRenewer { 193 @Override 194 protected Text getKind() { 195 return KIND; 196 } 197 } 198 199 @Override 200 public int hashCode() { 201 return getProto().hashCode(); 202 } 203 204 @Override 205 public boolean equals(Object other) { 206 if (other == null) 207 return false; 208 if (other.getClass().isAssignableFrom(this.getClass())) { 209 return this.getProto().equals(this.getClass().cast(other).getProto()); 210 } 211 return false; 212 } 213 214 @Override 215 public String toString() { 216 return TextFormat.shortDebugString(getProto()); 217 } 218}