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.hdfs.security.token.block; 020 021import java.io.DataInput; 022import java.io.DataOutput; 023import java.io.IOException; 024import java.util.EnumSet; 025 026import org.apache.hadoop.classification.InterfaceAudience; 027import org.apache.hadoop.io.Text; 028import org.apache.hadoop.io.WritableUtils; 029import org.apache.hadoop.security.UserGroupInformation; 030import org.apache.hadoop.security.token.Token; 031import org.apache.hadoop.security.token.TokenIdentifier; 032 033@InterfaceAudience.Private 034public class BlockTokenIdentifier extends TokenIdentifier { 035 static final Text KIND_NAME = new Text("HDFS_BLOCK_TOKEN"); 036 037 public enum AccessMode { 038 READ, WRITE, COPY, REPLACE 039 } 040 041 private long expiryDate; 042 private int keyId; 043 private String userId; 044 private String blockPoolId; 045 private long blockId; 046 private final EnumSet<AccessMode> modes; 047 048 private byte [] cache; 049 050 public BlockTokenIdentifier() { 051 this(null, null, 0, EnumSet.noneOf(AccessMode.class)); 052 } 053 054 public BlockTokenIdentifier(String userId, String bpid, long blockId, 055 EnumSet<AccessMode> modes) { 056 this.cache = null; 057 this.userId = userId; 058 this.blockPoolId = bpid; 059 this.blockId = blockId; 060 this.modes = modes == null ? EnumSet.noneOf(AccessMode.class) : modes; 061 } 062 063 @Override 064 public Text getKind() { 065 return KIND_NAME; 066 } 067 068 @Override 069 public UserGroupInformation getUser() { 070 if (userId == null || "".equals(userId)) { 071 String user = blockPoolId + ":" + Long.toString(blockId); 072 return UserGroupInformation.createRemoteUser(user); 073 } 074 return UserGroupInformation.createRemoteUser(userId); 075 } 076 077 public long getExpiryDate() { 078 return expiryDate; 079 } 080 081 public void setExpiryDate(long expiryDate) { 082 this.cache = null; 083 this.expiryDate = expiryDate; 084 } 085 086 public int getKeyId() { 087 return this.keyId; 088 } 089 090 public void setKeyId(int keyId) { 091 this.cache = null; 092 this.keyId = keyId; 093 } 094 095 public String getUserId() { 096 return userId; 097 } 098 099 public String getBlockPoolId() { 100 return blockPoolId; 101 } 102 103 public long getBlockId() { 104 return blockId; 105 } 106 107 public EnumSet<AccessMode> getAccessModes() { 108 return modes; 109 } 110 111 @Override 112 public String toString() { 113 return "block_token_identifier (expiryDate=" + this.getExpiryDate() 114 + ", keyId=" + this.getKeyId() + ", userId=" + this.getUserId() 115 + ", blockPoolId=" + this.getBlockPoolId() 116 + ", blockId=" + this.getBlockId() + ", access modes=" 117 + this.getAccessModes() + ")"; 118 } 119 120 static boolean isEqual(Object a, Object b) { 121 return a == null ? b == null : a.equals(b); 122 } 123 124 @Override 125 public boolean equals(Object obj) { 126 if (obj == this) { 127 return true; 128 } 129 if (obj instanceof BlockTokenIdentifier) { 130 BlockTokenIdentifier that = (BlockTokenIdentifier) obj; 131 return this.expiryDate == that.expiryDate && this.keyId == that.keyId 132 && isEqual(this.userId, that.userId) 133 && isEqual(this.blockPoolId, that.blockPoolId) 134 && this.blockId == that.blockId 135 && isEqual(this.modes, that.modes); 136 } 137 return false; 138 } 139 140 @Override 141 public int hashCode() { 142 return (int) expiryDate ^ keyId ^ (int) blockId ^ modes.hashCode() 143 ^ (userId == null ? 0 : userId.hashCode()) 144 ^ (blockPoolId == null ? 0 : blockPoolId.hashCode()); 145 } 146 147 @Override 148 public void readFields(DataInput in) throws IOException { 149 this.cache = null; 150 expiryDate = WritableUtils.readVLong(in); 151 keyId = WritableUtils.readVInt(in); 152 userId = WritableUtils.readString(in); 153 blockPoolId = WritableUtils.readString(in); 154 blockId = WritableUtils.readVLong(in); 155 int length = WritableUtils.readVIntInRange(in, 0, 156 AccessMode.class.getEnumConstants().length); 157 for (int i = 0; i < length; i++) { 158 modes.add(WritableUtils.readEnum(in, AccessMode.class)); 159 } 160 } 161 162 @Override 163 public void write(DataOutput out) throws IOException { 164 WritableUtils.writeVLong(out, expiryDate); 165 WritableUtils.writeVInt(out, keyId); 166 WritableUtils.writeString(out, userId); 167 WritableUtils.writeString(out, blockPoolId); 168 WritableUtils.writeVLong(out, blockId); 169 WritableUtils.writeVInt(out, modes.size()); 170 for (AccessMode aMode : modes) { 171 WritableUtils.writeEnum(out, aMode); 172 } 173 } 174 175 @Override 176 public byte[] getBytes() { 177 if(cache == null) cache = super.getBytes(); 178 179 return cache; 180 } 181 182 @InterfaceAudience.Private 183 public static class Renewer extends Token.TrivialRenewer { 184 @Override 185 protected Text getKind() { 186 return KIND_NAME; 187 } 188 } 189}