public static void validatePermission(@Nullable String tableName, AccessType accessType,
      @Nullable HttpHeaders httpHeaders, String endpointUrl, AccessControl accessControl) {
    String userMessage = getUserMessage(tableName, accessType, endpointUrl);
    String rawTableName = TableNameBuilder.extractRawTableName(tableName);

    try {
      if (rawTableName == null) {
        if (accessControl.hasAccess(accessType, httpHeaders, endpointUrl)) {
          return;
        }
      } else {
        if (accessControl.hasAccess(rawTableName, accessType, httpHeaders, endpointUrl)) {
          return;
        }
      }
    } catch (WebApplicationException exception) {
      // throwing the exception if it's WebApplicationException
      throw exception;
    } catch (Throwable t) {
      // catch and log Throwable for NoSuchMethodError which can happen when there are classpath conflicts
      // otherwise, grizzly will return a 500 without any logs or indication of what failed
      throw new ControllerApplicationException(LOGGER,
          "Caught exception while validating permission for " + userMessage, Response.Status.INTERNAL_SERVER_ERROR, t);
    }

    throw new ControllerApplicationException(LOGGER, "Permission is denied for " + userMessage,
        Response.Status.FORBIDDEN);
  }
@Test
  public void testValidatePermissionDenied() {
    AccessControl ac = Mockito.mock(AccessControl.class);
    HttpHeaders mockHttpHeaders = Mockito.mock(HttpHeaders.class);

    Mockito.when(ac.hasAccess(_table, AccessType.READ, mockHttpHeaders, _endpoint)).thenReturn(false);

    try {
      AccessControlUtils.validatePermission(_table, AccessType.READ, mockHttpHeaders, _endpoint, ac);
      Assert.fail("Expected ControllerApplicationException");
    } catch (ControllerApplicationException e) {
      Assert.assertTrue(e.getMessage().contains("Permission is denied"));
      Assert.assertEquals(e.getResponse().getStatus(), Response.Status.FORBIDDEN.getStatusCode());
    }
  }