/**
   * Update Quota Directory for a file share
   *
   * <p>NOTE: This is an asynchronous operation.
   *
   * @param id the URN of a ViPR Quota directory
   * @param param File system Quota directory update parameters
   * @brief Update file system Quota directory
   * @return Task resource representation
   * @throws com.emc.storageos.svcs.errorhandling.resources.InternalException
   */
  @POST
  @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{id}")
  @CheckPermission(
      roles = {Role.TENANT_ADMIN},
      acls = {ACL.OWN, ACL.ALL})
  public TaskResourceRep updateQuotaDirectory(
      @PathParam("id") URI id, QuotaDirectoryUpdateParam param) throws InternalException {
    _log.info("FileService::Update Quota directory Request recieved {}", id);

    QuotaDirectory quotaDir = queryResource(id);

    String task = UUID.randomUUID().toString();

    if (param.getSecurityStyle() != null) {
      ArgValidator.checkFieldValueFromEnum(
          param.getSecurityStyle(),
          "security_style",
          EnumSet.allOf(QuotaDirectory.SecurityStyles.class));
    }

    // Get the FileSystem object
    FileShare fs = queryFileShareResource(quotaDir.getParent().getURI());
    ArgValidator.checkFieldNotNull(fs, "filesystem");

    // Update the quota directory object to store in ViPR database
    quotaDir.setOpStatus(new OpStatusMap());

    // Set all other optional parameters too.
    if (param.getOpLock() != null) {
      quotaDir.setOpLock(param.getOpLock());
    }

    if (param.getSecurityStyle() != null) {
      quotaDir.setSecurityStyle(param.getSecurityStyle());
    }

    if (param.getSize() != null) {
      Long quotaSize = SizeUtil.translateSize(param.getSize());
      if (quotaSize > 0) {
        ArgValidator.checkFieldMaximum(quotaSize, fs.getCapacity(), " Bytes", "size");
        quotaDir.setSize(quotaSize);
      }
    }

    Operation op = new Operation();
    op.setResourceType(ResourceOperationTypeEnum.UPDATE_FILE_SYSTEM_QUOTA_DIR);
    quotaDir.getOpStatus().createTaskStatus(task, op);
    fs.setOpStatus(new OpStatusMap());
    fs.getOpStatus().createTaskStatus(task, op);
    _dbClient.persistObject(fs);
    _dbClient.persistObject(quotaDir);

    // Create an object of type "FileShareQtree" to be passed into the south-bound layers.
    FileShareQuotaDirectory qt = new FileShareQuotaDirectory(quotaDir);

    // Now get ready to make calls into the controller
    StorageSystem device = _dbClient.queryObject(StorageSystem.class, fs.getStorageDevice());
    FileController controller = getController(FileController.class, device.getSystemType());
    try {
      controller.updateQuotaDirectory(device.getId(), qt, fs.getId(), task);
    } catch (InternalException e) {
      _log.error("Error during update of Quota Directory {}", e);

      // treating all controller exceptions as internal error for now. controller
      // should discriminate between validation problems vs. internal errors
      throw e;
    }

    auditOp(
        OperationTypeEnum.UPDATE_FILE_SYSTEM_QUOTA_DIR,
        true,
        AuditLogManager.AUDITOP_BEGIN,
        quotaDir.getLabel(),
        quotaDir.getId().toString(),
        fs.getId().toString());

    fs = _dbClient.queryObject(FileShare.class, fs.getId());
    _log.debug(
        "FileService::Quota directory Before sending response, FS ID : {}, Taks : {} ; Status {}",
        fs.getOpStatus().get(task),
        fs.getOpStatus().get(task).getStatus());

    return toTask(quotaDir, task, op);
  }