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.inotify; 020 021import org.apache.hadoop.classification.InterfaceAudience; 022import org.apache.hadoop.classification.InterfaceStability; 023import org.apache.hadoop.fs.XAttr; 024import org.apache.hadoop.fs.permission.AclEntry; 025import org.apache.hadoop.fs.permission.FsPermission; 026 027import 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 036public 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}