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    }