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
019 package org.apache.hadoop.hdfs.protocol;
020
021 import java.io.IOException;
022
023 import javax.annotation.Nullable;
024
025 import org.apache.commons.lang.builder.EqualsBuilder;
026 import org.apache.commons.lang.builder.HashCodeBuilder;
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.apache.hadoop.classification.InterfaceAudience;
030 import org.apache.hadoop.classification.InterfaceStability;
031 import org.apache.hadoop.fs.InvalidRequestException;
032 import org.apache.hadoop.fs.permission.FsPermission;
033 import 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
043 public 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 }