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