/**
 * 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 static org.apache.hadoop.hdfs.server.namenode.AclTestHelpers.*;
import static org.apache.hadoop.fs.permission.AclEntryScope.*;
import static org.apache.hadoop.fs.permission.AclEntryType.*;
import static org.apache.hadoop.fs.permission.FsAction.*;

import java.io.IOException;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.permission.AclStatus;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.collect.Lists;

public class TestFSImageWithAcl {
  private static Configuration conf;
  private static MiniDFSCluster cluster;

  @BeforeClass
  public static void setUp() throws IOException {
    conf = new Configuration();
    conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true);
    cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build();
    cluster.waitActive();
  }

  @AfterClass
  public static void tearDown() {
    if (cluster != null) {
      cluster.shutdown();
    }
  }

  private void testAcl(boolean persistNamespace) throws IOException {
    Path p = new Path("/p");
    DistributedFileSystem fs = cluster.getFileSystem();
    fs.create(p).close();
    fs.mkdirs(new Path("/23"));

    AclEntry e = new AclEntry.Builder().setName("foo")
        .setPermission(READ_EXECUTE).setScope(ACCESS).setType(USER).build();
    fs.modifyAclEntries(p, Lists.newArrayList(e));

    restart(fs, persistNamespace);

    AclStatus s = cluster.getNamesystem().getAclStatus(p.toString());
    AclEntry[] returned = Lists.newArrayList(s.getEntries()).toArray(
        new AclEntry[0]);
    Assert.assertArrayEquals(new AclEntry[] {
        aclEntry(ACCESS, USER, "foo", READ_EXECUTE),
        aclEntry(ACCESS, GROUP, READ) }, returned);

    fs.removeAcl(p);

    if (persistNamespace) {
      fs.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
      fs.saveNamespace();
      fs.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
    }

    cluster.restartNameNode();
    cluster.waitActive();

    s = cluster.getNamesystem().getAclStatus(p.toString());
    returned = Lists.newArrayList(s.getEntries()).toArray(new AclEntry[0]);
    Assert.assertArrayEquals(new AclEntry[] { }, returned);

    fs.modifyAclEntries(p, Lists.newArrayList(e));
    s = cluster.getNamesystem().getAclStatus(p.toString());
    returned = Lists.newArrayList(s.getEntries()).toArray(new AclEntry[0]);
    Assert.assertArrayEquals(new AclEntry[] {
        aclEntry(ACCESS, USER, "foo", READ_EXECUTE),
        aclEntry(ACCESS, GROUP, READ) }, returned);
  }

  @Test
  public void testPersistAcl() throws IOException {
    testAcl(true);
  }

  @Test
  public void testAclEditLog() throws IOException {
    testAcl(false);
  }

  private void doTestDefaultAclNewChildren(boolean persistNamespace)
      throws IOException {
    Path dirPath = new Path("/dir");
    Path filePath = new Path(dirPath, "file1");
    Path subdirPath = new Path(dirPath, "subdir1");
    DistributedFileSystem fs = cluster.getFileSystem();
    fs.mkdirs(dirPath);
    List<AclEntry> aclSpec = Lists.newArrayList(
      aclEntry(DEFAULT, USER, "foo", ALL));
    fs.setAcl(dirPath, aclSpec);

    fs.create(filePath).close();
    fs.mkdirs(subdirPath);

    AclEntry[] fileExpected = new AclEntry[] {
      aclEntry(ACCESS, USER, "foo", ALL),
      aclEntry(ACCESS, GROUP, READ_EXECUTE) };
    AclEntry[] subdirExpected = new AclEntry[] {
      aclEntry(ACCESS, USER, "foo", ALL),
      aclEntry(ACCESS, GROUP, READ_EXECUTE),
      aclEntry(DEFAULT, USER, ALL),
      aclEntry(DEFAULT, USER, "foo", ALL),
      aclEntry(DEFAULT, GROUP, READ_EXECUTE),
      aclEntry(DEFAULT, MASK, ALL),
      aclEntry(DEFAULT, OTHER, READ_EXECUTE) };

    short permExpected = (short)010775;

    AclEntry[] fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    AclEntry[] subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);

    restart(fs, persistNamespace);

    fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);

    aclSpec = Lists.newArrayList(aclEntry(DEFAULT, USER, "foo", READ_WRITE));
    fs.modifyAclEntries(dirPath, aclSpec);

    fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);

    restart(fs, persistNamespace);

    fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);

    fs.removeAcl(dirPath);

    fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);

    restart(fs, persistNamespace);

    fileReturned = fs.getAclStatus(filePath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(fileExpected, fileReturned);
    subdirReturned = fs.getAclStatus(subdirPath).getEntries()
      .toArray(new AclEntry[0]);
    Assert.assertArrayEquals(subdirExpected, subdirReturned);
    assertPermission(fs, subdirPath, permExpected);
  }

  @Test
  public void testFsImageDefaultAclNewChildren() throws IOException {
    doTestDefaultAclNewChildren(true);
  }

  @Test
  public void testEditLogDefaultAclNewChildren() throws IOException {
    doTestDefaultAclNewChildren(false);
  }

  @Test
  public void testRootACLAfterLoadingFsImage() throws IOException {
    DistributedFileSystem fs = cluster.getFileSystem();
    Path rootdir = new Path("/");
    AclEntry e1 = new AclEntry.Builder().setName("foo")
        .setPermission(ALL).setScope(ACCESS).setType(GROUP).build();
    AclEntry e2 = new AclEntry.Builder().setName("bar")
        .setPermission(READ).setScope(ACCESS).setType(GROUP).build();
    fs.modifyAclEntries(rootdir, Lists.newArrayList(e1, e2));

    AclStatus s = cluster.getNamesystem().getAclStatus(rootdir.toString());
    AclEntry[] returned =
        Lists.newArrayList(s.getEntries()).toArray(new AclEntry[0]);
    Assert.assertArrayEquals(
        new AclEntry[] { aclEntry(ACCESS, GROUP, READ_EXECUTE),
            aclEntry(ACCESS, GROUP, "bar", READ),
            aclEntry(ACCESS, GROUP, "foo", ALL) }, returned);

    // restart - hence save and load from fsimage
    restart(fs, true);

    s = cluster.getNamesystem().getAclStatus(rootdir.toString());
    returned = Lists.newArrayList(s.getEntries()).toArray(new AclEntry[0]);
    Assert.assertArrayEquals(
        new AclEntry[] { aclEntry(ACCESS, GROUP, READ_EXECUTE),
            aclEntry(ACCESS, GROUP, "bar", READ),
            aclEntry(ACCESS, GROUP, "foo", ALL) }, returned);
  }

  /**
   * Restart the NameNode, optionally saving a new checkpoint.
   *
   * @param fs DistributedFileSystem used for saving namespace
   * @param persistNamespace boolean true to save a new checkpoint
   * @throws IOException if restart fails
   */
  private void restart(DistributedFileSystem fs, boolean persistNamespace)
      throws IOException {
    if (persistNamespace) {
      fs.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
      fs.saveNamespace();
      fs.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
    }

    cluster.restartNameNode();
    cluster.waitActive();
  }
}
