All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hotels.bdp.circustrain.s3mapreducecp.CopyListingFileStatus Maven / Gradle / Ivy

/**
 * Copyright (C) 2016-2017 Expedia Inc and Apache Hadoop contributors.
 *
 * Based on {@code org.apache.hadoop.tools.CopyListingFileStatus} from Hadoop DistCp 2.7.1:
 *
 * https://github.com/apache/hadoop/blob/release-2.7.1/hadoop-tools/hadoop-distcp/src/main/java/org/apache/
 * hadoop/tools/CopyListingFileStatus.java
 *
 * Licensed 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 com.hotels.bdp.circustrain.s3mapreducecp;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.permission.AclEntryScope;
import org.apache.hadoop.fs.permission.AclEntryType;
import org.apache.hadoop.fs.permission.AclUtil;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.io.WritableUtils;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * CopyListingFileStatus is a specialized subclass of {@link FileStatus} for attaching additional data members useful to
 * S3MapReduceCp. This class does not override {@link FileStatus#compareTo}, because the additional data members are not
 * relevant to sort order.
 */
@InterfaceAudience.Private
public final class CopyListingFileStatus extends FileStatus {

  private static final byte NO_ACL_ENTRIES = -1;
  private static final int NO_XATTRS = -1;

  // Retain static arrays of enum values to prevent repeated allocation of new
  // arrays during deserialization.
  private static final AclEntryType[] ACL_ENTRY_TYPES = AclEntryType.values();
  private static final AclEntryScope[] ACL_ENTRY_SCOPES = AclEntryScope.values();
  private static final FsAction[] FS_ACTIONS = FsAction.values();

  private List aclEntries;
  private Map xAttrs;

  /**
   * Default constructor.
   */
  public CopyListingFileStatus() {}

  /**
   * Creates a new CopyListingFileStatus by copying the members of the given FileStatus.
   *
   * @param fileStatus FileStatus to copy
   */
  public CopyListingFileStatus(FileStatus fileStatus) throws IOException {
    super(fileStatus);
  }

  /**
   * Returns the full logical ACL.
   *
   * @return List containing full logical ACL
   */
  public List getAclEntries() {
    return AclUtil
        .getAclFromPermAndEntries(getPermission(), aclEntries != null ? aclEntries : Collections.emptyList());
  }

  /**
   * Sets optional ACL entries.
   *
   * @param aclEntries List containing all ACL entries
   */
  public void setAclEntries(List aclEntries) {
    this.aclEntries = aclEntries;
  }

  /**
   * Returns all xAttrs.
   *
   * @return Map containing all xAttrs
   */
  public Map getXAttrs() {
    return xAttrs != null ? xAttrs : Collections.emptyMap();
  }

  /**
   * Sets optional xAttrs.
   *
   * @param xAttrs Map containing all xAttrs
   */
  public void setXAttrs(Map xAttrs) {
    this.xAttrs = xAttrs;
  }

  @Override
  public void write(DataOutput out) throws IOException {
    super.write(out);
    if (aclEntries != null) {
      // byte is sufficient, because 32 ACL entries is the max enforced by HDFS.
      out.writeByte(aclEntries.size());
      for (AclEntry entry : aclEntries) {
        out.writeByte(entry.getScope().ordinal());
        out.writeByte(entry.getType().ordinal());
        WritableUtils.writeString(out, entry.getName());
        out.writeByte(entry.getPermission().ordinal());
      }
    } else {
      out.writeByte(NO_ACL_ENTRIES);
    }

    if (xAttrs != null) {
      out.writeInt(xAttrs.size());
      Iterator> iter = xAttrs.entrySet().iterator();
      while (iter.hasNext()) {
        Entry entry = iter.next();
        WritableUtils.writeString(out, entry.getKey());
        final byte[] value = entry.getValue();
        if (value != null) {
          out.writeInt(value.length);
          if (value.length > 0) {
            out.write(value);
          }
        } else {
          out.writeInt(-1);
        }
      }
    } else {
      out.writeInt(NO_XATTRS);
    }
  }

  @Override
  public void readFields(DataInput in) throws IOException {
    super.readFields(in);
    byte aclEntriesSize = in.readByte();
    if (aclEntriesSize != NO_ACL_ENTRIES) {
      aclEntries = Lists.newArrayListWithCapacity(aclEntriesSize);
      for (int i = 0; i < aclEntriesSize; ++i) {
        aclEntries
            .add(new AclEntry.Builder()
                .setScope(ACL_ENTRY_SCOPES[in.readByte()])
                .setType(ACL_ENTRY_TYPES[in.readByte()])
                .setName(WritableUtils.readString(in))
                .setPermission(FS_ACTIONS[in.readByte()])
                .build());
      }
    } else {
      aclEntries = null;
    }

    int xAttrsSize = in.readInt();
    if (xAttrsSize != NO_XATTRS) {
      xAttrs = Maps.newHashMap();
      for (int i = 0; i < xAttrsSize; ++i) {
        final String name = WritableUtils.readString(in);
        final int valueLen = in.readInt();
        byte[] value = null;
        if (valueLen > -1) {
          value = new byte[valueLen];
          if (valueLen > 0) {
            in.readFully(value);
          }
        }
        xAttrs.put(name, value);
      }
    } else {
      xAttrs = null;
    }
  }

  @Override
  public boolean equals(Object o) {
    if (!super.equals(o)) {
      return false;
    }
    if (getClass() != o.getClass()) {
      return false;
    }
    CopyListingFileStatus other = (CopyListingFileStatus) o;
    return Objects.equal(aclEntries, other.aclEntries) && Objects.equal(xAttrs, other.xAttrs);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(super.hashCode(), aclEntries, xAttrs);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder(super.toString());
    sb.append('{');
    sb.append("aclEntries = " + aclEntries);
    sb.append(", xAttrs = " + xAttrs);
    sb.append('}');
    return sb.toString();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy