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 }