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, hostName, appSubmitter, r, expiryTimeStamp, masterKeyId, 091 rmIdentifier, priority, creationTime, logAggregationContext, 092 nodeLabelExpression, containerType, ExecutionType.GUARANTEED); 093 } 094 095 public ContainerTokenIdentifier(ContainerId containerID, String hostName, 096 String appSubmitter, Resource r, long expiryTimeStamp, int masterKeyId, 097 long rmIdentifier, Priority priority, long creationTime, 098 LogAggregationContext logAggregationContext, String nodeLabelExpression, 099 ContainerType containerType, ExecutionType executionType) { 100 ContainerTokenIdentifierProto.Builder builder = 101 ContainerTokenIdentifierProto.newBuilder(); 102 if (containerID != null) { 103 builder.setContainerId(((ContainerIdPBImpl)containerID).getProto()); 104 } 105 builder.setNmHostAddr(hostName); 106 builder.setAppSubmitter(appSubmitter); 107 if (r != null) { 108 builder.setResource(((ResourcePBImpl)r).getProto()); 109 } 110 builder.setExpiryTimeStamp(expiryTimeStamp); 111 builder.setMasterKeyId(masterKeyId); 112 builder.setRmIdentifier(rmIdentifier); 113 if (priority != null) { 114 builder.setPriority(((PriorityPBImpl)priority).getProto()); 115 } 116 builder.setCreationTime(creationTime); 117 118 if (logAggregationContext != null) { 119 builder.setLogAggregationContext( 120 ((LogAggregationContextPBImpl)logAggregationContext).getProto()); 121 } 122 123 if (nodeLabelExpression != null) { 124 builder.setNodeLabelExpression(nodeLabelExpression); 125 } 126 builder.setContainerType(convertToProtoFormat(containerType)); 127 builder.setExecutionType(convertToProtoFormat(executionType)); 128 129 proto = builder.build(); 130 } 131 132 /** 133 * Default constructor needed by RPC layer/SecretManager. 134 */ 135 public ContainerTokenIdentifier() { 136 } 137 138 public ContainerId getContainerID() { 139 if (!proto.hasContainerId()) { 140 return null; 141 } 142 return new ContainerIdPBImpl(proto.getContainerId()); 143 } 144 145 public String getApplicationSubmitter() { 146 return proto.getAppSubmitter(); 147 } 148 149 public String getNmHostAddress() { 150 return proto.getNmHostAddr(); 151 } 152 153 public Resource getResource() { 154 if (!proto.hasResource()) { 155 return null; 156 } 157 return new ResourcePBImpl(proto.getResource()); 158 } 159 160 public long getExpiryTimeStamp() { 161 return proto.getExpiryTimeStamp(); 162 } 163 164 public int getMasterKeyId() { 165 return proto.getMasterKeyId(); 166 } 167 168 public Priority getPriority() { 169 if (!proto.hasPriority()) { 170 return null; 171 } 172 return new PriorityPBImpl(proto.getPriority()); 173 } 174 175 public long getCreationTime() { 176 return proto.getCreationTime(); 177 } 178 /** 179 * Get the RMIdentifier of RM in which containers are allocated. 180 * @return RMIdentifier 181 */ 182 public long getRMIdentifier() { 183 return proto.getRmIdentifier(); 184 } 185 186 /** 187 * Get the ContainerType of container to allocate 188 * @return ContainerType 189 */ 190 public ContainerType getContainerType(){ 191 if (!proto.hasContainerType()) { 192 return null; 193 } 194 return convertFromProtoFormat(proto.getContainerType()); 195 } 196 197 /** 198 * Get the ExecutionType of container to allocate 199 * @return ExecutionType 200 */ 201 public ExecutionType getExecutionType(){ 202 if (!proto.hasExecutionType()) { 203 return null; 204 } 205 return convertFromProtoFormat(proto.getExecutionType()); 206 } 207 208 public ContainerTokenIdentifierProto getProto() { 209 return proto; 210 } 211 212 public LogAggregationContext getLogAggregationContext() { 213 if (!proto.hasLogAggregationContext()) { 214 return null; 215 } 216 return new LogAggregationContextPBImpl(proto.getLogAggregationContext()); 217 } 218 219 @Override 220 public void write(DataOutput out) throws IOException { 221 LOG.debug("Writing ContainerTokenIdentifier to RPC layer: " + this); 222 out.write(proto.toByteArray()); 223 } 224 225 @Override 226 public void readFields(DataInput in) throws IOException { 227 proto = ContainerTokenIdentifierProto.parseFrom((DataInputStream)in); 228 } 229 230 @Override 231 public Text getKind() { 232 return KIND; 233 } 234 235 @Override 236 public UserGroupInformation getUser() { 237 String containerId = null; 238 if (proto.hasContainerId()) { 239 containerId = new ContainerIdPBImpl(proto.getContainerId()).toString(); 240 } 241 return UserGroupInformation.createRemoteUser( 242 containerId); 243 } 244 245 /** 246 * Get the node-label-expression in the original ResourceRequest 247 */ 248 public String getNodeLabelExpression() { 249 if (proto.hasNodeLabelExpression()) { 250 return proto.getNodeLabelExpression(); 251 } 252 return CommonNodeLabelsManager.NO_LABEL; 253 } 254 255 // TODO: Needed? 256 @InterfaceAudience.Private 257 public static class Renewer extends Token.TrivialRenewer { 258 @Override 259 protected Text getKind() { 260 return KIND; 261 } 262 } 263 264 @Override 265 public int hashCode() { 266 return getProto().hashCode(); 267 } 268 269 @Override 270 public boolean equals(Object other) { 271 if (other == null) 272 return false; 273 if (other.getClass().isAssignableFrom(this.getClass())) { 274 return this.getProto().equals(this.getClass().cast(other).getProto()); 275 } 276 return false; 277 } 278 279 @Override 280 public String toString() { 281 return TextFormat.shortDebugString(getProto()); 282 } 283 284 private ContainerTypeProto convertToProtoFormat(ContainerType containerType) { 285 return ProtoUtils.convertToProtoFormat(containerType); 286 } 287 288 private ContainerType convertFromProtoFormat( 289 ContainerTypeProto containerType) { 290 return ProtoUtils.convertFromProtoFormat(containerType); 291 } 292 293 private ExecutionTypeProto convertToProtoFormat(ExecutionType executionType) { 294 return ProtoUtils.convertToProtoFormat(executionType); 295 } 296 297 private ExecutionType convertFromProtoFormat( 298 ExecutionTypeProto executionType) { 299 return ProtoUtils.convertFromProtoFormat(executionType); 300 } 301}