/**
* 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.yarn.server.resourcemanager;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.QueueACL;
import org.junit.Assert;

import org.apache.hadoop.security.authorize.AccessControlList;
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportResponse;
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationRequest;
import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest;
import org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationRequest;
import org.apache.hadoop.yarn.api.records.ApplicationAccessType;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
import org.junit.After;
import org.junit.Test;

public abstract class QueueACLsTestBase extends ACLsTestBase {

  protected static final String QUEUED = "D";
  protected static final String QUEUED1 = "D1";
  private static final String ALL_ACL = "*";
  private static final String NONE_ACL = " ";


  abstract public String getQueueD();

  abstract public String getQueueD1();

  abstract public void updateConfigWithDAndD1Queues(String rootAcl,
      String queueDAcl, String queueD1Acl) throws IOException;

  @After
  public void tearDown() {
    if (resourceManager != null) {
      resourceManager.stop();
    }
  }

  @Test
  public void testApplicationACLs() throws Exception {

    verifyKillAppSuccess(QUEUE_A_USER, QUEUE_A_USER, QUEUEA, true);
    verifyKillAppSuccess(QUEUE_A_USER, QUEUE_A_ADMIN, QUEUEA, true);
    verifyKillAppSuccess(QUEUE_A_USER, COMMON_USER, QUEUEA, true);
    verifyKillAppSuccess(QUEUE_A_USER, ROOT_ADMIN, QUEUEA, true);
    verifyKillAppFailure(QUEUE_A_USER, QUEUE_B_USER, QUEUEA, true);
    verifyKillAppFailure(QUEUE_A_USER, QUEUE_B_ADMIN, QUEUEA, true);

    verifyKillAppSuccess(QUEUE_B_USER, QUEUE_B_USER, QUEUEB, true);
    verifyKillAppSuccess(QUEUE_B_USER, QUEUE_B_ADMIN, QUEUEB, true);
    verifyKillAppSuccess(QUEUE_B_USER, COMMON_USER, QUEUEB, true);
    verifyKillAppSuccess(QUEUE_B_USER, ROOT_ADMIN, QUEUEB, true);

    verifyKillAppFailure(QUEUE_B_USER, QUEUE_A_USER, QUEUEB, true);
    verifyKillAppFailure(QUEUE_B_USER, QUEUE_A_ADMIN, QUEUEB, true);

    verifyKillAppSuccess(ROOT_ADMIN, ROOT_ADMIN, QUEUEA, false);
    verifyKillAppSuccess(ROOT_ADMIN, ROOT_ADMIN, QUEUEB, false);

    verifyGetClientAMToken(QUEUE_A_USER, ROOT_ADMIN, QUEUEA, true);

  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: (none)
   *    D: * (all)
   *      D1: * (all)
   * Expected result: the user will have access only to D and D1 queues.
   * @throws IOException
   */
  @Test
  public void testQueueAclRestrictedRootACL() throws IOException {
    updateConfigWithDAndD1Queues(NONE_ACL, ALL_ACL, ALL_ACL);
    checkAccess(false, true, true);
  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: (none)
   *    D:  (none)
   *      D1:  (none)
   * Expected result: the user will have to none of the queues.
   * @throws IOException
   */
  @Test
  public void testQueueAclNoAccess() throws IOException {
    updateConfigWithDAndD1Queues(NONE_ACL, NONE_ACL, NONE_ACL);
    checkAccess(false, false, false);
  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: (none)
   *    D: * (all)
   *      D1:  (none)
   * Expected result: access to D1 will be permitted by root.D,
   * so the user will be able to access queues D and D1.
   * @throws IOException
   */
  @Test
  public void testQueueAclRestrictedRootAndD1() throws IOException {
    updateConfigWithDAndD1Queues(NONE_ACL, ALL_ACL, NONE_ACL);
    checkAccess(false, true, true);
  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: (none)
   *    D:  (none)
   *      D1:  (all)
   * Expected result: only queue D1 can be accessed.
   * @throws IOException
   */
  @Test
  public void testQueueAclRestrictedRootAndD() throws IOException {
    updateConfigWithDAndD1Queues(NONE_ACL, NONE_ACL, ALL_ACL);
    checkAccess(false, false, true);
  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: * (all)
   *    D:  (none)
   *      D1: * (all)
   * Expected result: access to D will be permitted from the root queue,
   * so the user will be able to access queues root, D and D1.
   * @throws IOException
   */
  @Test
  public void testQueueAclRestrictedD() throws IOException {
    updateConfigWithDAndD1Queues(ALL_ACL, NONE_ACL, ALL_ACL);
    checkAccess(true, true, true);
  }

  /**
   * Test for the case when the following submit application
   * and administer queue ACLs are defined:
   * root: * (all)
   *    D: * (all)
   *      D1:  (none)
   * Expected result: access to D1 will be permitted from queue D,
   * so the user will be able to access queues root, D and D1.
   * @throws IOException
   */
  @Test
  public void testQueueAclRestrictedD1() throws IOException {
    updateConfigWithDAndD1Queues(ALL_ACL, ALL_ACL, NONE_ACL);
    checkAccess(true, true, true);
  }

  /**
   * Test for the case when no ACLs are defined, so the default values are used
   * Expected result: The default ACLs for the root queue is "*"(all) and for
   * the other queues are " " (none), so the user will have access to all the
   * queues because they will have permissions from the root.
   *
   * @throws IOException
   */
  @Test
  public void testQueueAclDefaultValues() throws IOException {
    updateConfigWithDAndD1Queues(null, null, null);
    checkAccess(true, true, true);
  }

  private void checkAccess(boolean rootAccess, boolean dAccess,
          boolean d1Access)throws IOException {
    checkAccess(rootAccess, "root");
    checkAccess(dAccess, getQueueD());
    checkAccess(d1Access, getQueueD1());
  }


  private void checkAccess(boolean access, String queueName)
      throws IOException {
    UserGroupInformation user = UserGroupInformation.getCurrentUser();

    String failureMsg = "Wrong %s access to %s queue";
    Assert.assertEquals(
        String.format(failureMsg, QueueACL.ADMINISTER_QUEUE, queueName),
        access, resourceManager.getResourceScheduler()
        .checkAccess(user, QueueACL.ADMINISTER_QUEUE, queueName));
    Assert.assertEquals(
        String.format(failureMsg, QueueACL.SUBMIT_APPLICATIONS, queueName),
        access, resourceManager.getResourceScheduler()
        .checkAccess(user, QueueACL.SUBMIT_APPLICATIONS, queueName));
  }

  private void verifyGetClientAMToken(String submitter, String queueAdmin,
      String queueName, boolean setupACLs) throws Exception {
    ApplicationId applicationId =
        submitAppAndGetAppId(submitter, queueName, setupACLs);
    final GetApplicationReportRequest appReportRequest =
        GetApplicationReportRequest.newInstance(applicationId);

    ApplicationClientProtocol submitterClient = getRMClientForUser(submitter);
    ApplicationClientProtocol adMinUserClient = getRMClientForUser(queueAdmin);

    GetApplicationReportResponse submitterGetReport =
        submitterClient.getApplicationReport(appReportRequest);
    GetApplicationReportResponse adMinUserGetReport =
        adMinUserClient.getApplicationReport(appReportRequest);

    Assert.assertEquals(submitterGetReport.getApplicationReport()
      .getClientToAMToken(), adMinUserGetReport.getApplicationReport()
      .getClientToAMToken());
  }

  private void verifyKillAppFailure(String submitter, String killer,
      String queueName, boolean setupACLs) throws Exception {

    ApplicationId applicationId =
        submitAppAndGetAppId(submitter, queueName, setupACLs);

    final KillApplicationRequest finishAppRequest =
        KillApplicationRequest.newInstance(applicationId);

    ApplicationClientProtocol killerClient = getRMClientForUser(killer);

    // Kill app as the killer
    try {
      killerClient.forceKillApplication(finishAppRequest);
      Assert.fail("App killing by the enemy should fail!!");
    } catch (YarnException e) {
      LOG.info("Got exception while killing app as the enemy", e);
      Assert.assertTrue(e.getMessage().contains(
        "User " + killer + " cannot perform operation MODIFY_APP on "
            + applicationId));
    }

    getRMClientForUser(submitter).forceKillApplication(finishAppRequest);
  }

  private void verifyKillAppSuccess(String submitter, String killer,
      String queueName, boolean setupACLs) throws Exception {
    ApplicationId applicationId =
        submitAppAndGetAppId(submitter, queueName, setupACLs);

    final KillApplicationRequest finishAppRequest =
        KillApplicationRequest.newInstance(applicationId);

    ApplicationClientProtocol ownerClient = getRMClientForUser(killer);

    // Kill app as killer
    ownerClient.forceKillApplication(finishAppRequest);
    resourceManager.waitForState(applicationId, RMAppState.KILLED);
  }

  private ApplicationId submitAppAndGetAppId(String submitter,
      String queueName, boolean setupACLs) throws Exception {

    GetNewApplicationRequest newAppRequest =
        GetNewApplicationRequest.newInstance();

    ApplicationClientProtocol submitterClient = getRMClientForUser(submitter);
    ApplicationId applicationId =
        submitterClient.getNewApplication(newAppRequest).getApplicationId();

    Resource resource = BuilderUtils.newResource(1024, 1);
    Map<ApplicationAccessType, String> acls = createACLs(submitter, setupACLs);
    ContainerLaunchContext amContainerSpec =
        ContainerLaunchContext.newInstance(null, null, null, null, null, acls);

    ApplicationSubmissionContext appSubmissionContext =
        ApplicationSubmissionContext.newInstance(applicationId,
          "applicationName", queueName, null, amContainerSpec, false, true, 1,
          resource, "applicationType");
    appSubmissionContext.setApplicationId(applicationId);
    appSubmissionContext.setQueue(queueName);

    SubmitApplicationRequest submitRequest =
        SubmitApplicationRequest.newInstance(appSubmissionContext);
    submitterClient.submitApplication(submitRequest);
    resourceManager.waitForState(applicationId, RMAppState.ACCEPTED);
    return applicationId;
  }

  private Map<ApplicationAccessType, String> createACLs(String submitter,
      boolean setupACLs) {
    AccessControlList viewACL = new AccessControlList("");
    AccessControlList modifyACL = new AccessControlList("");
    if (setupACLs) {
      viewACL.addUser(submitter);
      viewACL.addUser(COMMON_USER);
      modifyACL.addUser(submitter);
      modifyACL.addUser(COMMON_USER);
    }
    Map<ApplicationAccessType, String> acls =
        new HashMap<ApplicationAccessType, String>();
    acls.put(ApplicationAccessType.VIEW_APP, viewACL.getAclString());
    acls.put(ApplicationAccessType.MODIFY_APP, modifyACL.getAclString());
    return acls;
  }
}
