/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hdfs.server.namenode; import com.google.common.collect.Lists; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.hdfs.inotify.Event; import org.apache.hadoop.hdfs.inotify.EventBatch; import org.apache.hadoop.hdfs.protocol.Block; import java.util.List; /** * Translates from edit log ops to inotify events. */ @InterfaceAudience.Private public class InotifyFSEditLogOpTranslator { private static long getSize(FSEditLogOp.AddCloseOp acOp) { long size = 0; for (Block b : acOp.getBlocks()) { size += b.getNumBytes(); } return size; } public static EventBatch translate(FSEditLogOp op) { switch(op.opCode) { case OP_ADD: FSEditLogOp.AddOp addOp = (FSEditLogOp.AddOp) op; if (addOp.blocks.length == 0) { // create return new EventBatch(op.txid, new Event[] { new Event.CreateEvent.Builder().path(addOp.path) .ctime(addOp.atime) .replication(addOp.replication) .ownerName(addOp.permissions.getUserName()) .groupName(addOp.permissions.getGroupName()) .perms(addOp.permissions.getPermission()) .overwrite(addOp.overwrite) .defaultBlockSize(addOp.blockSize) .iNodeType(Event.CreateEvent.INodeType.FILE).build() }); } else { // append return new EventBatch(op.txid, new Event[]{new Event.AppendEvent.Builder() .path(addOp.path) .build()}); } case OP_CLOSE: FSEditLogOp.CloseOp cOp = (FSEditLogOp.CloseOp) op; return new EventBatch(op.txid, new Event[] { new Event.CloseEvent(cOp.path, getSize(cOp), cOp.mtime) }); case OP_APPEND: FSEditLogOp.AppendOp appendOp = (FSEditLogOp.AppendOp) op; return new EventBatch(op.txid, new Event[] {new Event.AppendEvent .Builder().path(appendOp.path).newBlock(appendOp.newBlock).build()}); case OP_SET_REPLICATION: FSEditLogOp.SetReplicationOp setRepOp = (FSEditLogOp.SetReplicationOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.REPLICATION) .path(setRepOp.path) .replication(setRepOp.replication).build() }); case OP_CONCAT_DELETE: FSEditLogOp.ConcatDeleteOp cdOp = (FSEditLogOp.ConcatDeleteOp) op; List<Event> events = Lists.newArrayList(); events.add(new Event.AppendEvent.Builder() .path(cdOp.trg) .build()); for (String src : cdOp.srcs) { events.add(new Event.UnlinkEvent.Builder() .path(src) .timestamp(cdOp.timestamp) .build()); } events.add(new Event.CloseEvent(cdOp.trg, -1, cdOp.timestamp)); return new EventBatch(op.txid, events.toArray(new Event[0])); case OP_RENAME_OLD: FSEditLogOp.RenameOldOp rnOpOld = (FSEditLogOp.RenameOldOp) op; return new EventBatch(op.txid, new Event[] { new Event.RenameEvent.Builder() .srcPath(rnOpOld.src) .dstPath(rnOpOld.dst) .timestamp(rnOpOld.timestamp) .build() }); case OP_RENAME: FSEditLogOp.RenameOp rnOp = (FSEditLogOp.RenameOp) op; return new EventBatch(op.txid, new Event[] { new Event.RenameEvent.Builder() .srcPath(rnOp.src) .dstPath(rnOp.dst) .timestamp(rnOp.timestamp) .build() }); case OP_DELETE: FSEditLogOp.DeleteOp delOp = (FSEditLogOp.DeleteOp) op; return new EventBatch(op.txid, new Event[] { new Event.UnlinkEvent.Builder() .path(delOp.path) .timestamp(delOp.timestamp) .build() }); case OP_MKDIR: FSEditLogOp.MkdirOp mkOp = (FSEditLogOp.MkdirOp) op; return new EventBatch(op.txid, new Event[] { new Event.CreateEvent.Builder().path(mkOp.path) .ctime(mkOp.timestamp) .ownerName(mkOp.permissions.getUserName()) .groupName(mkOp.permissions.getGroupName()) .perms(mkOp.permissions.getPermission()) .iNodeType(Event.CreateEvent.INodeType.DIRECTORY).build() }); case OP_SET_PERMISSIONS: FSEditLogOp.SetPermissionsOp permOp = (FSEditLogOp.SetPermissionsOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.PERMS) .path(permOp.src) .perms(permOp.permissions).build() }); case OP_SET_OWNER: FSEditLogOp.SetOwnerOp ownOp = (FSEditLogOp.SetOwnerOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.OWNER) .path(ownOp.src) .ownerName(ownOp.username).groupName(ownOp.groupname).build() }); case OP_TIMES: FSEditLogOp.TimesOp timesOp = (FSEditLogOp.TimesOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.TIMES) .path(timesOp.path) .atime(timesOp.atime).mtime(timesOp.mtime).build() }); case OP_SYMLINK: FSEditLogOp.SymlinkOp symOp = (FSEditLogOp.SymlinkOp) op; return new EventBatch(op.txid, new Event[] { new Event.CreateEvent.Builder().path(symOp.path) .ctime(symOp.atime) .ownerName(symOp.permissionStatus.getUserName()) .groupName(symOp.permissionStatus.getGroupName()) .perms(symOp.permissionStatus.getPermission()) .symlinkTarget(symOp.value) .iNodeType(Event.CreateEvent.INodeType.SYMLINK).build() }); case OP_REMOVE_XATTR: FSEditLogOp.RemoveXAttrOp rxOp = (FSEditLogOp.RemoveXAttrOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.XATTRS) .path(rxOp.src) .xAttrs(rxOp.xAttrs) .xAttrsRemoved(true).build() }); case OP_SET_XATTR: FSEditLogOp.SetXAttrOp sxOp = (FSEditLogOp.SetXAttrOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.XATTRS) .path(sxOp.src) .xAttrs(sxOp.xAttrs) .xAttrsRemoved(false).build() }); case OP_SET_ACL: FSEditLogOp.SetAclOp saOp = (FSEditLogOp.SetAclOp) op; return new EventBatch(op.txid, new Event[] { new Event.MetadataUpdateEvent.Builder() .metadataType(Event.MetadataUpdateEvent.MetadataType.ACLS) .path(saOp.src) .acls(saOp.aclEntries).build() }); default: return null; } } }