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 019 package org.apache.hadoop.yarn.security; 020 021 import java.io.DataInput; 022 import java.io.DataInputStream; 023 import java.io.DataOutput; 024 import java.io.IOException; 025 026 import org.apache.commons.logging.Log; 027 import org.apache.commons.logging.LogFactory; 028 import org.apache.hadoop.classification.InterfaceAudience; 029 import org.apache.hadoop.classification.InterfaceAudience.Public; 030 import org.apache.hadoop.classification.InterfaceStability.Evolving; 031 import org.apache.hadoop.io.Text; 032 import org.apache.hadoop.security.UserGroupInformation; 033 import org.apache.hadoop.security.token.Token; 034 import org.apache.hadoop.security.token.TokenIdentifier; 035 import org.apache.hadoop.yarn.api.records.ContainerId; 036 import org.apache.hadoop.yarn.api.records.LogAggregationContext; 037 import org.apache.hadoop.yarn.api.records.Priority; 038 import org.apache.hadoop.yarn.api.records.Resource; 039 import org.apache.hadoop.yarn.api.records.impl.pb.ContainerIdPBImpl; 040 import org.apache.hadoop.yarn.api.records.impl.pb.LogAggregationContextPBImpl; 041 import org.apache.hadoop.yarn.api.records.impl.pb.PriorityPBImpl; 042 import org.apache.hadoop.yarn.api.records.impl.pb.ResourcePBImpl; 043 import org.apache.hadoop.yarn.proto.YarnSecurityTokenProtos.ContainerTokenIdentifierProto; 044 045 import 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 055 public 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 }