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