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.protocol; 020 021import java.io.IOException; 022 023import javax.annotation.Nullable; 024 025import org.apache.commons.lang.builder.EqualsBuilder; 026import org.apache.commons.lang.builder.HashCodeBuilder; 027import org.apache.hadoop.classification.InterfaceAudience; 028import org.apache.hadoop.classification.InterfaceStability; 029import org.apache.hadoop.fs.InvalidRequestException; 030import org.apache.hadoop.fs.permission.FsPermission; 031import org.apache.hadoop.hdfs.protocol.CacheDirectiveInfo.Expiration; 032 033/** 034 * CachePoolInfo describes a cache pool. 035 * 036 * This class is used in RPCs to create and modify cache pools. 037 * It is serializable and can be stored in the edit log. 038 */ 039@InterfaceAudience.Public 040@InterfaceStability.Evolving 041public class CachePoolInfo { 042 043 /** 044 * Indicates that the pool does not have a maximum relative expiry. 045 */ 046 public static final long RELATIVE_EXPIRY_NEVER = 047 Expiration.MAX_RELATIVE_EXPIRY_MS; 048 /** 049 * Default max relative expiry for cache pools. 050 */ 051 public static final long DEFAULT_MAX_RELATIVE_EXPIRY = 052 RELATIVE_EXPIRY_NEVER; 053 054 public static final long LIMIT_UNLIMITED = Long.MAX_VALUE; 055 public static final long DEFAULT_LIMIT = LIMIT_UNLIMITED; 056 057 public static final short DEFAULT_REPLICATION_NUM = 1; 058 059 final String poolName; 060 061 @Nullable 062 String ownerName; 063 064 @Nullable 065 String groupName; 066 067 @Nullable 068 FsPermission mode; 069 070 @Nullable 071 Long limit; 072 073 @Nullable 074 private Short defaultReplication; 075 076 @Nullable 077 Long maxRelativeExpiryMs; 078 079 public CachePoolInfo(String poolName) { 080 this.poolName = poolName; 081 } 082 083 /** 084 * @return Name of the pool. 085 */ 086 public String getPoolName() { 087 return poolName; 088 } 089 090 /** 091 * @return The owner of the pool. Along with the group and mode, determines 092 * who has access to view and modify the pool. 093 */ 094 public String getOwnerName() { 095 return ownerName; 096 } 097 098 public CachePoolInfo setOwnerName(String ownerName) { 099 this.ownerName = ownerName; 100 return this; 101 } 102 103 /** 104 * @return The group of the pool. Along with the owner and mode, determines 105 * who has access to view and modify the pool. 106 */ 107 public String getGroupName() { 108 return groupName; 109 } 110 111 public CachePoolInfo setGroupName(String groupName) { 112 this.groupName = groupName; 113 return this; 114 } 115 116 /** 117 * @return Unix-style permissions of the pool. Along with the owner and group, 118 * determines who has access to view and modify the pool. 119 */ 120 public FsPermission getMode() { 121 return mode; 122 } 123 124 public CachePoolInfo setMode(FsPermission mode) { 125 this.mode = mode; 126 return this; 127 } 128 129 /** 130 * @return The maximum aggregate number of bytes that can be cached by 131 * directives in this pool. 132 */ 133 public Long getLimit() { 134 return limit; 135 } 136 137 public CachePoolInfo setLimit(Long bytes) { 138 this.limit = bytes; 139 return this; 140 } 141 142 /** 143 * @return The default replication num for CacheDirective in this pool 144 */ 145 public Short getDefaultReplication() { 146 return defaultReplication; 147 } 148 149 public CachePoolInfo setDefaultReplication(Short repl) { 150 this.defaultReplication = repl; 151 return this; 152 } 153 154 /** 155 * @return The maximum relative expiration of directives of this pool in 156 * milliseconds 157 */ 158 public Long getMaxRelativeExpiryMs() { 159 return maxRelativeExpiryMs; 160 } 161 162 /** 163 * Set the maximum relative expiration of directives of this pool in 164 * milliseconds. 165 * 166 * @param ms in milliseconds 167 * @return This builder, for call chaining. 168 */ 169 public CachePoolInfo setMaxRelativeExpiryMs(Long ms) { 170 this.maxRelativeExpiryMs = ms; 171 return this; 172 } 173 174 public String toString() { 175 return "{" + "poolName:" + poolName 176 + ", ownerName:" + ownerName 177 + ", groupName:" + groupName 178 + ", mode:" 179 + ((mode == null) ? "null" : String.format("0%03o", mode.toShort())) 180 + ", limit:" + limit 181 + ", defaultReplication:" + defaultReplication 182 + ", maxRelativeExpiryMs:" + maxRelativeExpiryMs + "}"; 183 } 184 185 @Override 186 public boolean equals(Object o) { 187 if (o == null) { return false; } 188 if (o == this) { return true; } 189 if (o.getClass() != getClass()) { 190 return false; 191 } 192 CachePoolInfo other = (CachePoolInfo)o; 193 return new EqualsBuilder(). 194 append(poolName, other.poolName). 195 append(ownerName, other.ownerName). 196 append(groupName, other.groupName). 197 append(mode, other.mode). 198 append(limit, other.limit). 199 append(defaultReplication, other.defaultReplication). 200 append(maxRelativeExpiryMs, other.maxRelativeExpiryMs). 201 isEquals(); 202 } 203 204 @Override 205 public int hashCode() { 206 return new HashCodeBuilder(). 207 append(poolName). 208 append(ownerName). 209 append(groupName). 210 append(mode). 211 append(limit). 212 append(defaultReplication). 213 append(maxRelativeExpiryMs). 214 hashCode(); 215 } 216 217 public static void validate(CachePoolInfo info) throws IOException { 218 if (info == null) { 219 throw new InvalidRequestException("CachePoolInfo is null"); 220 } 221 if ((info.getLimit() != null) && (info.getLimit() < 0)) { 222 throw new InvalidRequestException("Limit is negative."); 223 } 224 if ((info.getDefaultReplication() != null) 225 && (info.getDefaultReplication() < 0)) { 226 throw new InvalidRequestException("Default Replication is negative"); 227 } 228 229 if (info.getMaxRelativeExpiryMs() != null) { 230 long maxRelativeExpiryMs = info.getMaxRelativeExpiryMs(); 231 if (maxRelativeExpiryMs < 0l) { 232 throw new InvalidRequestException("Max relative expiry is negative."); 233 } 234 if (maxRelativeExpiryMs > Expiration.MAX_RELATIVE_EXPIRY_MS) { 235 throw new InvalidRequestException("Max relative expiry is too big."); 236 } 237 } 238 validateName(info.poolName); 239 } 240 241 public static void validateName(String poolName) throws IOException { 242 if (poolName == null || poolName.isEmpty()) { 243 // Empty pool names are not allowed because they would be highly 244 // confusing. They would also break the ability to list all pools 245 // by starting with prevKey = "" 246 throw new IOException("invalid empty cache pool name"); 247 } 248 } 249}