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.ProtoUtils; 043import org.apache.hadoop.yarn.api.records.impl.pb.ResourcePBImpl; 044import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; 045import org.apache.hadoop.yarn.proto.YarnProtos.ContainerTypeProto; 046import org.apache.hadoop.yarn.proto.YarnSecurityTokenProtos.ContainerTokenIdentifierProto; 047import org.apache.hadoop.yarn.server.api.ContainerType; 048 049import com.google.protobuf.TextFormat; 050 051/** 052 * TokenIdentifier for a container. Encodes {@link ContainerId}, 053 * {@link Resource} needed by the container and the target NMs host-address. 054 * 055 */ 056@Public 057@Evolving 058public class ContainerTokenIdentifier extends TokenIdentifier { 059 060 private static Log LOG = LogFactory.getLog(ContainerTokenIdentifier.class); 061 062 public static final Text KIND = new Text("ContainerToken"); 063 064 private ContainerTokenIdentifierProto proto; 065 066 public ContainerTokenIdentifier(ContainerId containerID, 067 String hostName, String appSubmitter, Resource r, long expiryTimeStamp, 068 int masterKeyId, long rmIdentifier, Priority priority, long creationTime) { 069 this(containerID, hostName, appSubmitter, r, expiryTimeStamp, masterKeyId, 070 rmIdentifier, priority, creationTime, null, 071 CommonNodeLabelsManager.NO_LABEL, ContainerType.TASK); 072 } 073 074 /** 075 * Creates a instance. 076 * 077 * @param appSubmitter appSubmitter 078 * @param containerID container ID 079 * @param creationTime creation time 080 * @param expiryTimeStamp expiry timestamp 081 * @param hostName hostname 082 * @param logAggregationContext log aggregation context 083 * @param masterKeyId master key ID 084 * @param priority priority 085 * @param r resource needed by the container 086 * @param rmIdentifier ResourceManager identifier 087 * @deprecated Use one of the other constructors instead. 088 */ 089 @Deprecated 090 public ContainerTokenIdentifier(ContainerId containerID, String hostName, 091 String appSubmitter, Resource r, long expiryTimeStamp, int masterKeyId, 092 long rmIdentifier, Priority priority, long creationTime, 093 LogAggregationContext logAggregationContext) { 094 this(containerID, hostName, appSubmitter, r, expiryTimeStamp, masterKeyId, 095 rmIdentifier, priority, creationTime, logAggregationContext, 096 CommonNodeLabelsManager.NO_LABEL); 097 } 098 099 public ContainerTokenIdentifier(ContainerId containerID, String hostName, 100 String appSubmitter, Resource r, long expiryTimeStamp, int masterKeyId, 101 long rmIdentifier, Priority priority, long creationTime, 102 LogAggregationContext logAggregationContext, String nodeLabelExpression) { 103 this(containerID, hostName, appSubmitter, r, expiryTimeStamp, masterKeyId, 104 rmIdentifier, priority, creationTime, logAggregationContext, 105 nodeLabelExpression, ContainerType.TASK); 106 } 107 108 public ContainerTokenIdentifier(ContainerId containerID, String hostName, 109 String appSubmitter, Resource r, long expiryTimeStamp, int masterKeyId, 110 long rmIdentifier, Priority priority, long creationTime, 111 LogAggregationContext logAggregationContext, String nodeLabelExpression, 112 ContainerType containerType) { 113 this(containerID, 0, hostName, appSubmitter, r, expiryTimeStamp, 114 masterKeyId, rmIdentifier, priority, creationTime, 115 logAggregationContext, nodeLabelExpression, containerType); 116 } 117 118 public ContainerTokenIdentifier(ContainerId containerID, int containerVersion, 119 String hostName, String appSubmitter, Resource r, long expiryTimeStamp, 120 int masterKeyId, long rmIdentifier, Priority priority, long creationTime, 121 LogAggregationContext logAggregationContext, String nodeLabelExpression, 122 ContainerType containerType) { 123 ContainerTokenIdentifierProto.Builder builder = 124 ContainerTokenIdentifierProto.newBuilder(); 125 if (containerID != null) { 126 builder.setContainerId(((ContainerIdPBImpl)containerID).getProto()); 127 } 128 builder.setVersion(containerVersion); 129 builder.setNmHostAddr(hostName); 130 builder.setAppSubmitter(appSubmitter); 131 if (r != null) { 132 builder.setResource(((ResourcePBImpl)r).getProto()); 133 } 134 builder.setExpiryTimeStamp(expiryTimeStamp); 135 builder.setMasterKeyId(masterKeyId); 136 builder.setRmIdentifier(rmIdentifier); 137 if (priority != null) { 138 builder.setPriority(((PriorityPBImpl)priority).getProto()); 139 } 140 builder.setCreationTime(creationTime); 141 142 if (logAggregationContext != null) { 143 builder.setLogAggregationContext( 144 ((LogAggregationContextPBImpl)logAggregationContext).getProto()); 145 } 146 147 if (nodeLabelExpression != null) { 148 builder.setNodeLabelExpression(nodeLabelExpression); 149 } 150 builder.setContainerType(convertToProtoFormat(containerType)); 151 152 proto = builder.build(); 153 } 154 155 /** 156 * Default constructor needed by RPC layer/SecretManager. 157 */ 158 public ContainerTokenIdentifier() { 159 } 160 161 public ContainerId getContainerID() { 162 if (!proto.hasContainerId()) { 163 return null; 164 } 165 return new ContainerIdPBImpl(proto.getContainerId()); 166 } 167 168 public String getApplicationSubmitter() { 169 return proto.getAppSubmitter(); 170 } 171 172 public String getNmHostAddress() { 173 return proto.getNmHostAddr(); 174 } 175 176 public Resource getResource() { 177 if (!proto.hasResource()) { 178 return null; 179 } 180 return new ResourcePBImpl(proto.getResource()); 181 } 182 183 public long getExpiryTimeStamp() { 184 return proto.getExpiryTimeStamp(); 185 } 186 187 public int getMasterKeyId() { 188 return proto.getMasterKeyId(); 189 } 190 191 public Priority getPriority() { 192 if (!proto.hasPriority()) { 193 return null; 194 } 195 return new PriorityPBImpl(proto.getPriority()); 196 } 197 198 public long getCreationTime() { 199 return proto.getCreationTime(); 200 } 201 /** 202 * Get the RMIdentifier of RM in which containers are allocated 203 * @return RMIdentifier 204 */ 205 public long getRMIdentifier() { 206 return proto.getRmIdentifier(); 207 } 208 209 /** 210 * Get the ContainerType of container to allocate. 211 * @return ContainerType 212 */ 213 public ContainerType getContainerType(){ 214 if (!proto.hasContainerType()) { 215 return null; 216 } 217 return convertFromProtoFormat(proto.getContainerType()); 218 } 219 220 public ContainerTokenIdentifierProto getProto() { 221 return proto; 222 } 223 224 public LogAggregationContext getLogAggregationContext() { 225 if (!proto.hasLogAggregationContext()) { 226 return null; 227 } 228 return new LogAggregationContextPBImpl(proto.getLogAggregationContext()); 229 } 230 231 @Override 232 public void write(DataOutput out) throws IOException { 233 LOG.debug("Writing ContainerTokenIdentifier to RPC layer: " + this); 234 out.write(proto.toByteArray()); 235 } 236 237 @Override 238 public void readFields(DataInput in) throws IOException { 239 proto = ContainerTokenIdentifierProto.parseFrom((DataInputStream)in); 240 } 241 242 @Override 243 public Text getKind() { 244 return KIND; 245 } 246 247 @Override 248 public UserGroupInformation getUser() { 249 String containerId = null; 250 if (proto.hasContainerId()) { 251 containerId = new ContainerIdPBImpl(proto.getContainerId()).toString(); 252 } 253 return UserGroupInformation.createRemoteUser( 254 containerId); 255 } 256 257 /** 258 * Get the Container version 259 * @return container version 260 */ 261 public int getVersion() { 262 if (proto.hasVersion()) { 263 return proto.getVersion(); 264 } else { 265 return 0; 266 } 267 } 268 /** 269 * Get the node-label-expression in the original ResourceRequest 270 */ 271 public String getNodeLabelExpression() { 272 if (proto.hasNodeLabelExpression()) { 273 return proto.getNodeLabelExpression(); 274 } 275 return CommonNodeLabelsManager.NO_LABEL; 276 } 277 278 // TODO: Needed? 279 @InterfaceAudience.Private 280 public static class Renewer extends Token.TrivialRenewer { 281 @Override 282 protected Text getKind() { 283 return KIND; 284 } 285 } 286 287 @Override 288 public int hashCode() { 289 return getProto().hashCode(); 290 } 291 292 @Override 293 public boolean equals(Object other) { 294 if (other == null) 295 return false; 296 if (other.getClass().isAssignableFrom(this.getClass())) { 297 return this.getProto().equals(this.getClass().cast(other).getProto()); 298 } 299 return false; 300 } 301 302 @Override 303 public String toString() { 304 return TextFormat.shortDebugString(getProto()); 305 } 306 307 private ContainerTypeProto convertToProtoFormat(ContainerType containerType) { 308 return ProtoUtils.convertToProtoFormat(containerType); 309 } 310 311 private ContainerType convertFromProtoFormat( 312 ContainerTypeProto containerType) { 313 return ProtoUtils.convertFromProtoFormat(containerType); 314 } 315}