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 final String poolName; 058 059 @Nullable 060 String ownerName; 061 062 @Nullable 063 String groupName; 064 065 @Nullable 066 FsPermission mode; 067 068 @Nullable 069 Long limit; 070 071 @Nullable 072 Long maxRelativeExpiryMs; 073 074 public CachePoolInfo(String poolName) { 075 this.poolName = poolName; 076 } 077 078 /** 079 * @return Name of the pool. 080 */ 081 public String getPoolName() { 082 return poolName; 083 } 084 085 /** 086 * @return The owner of the pool. Along with the group and mode, determines 087 * who has access to view and modify the pool. 088 */ 089 public String getOwnerName() { 090 return ownerName; 091 } 092 093 public CachePoolInfo setOwnerName(String ownerName) { 094 this.ownerName = ownerName; 095 return this; 096 } 097 098 /** 099 * @return The group of the pool. Along with the owner and mode, determines 100 * who has access to view and modify the pool. 101 */ 102 public String getGroupName() { 103 return groupName; 104 } 105 106 public CachePoolInfo setGroupName(String groupName) { 107 this.groupName = groupName; 108 return this; 109 } 110 111 /** 112 * @return Unix-style permissions of the pool. Along with the owner and group, 113 * determines who has access to view and modify the pool. 114 */ 115 public FsPermission getMode() { 116 return mode; 117 } 118 119 public CachePoolInfo setMode(FsPermission mode) { 120 this.mode = mode; 121 return this; 122 } 123 124 /** 125 * @return The maximum aggregate number of bytes that can be cached by 126 * directives in this pool. 127 */ 128 public Long getLimit() { 129 return limit; 130 } 131 132 public CachePoolInfo setLimit(Long bytes) { 133 this.limit = bytes; 134 return this; 135 } 136 137 /** 138 * @return The maximum relative expiration of directives of this pool in 139 * milliseconds 140 */ 141 public Long getMaxRelativeExpiryMs() { 142 return maxRelativeExpiryMs; 143 } 144 145 /** 146 * Set the maximum relative expiration of directives of this pool in 147 * milliseconds. 148 * 149 * @param ms in milliseconds 150 * @return This builder, for call chaining. 151 */ 152 public CachePoolInfo setMaxRelativeExpiryMs(Long ms) { 153 this.maxRelativeExpiryMs = ms; 154 return this; 155 } 156 157 public String toString() { 158 return new StringBuilder().append("{"). 159 append("poolName:").append(poolName). 160 append(", ownerName:").append(ownerName). 161 append(", groupName:").append(groupName). 162 append(", mode:").append((mode == null) ? "null" : 163 String.format("0%03o", mode.toShort())). 164 append(", limit:").append(limit). 165 append(", maxRelativeExpiryMs:").append(maxRelativeExpiryMs). 166 append("}").toString(); 167 } 168 169 @Override 170 public boolean equals(Object o) { 171 if (o == null) { return false; } 172 if (o == this) { return true; } 173 if (o.getClass() != getClass()) { 174 return false; 175 } 176 CachePoolInfo other = (CachePoolInfo)o; 177 return new EqualsBuilder(). 178 append(poolName, other.poolName). 179 append(ownerName, other.ownerName). 180 append(groupName, other.groupName). 181 append(mode, other.mode). 182 append(limit, other.limit). 183 append(maxRelativeExpiryMs, other.maxRelativeExpiryMs). 184 isEquals(); 185 } 186 187 @Override 188 public int hashCode() { 189 return new HashCodeBuilder(). 190 append(poolName). 191 append(ownerName). 192 append(groupName). 193 append(mode). 194 append(limit). 195 append(maxRelativeExpiryMs). 196 hashCode(); 197 } 198 199 public static void validate(CachePoolInfo info) throws IOException { 200 if (info == null) { 201 throw new InvalidRequestException("CachePoolInfo is null"); 202 } 203 if ((info.getLimit() != null) && (info.getLimit() < 0)) { 204 throw new InvalidRequestException("Limit is negative."); 205 } 206 if (info.getMaxRelativeExpiryMs() != null) { 207 long maxRelativeExpiryMs = info.getMaxRelativeExpiryMs(); 208 if (maxRelativeExpiryMs < 0l) { 209 throw new InvalidRequestException("Max relative expiry is negative."); 210 } 211 if (maxRelativeExpiryMs > Expiration.MAX_RELATIVE_EXPIRY_MS) { 212 throw new InvalidRequestException("Max relative expiry is too big."); 213 } 214 } 215 validateName(info.poolName); 216 } 217 218 public static void validateName(String poolName) throws IOException { 219 if (poolName == null || poolName.isEmpty()) { 220 // Empty pool names are not allowed because they would be highly 221 // confusing. They would also break the ability to list all pools 222 // by starting with prevKey = "" 223 throw new IOException("invalid empty cache pool name"); 224 } 225 } 226}