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.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029import org.apache.hadoop.classification.InterfaceAudience; 030import org.apache.hadoop.classification.InterfaceStability; 031import org.apache.hadoop.fs.InvalidRequestException; 032import org.apache.hadoop.fs.permission.FsPermission; 033import org.apache.hadoop.hdfs.protocol.CacheDirectiveInfo.Expiration; 034 035/** 036 * CachePoolInfo describes a cache pool. 037 * 038 * This class is used in RPCs to create and modify cache pools. 039 * It is serializable and can be stored in the edit log. 040 */ 041@InterfaceAudience.Public 042@InterfaceStability.Evolving 043public class CachePoolInfo { 044 public static final Log LOG = LogFactory.getLog(CachePoolInfo.class); 045 046 /** 047 * Indicates that the pool does not have a maximum relative expiry. 048 */ 049 public static final long RELATIVE_EXPIRY_NEVER = 050 Expiration.MAX_RELATIVE_EXPIRY_MS; 051 /** 052 * Default max relative expiry for cache pools. 053 */ 054 public static final long DEFAULT_MAX_RELATIVE_EXPIRY = 055 RELATIVE_EXPIRY_NEVER; 056 057 public static final long LIMIT_UNLIMITED = Long.MAX_VALUE; 058 public static final long DEFAULT_LIMIT = LIMIT_UNLIMITED; 059 060 final String poolName; 061 062 @Nullable 063 String ownerName; 064 065 @Nullable 066 String groupName; 067 068 @Nullable 069 FsPermission mode; 070 071 @Nullable 072 Long limit; 073 074 @Nullable 075 Long maxRelativeExpiryMs; 076 077 public CachePoolInfo(String poolName) { 078 this.poolName = poolName; 079 } 080 081 /** 082 * @return Name of the pool. 083 */ 084 public String getPoolName() { 085 return poolName; 086 } 087 088 /** 089 * @return The owner of the pool. Along with the group and mode, determines 090 * who has access to view and modify the pool. 091 */ 092 public String getOwnerName() { 093 return ownerName; 094 } 095 096 public CachePoolInfo setOwnerName(String ownerName) { 097 this.ownerName = ownerName; 098 return this; 099 } 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 */ 105 public String getGroupName() { 106 return groupName; 107 } 108 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 */ 118 public FsPermission getMode() { 119 return mode; 120 } 121 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 */ 131 public Long getLimit() { 132 return limit; 133 } 134 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 */ 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 */ 155 public CachePoolInfo setMaxRelativeExpiryMs(Long ms) { 156 this.maxRelativeExpiryMs = ms; 157 return this; 158 } 159 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 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 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 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 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}