1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.hdfs.protocol; 20 21 import java.io.IOException; 22 23 import javax.annotation.Nullable; 24 25 import org.apache.commons.lang.builder.EqualsBuilder; 26 import org.apache.commons.lang.builder.HashCodeBuilder; 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 import org.apache.hadoop.classification.InterfaceAudience; 30 import org.apache.hadoop.classification.InterfaceStability; 31 import org.apache.hadoop.fs.InvalidRequestException; 32 import org.apache.hadoop.fs.permission.FsPermission; 33 import org.apache.hadoop.hdfs.protocol.CacheDirectiveInfo.Expiration; 34 35 /** 36 * CachePoolInfo describes a cache pool. 37 * 38 * This class is used in RPCs to create and modify cache pools. 39 * It is serializable and can be stored in the edit log. 40 */ 41 @InterfaceAudience.Public 42 @InterfaceStability.Evolving 43 public class CachePoolInfo { 44 public static final Log LOG = LogFactory.getLog(CachePoolInfo.class); 45 46 /** 47 * Indicates that the pool does not have a maximum relative expiry. 48 */ 49 public static final long RELATIVE_EXPIRY_NEVER = 50 Expiration.MAX_RELATIVE_EXPIRY_MS; 51 /** 52 * Default max relative expiry for cache pools. 53 */ 54 public static final long DEFAULT_MAX_RELATIVE_EXPIRY = 55 RELATIVE_EXPIRY_NEVER; 56 57 public static final long LIMIT_UNLIMITED = Long.MAX_VALUE; 58 public static final long DEFAULT_LIMIT = LIMIT_UNLIMITED; 59 60 final String poolName; 61 62 @Nullable 63 String ownerName; 64 65 @Nullable 66 String groupName; 67 68 @Nullable 69 FsPermission mode; 70 71 @Nullable 72 Long limit; 73 74 @Nullable 75 Long maxRelativeExpiryMs; 76 CachePoolInfo(String poolName)77 public CachePoolInfo(String poolName) { 78 this.poolName = poolName; 79 } 80 81 /** 82 * @return Name of the pool. 83 */ getPoolName()84 public String getPoolName() { 85 return poolName; 86 } 87 88 /** 89 * @return The owner of the pool. Along with the group and mode, determines 90 * who has access to view and modify the pool. 91 */ getOwnerName()92 public String getOwnerName() { 93 return ownerName; 94 } 95 setOwnerName(String ownerName)96 public CachePoolInfo setOwnerName(String ownerName) { 97 this.ownerName = ownerName; 98 return this; 99 } 100 101 /** 102 * @return The group of the pool. Along with the owner and mode, determines 103 * who has access to view and modify the pool. 104 */ getGroupName()105 public String getGroupName() { 106 return groupName; 107 } 108 setGroupName(String groupName)109 public CachePoolInfo setGroupName(String groupName) { 110 this.groupName = groupName; 111 return this; 112 } 113 114 /** 115 * @return Unix-style permissions of the pool. Along with the owner and group, 116 * determines who has access to view and modify the pool. 117 */ getMode()118 public FsPermission getMode() { 119 return mode; 120 } 121 setMode(FsPermission mode)122 public CachePoolInfo setMode(FsPermission mode) { 123 this.mode = mode; 124 return this; 125 } 126 127 /** 128 * @return The maximum aggregate number of bytes that can be cached by 129 * directives in this pool. 130 */ getLimit()131 public Long getLimit() { 132 return limit; 133 } 134 setLimit(Long bytes)135 public CachePoolInfo setLimit(Long bytes) { 136 this.limit = bytes; 137 return this; 138 } 139 140 /** 141 * @return The maximum relative expiration of directives of this pool in 142 * milliseconds 143 */ getMaxRelativeExpiryMs()144 public Long getMaxRelativeExpiryMs() { 145 return maxRelativeExpiryMs; 146 } 147 148 /** 149 * Set the maximum relative expiration of directives of this pool in 150 * milliseconds. 151 * 152 * @param ms in milliseconds 153 * @return This builder, for call chaining. 154 */ setMaxRelativeExpiryMs(Long ms)155 public CachePoolInfo setMaxRelativeExpiryMs(Long ms) { 156 this.maxRelativeExpiryMs = ms; 157 return this; 158 } 159 toString()160 public String toString() { 161 return new StringBuilder().append("{"). 162 append("poolName:").append(poolName). 163 append(", ownerName:").append(ownerName). 164 append(", groupName:").append(groupName). 165 append(", mode:").append((mode == null) ? "null" : 166 String.format("0%03o", mode.toShort())). 167 append(", limit:").append(limit). 168 append(", maxRelativeExpiryMs:").append(maxRelativeExpiryMs). 169 append("}").toString(); 170 } 171 172 @Override equals(Object o)173 public boolean equals(Object o) { 174 if (o == null) { return false; } 175 if (o == this) { return true; } 176 if (o.getClass() != getClass()) { 177 return false; 178 } 179 CachePoolInfo other = (CachePoolInfo)o; 180 return new EqualsBuilder(). 181 append(poolName, other.poolName). 182 append(ownerName, other.ownerName). 183 append(groupName, other.groupName). 184 append(mode, other.mode). 185 append(limit, other.limit). 186 append(maxRelativeExpiryMs, other.maxRelativeExpiryMs). 187 isEquals(); 188 } 189 190 @Override hashCode()191 public int hashCode() { 192 return new HashCodeBuilder(). 193 append(poolName). 194 append(ownerName). 195 append(groupName). 196 append(mode). 197 append(limit). 198 append(maxRelativeExpiryMs). 199 hashCode(); 200 } 201 validate(CachePoolInfo info)202 public static void validate(CachePoolInfo info) throws IOException { 203 if (info == null) { 204 throw new InvalidRequestException("CachePoolInfo is null"); 205 } 206 if ((info.getLimit() != null) && (info.getLimit() < 0)) { 207 throw new InvalidRequestException("Limit is negative."); 208 } 209 if (info.getMaxRelativeExpiryMs() != null) { 210 long maxRelativeExpiryMs = info.getMaxRelativeExpiryMs(); 211 if (maxRelativeExpiryMs < 0l) { 212 throw new InvalidRequestException("Max relative expiry is negative."); 213 } 214 if (maxRelativeExpiryMs > Expiration.MAX_RELATIVE_EXPIRY_MS) { 215 throw new InvalidRequestException("Max relative expiry is too big."); 216 } 217 } 218 validateName(info.poolName); 219 } 220 validateName(String poolName)221 public static void validateName(String poolName) throws IOException { 222 if (poolName == null || poolName.isEmpty()) { 223 // Empty pool names are not allowed because they would be highly 224 // confusing. They would also break the ability to list all pools 225 // by starting with prevKey = "" 226 throw new IOException("invalid empty cache pool name"); 227 } 228 } 229 } 230