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.inotify;
020
021 import org.apache.hadoop.classification.InterfaceAudience;
022 import org.apache.hadoop.classification.InterfaceStability;
023 import org.apache.hadoop.fs.XAttr;
024 import org.apache.hadoop.fs.permission.AclEntry;
025 import org.apache.hadoop.fs.permission.FsPermission;
026
027 import java.util.List;
028
029 /**
030 * Events sent by the inotify system. Note that no events are necessarily sent
031 * when a file is opened for read (although a MetadataUpdateEvent will be sent
032 * if the atime is updated).
033 */
034 @InterfaceAudience.Public
035 @InterfaceStability.Unstable
036 public abstract class Event {
037 public static enum EventType {
038 CREATE, CLOSE, APPEND, RENAME, METADATA, UNLINK
039 }
040
041 private EventType eventType;
042
043 public EventType getEventType() {
044 return eventType;
045 }
046
047 public Event(EventType eventType) {
048 this.eventType = eventType;
049 }
050
051 /**
052 * Sent when a file is closed after append or create.
053 */
054 public static class CloseEvent extends Event {
055 private String path;
056 private long fileSize;
057 private long timestamp;
058
059 public CloseEvent(String path, long fileSize, long timestamp) {
060 super(EventType.CLOSE);
061 this.path = path;
062 this.fileSize = fileSize;
063 this.timestamp = timestamp;
064 }
065
066 public String getPath() {
067 return path;
068 }
069
070 /**
071 * The size of the closed file in bytes. May be -1 if the size is not
072 * available (e.g. in the case of a close generated by a concat operation).
073 */
074 public long getFileSize() {
075 return fileSize;
076 }
077
078 /**
079 * The time when this event occurred, in milliseconds since the epoch.
080 */
081 public long getTimestamp() {
082 return timestamp;
083 }
084 }
085
086 /**
087 * Sent when a new file is created (including overwrite).
088 */
089 public static class CreateEvent extends Event {
090
091 public static enum INodeType {
092 FILE, DIRECTORY, SYMLINK;
093 }
094
095 private INodeType iNodeType;
096 private String path;
097 private long ctime;
098 private int replication;
099 private String ownerName;
100 private String groupName;
101 private FsPermission perms;
102 private String symlinkTarget;
103 private boolean overwrite;
104
105 public static class Builder {
106 private INodeType iNodeType;
107 private String path;
108 private long ctime;
109 private int replication;
110 private String ownerName;
111 private String groupName;
112 private FsPermission perms;
113 private String symlinkTarget;
114 private boolean overwrite;
115
116 public Builder iNodeType(INodeType type) {
117 this.iNodeType = type;
118 return this;
119 }
120
121 public Builder path(String path) {
122 this.path = path;
123 return this;
124 }
125
126 public Builder ctime(long ctime) {
127 this.ctime = ctime;
128 return this;
129 }
130
131 public Builder replication(int replication) {
132 this.replication = replication;
133 return this;
134 }
135
136 public Builder ownerName(String ownerName) {
137 this.ownerName = ownerName;
138 return this;
139 }
140
141 public Builder groupName(String groupName) {
142 this.groupName = groupName;
143 return this;
144 }
145
146 public Builder perms(FsPermission perms) {
147 this.perms = perms;
148 return this;
149 }
150
151 public Builder symlinkTarget(String symlinkTarget) {
152 this.symlinkTarget = symlinkTarget;
153 return this;
154 }
155
156 public Builder overwrite(boolean overwrite) {
157 this.overwrite = overwrite;
158 return this;
159 }
160
161 public CreateEvent build() {
162 return new CreateEvent(this);
163 }
164 }
165
166 private CreateEvent(Builder b) {
167 super(EventType.CREATE);
168 this.iNodeType = b.iNodeType;
169 this.path = b.path;
170 this.ctime = b.ctime;
171 this.replication = b.replication;
172 this.ownerName = b.ownerName;
173 this.groupName = b.groupName;
174 this.perms = b.perms;
175 this.symlinkTarget = b.symlinkTarget;
176 this.overwrite = b.overwrite;
177 }
178
179 public INodeType getiNodeType() {
180 return iNodeType;
181 }
182
183 public String getPath() {
184 return path;
185 }
186
187 /**
188 * Creation time of the file, directory, or symlink.
189 */
190 public long getCtime() {
191 return ctime;
192 }
193
194 /**
195 * Replication is zero if the CreateEvent iNodeType is directory or symlink.
196 */
197 public int getReplication() {
198 return replication;
199 }
200
201 public String getOwnerName() {
202 return ownerName;
203 }
204
205 public String getGroupName() {
206 return groupName;
207 }
208
209 public FsPermission getPerms() {
210 return perms;
211 }
212
213 /**
214 * Symlink target is null if the CreateEvent iNodeType is not symlink.
215 */
216 public String getSymlinkTarget() {
217 return symlinkTarget;
218 }
219
220 public boolean getOverwrite() {
221 return overwrite;
222 }
223 }
224
225 /**
226 * Sent when there is an update to directory or file (none of the metadata
227 * tracked here applies to symlinks) that is not associated with another
228 * inotify event. The tracked metadata includes atime/mtime, replication,
229 * owner/group, permissions, ACLs, and XAttributes. Fields not relevant to the
230 * metadataType of the MetadataUpdateEvent will be null or will have their default
231 * values.
232 */
233 public static class MetadataUpdateEvent extends Event {
234
235 public static enum MetadataType {
236 TIMES, REPLICATION, OWNER, PERMS, ACLS, XATTRS;
237 }
238
239 private String path;
240 private MetadataType metadataType;
241 private long mtime;
242 private long atime;
243 private int replication;
244 private String ownerName;
245 private String groupName;
246 private FsPermission perms;
247 private List<AclEntry> acls;
248 private List<XAttr> xAttrs;
249 private boolean xAttrsRemoved;
250
251 public static class Builder {
252 private String path;
253 private MetadataType metadataType;
254 private long mtime;
255 private long atime;
256 private int replication;
257 private String ownerName;
258 private String groupName;
259 private FsPermission perms;
260 private List<AclEntry> acls;
261 private List<XAttr> xAttrs;
262 private boolean xAttrsRemoved;
263
264 public Builder path(String path) {
265 this.path = path;
266 return this;
267 }
268
269 public Builder metadataType(MetadataType type) {
270 this.metadataType = type;
271 return this;
272 }
273
274 public Builder mtime(long mtime) {
275 this.mtime = mtime;
276 return this;
277 }
278
279 public Builder atime(long atime) {
280 this.atime = atime;
281 return this;
282 }
283
284 public Builder replication(int replication) {
285 this.replication = replication;
286 return this;
287 }
288
289 public Builder ownerName(String ownerName) {
290 this.ownerName = ownerName;
291 return this;
292 }
293
294 public Builder groupName(String groupName) {
295 this.groupName = groupName;
296 return this;
297 }
298
299 public Builder perms(FsPermission perms) {
300 this.perms = perms;
301 return this;
302 }
303
304 public Builder acls(List<AclEntry> acls) {
305 this.acls = acls;
306 return this;
307 }
308
309 public Builder xAttrs(List<XAttr> xAttrs) {
310 this.xAttrs = xAttrs;
311 return this;
312 }
313
314 public Builder xAttrsRemoved(boolean xAttrsRemoved) {
315 this.xAttrsRemoved = xAttrsRemoved;
316 return this;
317 }
318
319 public MetadataUpdateEvent build() {
320 return new MetadataUpdateEvent(this);
321 }
322 }
323
324 private MetadataUpdateEvent(Builder b) {
325 super(EventType.METADATA);
326 this.path = b.path;
327 this.metadataType = b.metadataType;
328 this.mtime = b.mtime;
329 this.atime = b.atime;
330 this.replication = b.replication;
331 this.ownerName = b.ownerName;
332 this.groupName = b.groupName;
333 this.perms = b.perms;
334 this.acls = b.acls;
335 this.xAttrs = b.xAttrs;
336 this.xAttrsRemoved = b.xAttrsRemoved;
337 }
338
339 public String getPath() {
340 return path;
341 }
342
343 public MetadataType getMetadataType() {
344 return metadataType;
345 }
346
347 public long getMtime() {
348 return mtime;
349 }
350
351 public long getAtime() {
352 return atime;
353 }
354
355 public int getReplication() {
356 return replication;
357 }
358
359 public String getOwnerName() {
360 return ownerName;
361 }
362
363 public String getGroupName() {
364 return groupName;
365 }
366
367 public FsPermission getPerms() {
368 return perms;
369 }
370
371 /**
372 * The full set of ACLs currently associated with this file or directory.
373 * May be null if all ACLs were removed.
374 */
375 public List<AclEntry> getAcls() {
376 return acls;
377 }
378
379 public List<XAttr> getxAttrs() {
380 return xAttrs;
381 }
382
383 /**
384 * Whether the xAttrs returned by getxAttrs() were removed (as opposed to
385 * added).
386 */
387 public boolean isxAttrsRemoved() {
388 return xAttrsRemoved;
389 }
390
391 }
392
393 /**
394 * Sent when a file, directory, or symlink is renamed.
395 */
396 public static class RenameEvent extends Event {
397 private String srcPath;
398 private String dstPath;
399 private long timestamp;
400
401 public RenameEvent(String srcPath, String dstPath, long timestamp) {
402 super(EventType.RENAME);
403 this.srcPath = srcPath;
404 this.dstPath = dstPath;
405 this.timestamp = timestamp;
406 }
407
408 public String getSrcPath() {
409 return srcPath;
410 }
411
412 public String getDstPath() {
413 return dstPath;
414 }
415
416 /**
417 * The time when this event occurred, in milliseconds since the epoch.
418 */
419 public long getTimestamp() {
420 return timestamp;
421 }
422 }
423
424 /**
425 * Sent when an existing file is opened for append.
426 */
427 public static class AppendEvent extends Event {
428 private String path;
429
430 public AppendEvent(String path) {
431 super(EventType.APPEND);
432 this.path = path;
433 }
434
435 public String getPath() {
436 return path;
437 }
438 }
439
440 /**
441 * Sent when a file, directory, or symlink is deleted.
442 */
443 public static class UnlinkEvent extends Event {
444 private String path;
445 private long timestamp;
446
447 public UnlinkEvent(String path, long timestamp) {
448 super(EventType.UNLINK);
449 this.path = path;
450 this.timestamp = timestamp;
451 }
452
453 public String getPath() {
454 return path;
455 }
456
457 /**
458 * The time when this event occurred, in milliseconds since the epoch.
459 */
460 public long getTimestamp() {
461 return timestamp;
462 }
463 }
464 }