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