/**
   * Allocate, initialize and persist state of the Bucket being created.
   *
   * @param param
   * @param project
   * @param tenantOrg
   * @param neighborhood
   * @param vpool
   * @param flags
   * @param placement
   * @return
   */
  private Bucket prepareBucket(
      BucketParam param,
      Project project,
      TenantOrg tenantOrg,
      VirtualArray neighborhood,
      VirtualPool vpool,
      DataObject.Flag[] flags,
      BucketRecommendation placement) {
    _log.debug("Preparing Bucket creation for Param : {}", param);
    StoragePool pool = null;
    Bucket bucket = new Bucket();
    bucket.setId(URIUtil.createId(Bucket.class));
    bucket.setLabel(param.getLabel().replaceAll(SPECIAL_CHAR_REGEX, ""));
    bucket.setHardQuota(SizeUtil.translateSize(param.getHardQuota()));
    bucket.setSoftQuota(SizeUtil.translateSize(param.getSoftQuota()));
    bucket.setRetention(Integer.valueOf(param.getRetention()));
    bucket.setOwner(getOwner(param.getOwner()));
    bucket.setNamespace(tenantOrg.getNamespace());
    bucket.setVirtualPool(param.getVpool());
    if (project != null) {
      bucket.setProject(new NamedURI(project.getId(), bucket.getLabel()));
    }
    bucket.setTenant(new NamedURI(tenantOrg.getId(), param.getLabel()));
    bucket.setVirtualArray(neighborhood.getId());

    if (null != placement.getSourceStoragePool()) {
      pool = _dbClient.queryObject(StoragePool.class, placement.getSourceStoragePool());
      if (null != pool) {
        bucket.setProtocol(new StringSet());
        bucket
            .getProtocol()
            .addAll(
                VirtualPoolUtil.getMatchingProtocols(vpool.getProtocols(), pool.getProtocols()));
      }
    }

    bucket.setStorageDevice(placement.getSourceStorageSystem());
    bucket.setPool(placement.getSourceStoragePool());
    bucket.setOpStatus(new OpStatusMap());

    // Bucket name to be used at Storage System
    String bucketName = project.getLabel() + UNDER_SCORE + param.getLabel();
    bucket.setName(bucketName.replaceAll(SPECIAL_CHAR_REGEX, ""));

    // Update Bucket path
    StringBuilder bucketPath = new StringBuilder();
    bucketPath
        .append(tenantOrg.getNamespace())
        .append(SLASH)
        .append(project.getLabel())
        .append(SLASH)
        .append(param.getLabel());
    bucket.setPath(bucketPath.toString());

    if (flags != null) {
      bucket.addInternalFlags(flags);
    }
    _dbClient.createObject(bucket);
    return bucket;
  }
  /**
   * Creates bucket.
   *
   * <p>NOTE: This is an asynchronous operation.
   *
   * @param param Bucket parameters
   * @param id the URN of a ViPR Project
   * @brief Create Bucket
   * @return Task resource representation
   * @throws InternalException
   */
  @POST
  @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @CheckPermission(
      roles = {Role.TENANT_ADMIN},
      acls = {ACL.OWN, ACL.ALL})
  public TaskResourceRep createBucket(BucketParam param, @QueryParam("project") URI id)
      throws InternalException {
    // check project
    ArgValidator.checkFieldUriType(id, Project.class, "project");

    // Check for all mandatory field
    ArgValidator.checkFieldNotNull(param.getLabel(), "name");

    Project project = _permissionsHelper.getObjectById(id, Project.class);
    ArgValidator.checkEntity(project, id, isIdEmbeddedInURL(id));
    ArgValidator.checkFieldNotNull(project.getTenantOrg(), "project");
    TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, project.getTenantOrg().getURI());

    final String namespace = tenant.getNamespace();
    if (null == namespace || namespace.isEmpty()) {
      throw APIException.badRequests.objNoNamespaceForTenant(tenant.getId());
    }

    // Check if there already exist a bucket with same name in a Project.
    checkForDuplicateName(
        param.getLabel().replaceAll(SPECIAL_CHAR_REGEX, ""),
        Bucket.class,
        id,
        "project",
        _dbClient);

    return initiateBucketCreation(param, project, tenant, null);
  }
  /*
   * POST to create
   */
  @POST
  @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  public TaskResourceRep createFileSystemInternal(FileSystemParam param) {
    TenantOrg tenant = _permissionsHelper.getRootTenant();
    TaskResourceRep rep = null;
    if (!_permissionsHelper.userHasGivenRole(
        getUserFromContext(), tenant.getId(), Role.SYSTEM_ADMIN, Role.TENANT_ADMIN)) {
      rep = new TaskResourceRep();
      _log.error(
          "Unable to process the request as Only [system_admin, tenant_admin] can provision file systems for object");
      rep.setMessage("Only [system_admin, tenant_admin] can provision file systems for object");
      rep.setState(Operation.Status.error.name());
      return rep;
    }
    try {
      rep =
          _fileService.createFSInternal(param, _internalProject, tenant, INTERNAL_FILESHARE_FLAGS);
    } catch (Exception ex) {
      rep = new TaskResourceRep();
      _log.error("Exception occurred while creating file system due to:", ex);
      rep.setMessage(ex.getMessage());
      rep.setState(Operation.Status.error.name());
    }

    return rep;
  }
  /**
   * Prepares and persists the Project/Tenant data.
   *
   * @throws Exception
   */
  private void prepareProjectData() throws Exception {
    TenantOrg tenantOrg = new TenantOrg();
    URI tenantOrgURI = URIUtil.createId(TenantOrg.class);
    tenantOrg.setId(tenantOrgURI);
    _dbClient.createObject(tenantOrg);

    Project proj = new Project();
    projectURI = URIUtil.createId(Project.class);
    String projectLabel = "project";
    proj.setId(projectURI);
    proj.setLabel(projectLabel);
    proj.setTenantOrg(new NamedURI(tenantOrgURI, projectLabel));
    _dbClient.createObject(proj);
  }
  /**
   * Adds the tenant to the vCenter acls if the tenant admin is creating it. This always sets the
   * vCenter tenant (the old deprecated filed to null).
   *
   * @param tenant a valid tenant org if the tenant admin is creating it.
   * @param vcenter the vCenter being created.
   */
  private void addVcenterAclIfTenantAdmin(TenantOrg tenant, Vcenter vcenter) {
    // Always set the deprecated tenant field of a vCenter to null.
    vcenter.setTenant(NullColumnValueGetter.getNullURI());

    if (isSystemAdmin()) {
      return;
    }

    URI tenantId;
    if (tenant != null) {
      tenantId = tenant.getId();
    } else {
      // If the tenant org is not valid, try to use the
      // user's tenant org.
      tenantId = URI.create(getUserFromContext().getTenantId());
    }

    // If the User is an admin in the tenant org, allow the
    // operation otherwise, report the insufficient permission
    // exception.
    if (_permissionsHelper.userHasGivenRole(getUserFromContext(), tenantId, Role.TENANT_ADMIN)) {
      // Generate the acl entry and add to the vCenters acls.
      String aclKey = _permissionsHelper.getTenantUsePermissionKey(tenantId.toString());
      vcenter.addAcl(aclKey, ACL.USE.name());
      _log.debug("Adding {} to the vCenter {} acls", aclKey, vcenter.getLabel());
    }
  }
 /*
  * POST to deactivate filesystem
  */
 @POST
 @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 @Path("/{id}/deactivate")
 public TaskResourceRep deactivateFileSystemInternal(
     @PathParam("id") URI id, FileSystemDeleteParam param) throws InternalException {
   ArgValidator.checkFieldUriType(id, FileShare.class, "id");
   FileShare fs = _fileService.queryResource(id);
   checkFileShareInternal(fs);
   TenantOrg tenant = _permissionsHelper.getRootTenant();
   if (!_permissionsHelper.userHasGivenRole(
       getUserFromContext(), tenant.getId(), Role.SYSTEM_ADMIN, Role.TENANT_ADMIN)) {
     throw APIException.forbidden.onlyAdminsCanDeactivateFileSystems(
         Role.SYSTEM_ADMIN.toString(), Role.TENANT_ADMIN.toString());
   }
   return _fileService.deactivateFileSystem(id, param);
 }
 @Before
 public void setup() {
   _context = new ClassPathXmlApplicationContext("metering-vnxfile-context.xml");
   try {
     ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/dbutils-conf.xml");
     _dbClient = (DbClientImpl) ctx.getBean("dbclient");
     _dbClient = Cassandraforplugin.returnDBClient();
     final TenantOrg tenantorg = new TenantOrg();
     tenantorg.setId(URIUtil.createId(TenantOrg.class));
     tenantorg.setLabel("some org");
     tenantorg.setParentTenant(
         new NamedURI(URIUtil.createId(TenantOrg.class), tenantorg.getLabel()));
     _logger.info("TenantOrg :" + tenantorg.getId());
     _dbClient.persistObject(tenantorg);
     final Project proj = new Project();
     proj.setId(URIUtil.createId(Project.class));
     proj.setLabel("some name");
     proj.setTenantOrg(new NamedURI(tenantorg.getId(), proj.getLabel()));
     _logger.info("Project :" + proj.getId());
     _logger.info("TenantOrg-Proj :" + proj.getTenantOrg());
     _dbClient.persistObject(proj);
     final FileShare fileShare = new FileShare();
     fileShare.setId(URIUtil.createId(FileShare.class));
     fileShare.setLabel("some fileshare");
     fileShare.setNativeGuid("CELERRA+" + serialNumber);
     fileShare.setVirtualPool(URIUtil.createId(VirtualPool.class));
     fileShare.setProject(new NamedURI(proj.getId(), fileShare.getLabel()));
     fileShare.setCapacity(12500L);
     _dbClient.persistObject(fileShare);
   } catch (final Exception ioEx) {
     _logger.error("Exception occurred while persisting objects in db {}", ioEx.getMessage());
     _logger.error(ioEx.getMessage(), ioEx);
   }
 }
  /**
   * Check if the vCenter being updated is used by any of its vCenterDataCenters or clusters or
   * hosts or not. This validates only with respect to the tenant that is being removed from the
   * vCenter acls. If the tenant that is getting removed teh vCenter has any exports with the
   * vCenter's vCenterDataCenter or its clusters or hosts.
   *
   * @param vcenter the vCenter being updated.
   * @param changes new acl assignment changes for the vCenter.
   */
  private void checkVcenterUsage(Vcenter vcenter, ACLAssignmentChanges changes) {
    // Make a copy of the vCenter's existing tenant list.
    List<ACLEntry> existingAclEntries = _permissionsHelper.convertToACLEntries(vcenter.getAcls());
    if (CollectionUtils.isEmpty(existingAclEntries)) {
      // If there no existing acl entries for the vCenter
      // there is nothing to validate if it is in user or not.
      _log.debug("vCenter {} does not have any existing acls", vcenter.getLabel());
      return;
    }

    // If there are no tenants to be removed from the vCenter acls,
    // there is nothing to check for usage.
    if (CollectionUtils.isEmpty(changes.getRemove())) {
      _log.debug("There are not acls to remove from vCenter {}", vcenter.getLabel());
      return;
    }

    Set<String> tenantsInUse = new HashSet<String>();

    Set<URI> removingTenants = _permissionsHelper.getUsageURIsFromAclEntries(changes.getRemove());
    Set<URI> existingTenants = _permissionsHelper.getUsageURIsFromAclEntries(existingAclEntries);

    Iterator<URI> removingTenantsIterator = removingTenants.iterator();
    while (removingTenantsIterator.hasNext()) {
      URI removingTenant = removingTenantsIterator.next();
      if (!existingTenants.contains(removingTenant)) {
        continue;
      }

      // Check if vCenter is in use for the removing tenant or not.
      // This checks for all the datacenters of this vcenter that belong to the
      // removing tenant and finds if the datacenter or it clusters or hosts
      // use the exports from the removing tenant or not.
      if (ComputeSystemHelper.isVcenterInUseForTheTenant(
          _dbClient, vcenter.getId(), removingTenant)) {
        TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, removingTenant);
        tenantsInUse.add(tenant.getLabel());
      }
    }

    if (!CollectionUtils.isEmpty(tenantsInUse)) {
      throw APIException.badRequests.cannotRemoveTenant("vCener", vcenter.getLabel(), tenantsInUse);
    }
  }
  @Override
  public void createGroupSnapshots(
      StorageSystem storage,
      List<URI> snapshotList,
      Boolean createInactive,
      Boolean readOnly,
      TaskCompleter taskCompleter)
      throws DeviceControllerException {
    try {
      URI snapshot = snapshotList.get(0);
      BlockSnapshot snapshotObj = _dbClient.queryObject(BlockSnapshot.class, snapshot);

      Volume volume = _dbClient.queryObject(Volume.class, snapshotObj.getParent());
      TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, volume.getTenant().getURI());
      String tenantName = tenant.getLabel();
      String snapLabelToUse =
          _nameGenerator.generate(
              tenantName,
              snapshotObj.getLabel(),
              snapshot.toString(),
              '-',
              SmisConstants.MAX_SNAPSHOT_NAME_LENGTH);
      String groupName = getConsistencyGroupName(snapshotObj);
      VNXeApiClient apiClient = getVnxeClient(storage);
      VNXeCommandJob job = apiClient.createLunGroupSnap(groupName, snapLabelToUse);
      if (job != null) {
        ControllerServiceImpl.enqueueJob(
            new QueueJob(
                new VNXeBlockCreateCGSnapshotJob(
                    job.getId(), storage.getId(), !createInactive, taskCompleter)));
      }

    } catch (VNXeException e) {
      _log.error("Create volume snapshot got the exception", e);
      taskCompleter.error(_dbClient, e);

    } catch (Exception ex) {
      _log.error("Create volume snapshot got the exception", ex);
      ServiceError error =
          DeviceControllerErrors.vnxe.jobFailed("CreateCGSnapshot", ex.getMessage());
      taskCompleter.error(_dbClient, error);
    }
  }
 @Override
 protected void checkUnManagedVolumeAddedToCG(
     UnManagedVolume unManagedVolume,
     VirtualArray virtualArray,
     TenantOrg tenant,
     Project project,
     VirtualPool vPool) {
   if (VolumeIngestionUtil.checkUnManagedResourceAddedToConsistencyGroup(unManagedVolume)) {
     URI consistencyGroupUri =
         VolumeIngestionUtil.getVplexConsistencyGroup(
             unManagedVolume,
             vPool,
             project.getId(),
             tenant.getId(),
             virtualArray.getId(),
             _dbClient);
     if (null == consistencyGroupUri) {
       _logger.warn(
           "A Consistency Group for the VPLEX volume could not be determined. Skipping Ingestion.");
       throw IngestionException.exceptions
           .unmanagedVolumeVplexConsistencyGroupCouldNotBeIdentified(unManagedVolume.getLabel());
     }
   }
 }
  @Override
  public void createSingleVolumeMirror(
      StorageSystem storage, URI mirror, Boolean createInactive, TaskCompleter taskCompleter)
      throws DeviceControllerException {
    _log.info("createSingleVolumeMirror operation START");
    try {
      BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
      StoragePool targetPool = _dbClient.queryObject(StoragePool.class, mirrorObj.getPool());
      Volume source = _dbClient.queryObject(Volume.class, mirrorObj.getSource());
      TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, source.getTenant().getURI());
      String tenantName = tenant.getLabel();
      String targetLabelToUse =
          _nameGenerator.generate(
              tenantName,
              mirrorObj.getLabel(),
              mirror.toString(),
              '-',
              SmisConstants.MAX_VOLUME_NAME_LENGTH);
      CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(storage);
      CIMArgument[] inArgs = null;
      if (storage.checkIfVmax3()) {
        CIMObjectPath volumeGroupPath = _helper.getVolumeGroupPath(storage, source, targetPool);
        CIMInstance replicaSettingData = getDefaultReplicationSettingData(storage);
        inArgs =
            _helper.getCreateElementReplicaMirrorInputArguments(
                storage,
                source,
                targetPool,
                createInactive,
                targetLabelToUse,
                volumeGroupPath,
                replicaSettingData);
      } else {
        inArgs =
            _helper.getCreateElementReplicaMirrorInputArguments(
                storage, source, targetPool, createInactive, targetLabelToUse);
      }

      CIMArgument[] outArgs = new CIMArgument[5];
      _helper.invokeMethod(
          storage, replicationSvcPath, SmisConstants.CREATE_ELEMENT_REPLICA, inArgs, outArgs);
      CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
      if (job != null) {
        ControllerServiceImpl.enqueueJob(
            new QueueJob(
                new SmisBlockCreateMirrorJob(
                    job, storage.getId(), !createInactive, taskCompleter)));
        // Resynchronizing state applies to the initial copy as well as future
        // re-synchronization's.
        mirrorObj.setSyncState(SynchronizationState.RESYNCHRONIZING.toString());
        _dbClient.persistObject(mirrorObj);
      }
    } catch (final InternalException e) {
      _log.info("Problem making SMI-S call: ", e);
      taskCompleter.error(_dbClient, e);
    } catch (Exception e) {
      _log.info("Problem making SMI-S call: ", e);
      ServiceError serviceError =
          DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
      taskCompleter.error(_dbClient, serviceError);
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see com.emc.storageos.volumecontroller.BlockStorageDevice#doCreateVolumes(com.emc.storageos.db.client.model.StorageSystem,
   * com.emc.storageos.db.client.model.StoragePool, java.lang.String, java.util.List,
   * com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper, com.emc.storageos.volumecontroller.TaskCompleter)
   */
  @Override
  public void doCreateVolumes(
      StorageSystem storageSystem,
      StoragePool storagePool,
      String opId,
      List<Volume> volumes,
      VirtualPoolCapabilityValuesWrapper capabilities,
      TaskCompleter taskCompleter)
      throws DeviceControllerException {
    String label = null;
    Long capacity = null;
    boolean isThinVolume = false;
    boolean opCreationFailed = false;
    StringBuilder logMsgBuilder =
        new StringBuilder(
            String.format(
                "Create Volume Start - Array:%s, Pool:%s",
                storageSystem.getSerialNumber(), storagePool.getNativeGuid()));
    for (Volume volume : volumes) {
      logMsgBuilder.append(
          String.format(
              "%nVolume:%s , IsThinlyProvisioned: %s",
              volume.getLabel(), volume.getThinlyProvisioned()));

      if ((label == null) && (volumes.size() == 1)) {
        String tenantName = "";
        try {
          TenantOrg tenant = dbClient.queryObject(TenantOrg.class, volume.getTenant().getURI());
          tenantName = tenant.getLabel();
        } catch (DatabaseException e) {
          log.error("Error lookup TenantOrb object", e);
        }
        label =
            nameGenerator.generate(
                tenantName,
                volume.getLabel(),
                volume.getId().toString(),
                '-',
                HDSConstants.MAX_VOLUME_NAME_LENGTH);
      }

      if (capacity == null) {
        capacity = volume.getCapacity();
      }
      isThinVolume = volume.getThinlyProvisioned();
    }
    log.info(logMsgBuilder.toString());
    try {
      multiVolumeCheckForHitachiModel(volumes, storageSystem);

      HDSApiClient hdsApiClient =
          hdsApiFactory.getClient(
              HDSUtils.getHDSServerManagementServerInfo(storageSystem),
              storageSystem.getSmisUserName(),
              storageSystem.getSmisPassword());
      String systemObjectID = HDSUtils.getSystemObjectID(storageSystem);
      String poolObjectID = HDSUtils.getPoolObjectID(storagePool);
      String asyncTaskMessageId = null;

      // isThinVolume = true, creates VirtualVolumes
      // isThinVolume = false, creates LogicalUnits
      if (isThinVolume) {
        asyncTaskMessageId =
            hdsApiClient.createThinVolumes(
                systemObjectID,
                storagePool.getNativeId(),
                capacity,
                volumes.size(),
                label,
                QUICK_FORMAT_TYPE,
                storageSystem.getModel());
      } else if (!isThinVolume) {
        asyncTaskMessageId =
            hdsApiClient.createThickVolumes(
                systemObjectID,
                poolObjectID,
                capacity,
                volumes.size(),
                label,
                null,
                storageSystem.getModel(),
                null);
      }

      if (asyncTaskMessageId != null) {
        HDSJob createHDSJob =
            (volumes.size() > 1)
                ? new HDSCreateMultiVolumeJob(
                    asyncTaskMessageId,
                    volumes.get(0).getStorageController(),
                    storagePool.getId(),
                    volumes.size(),
                    taskCompleter)
                : new HDSCreateVolumeJob(
                    asyncTaskMessageId,
                    volumes.get(0).getStorageController(),
                    storagePool.getId(),
                    taskCompleter);
        ControllerServiceImpl.enqueueJob(new QueueJob(createHDSJob));
      }
    } catch (final InternalException e) {
      log.error("Problem in doCreateVolumes: ", e);
      opCreationFailed = true;
      taskCompleter.error(dbClient, e);
    } catch (final Exception e) {
      log.error("Problem in doCreateVolumes: ", e);
      opCreationFailed = true;
      ServiceError serviceError =
          DeviceControllerErrors.hds.methodFailed("doCreateVolumes", e.getMessage());
      taskCompleter.error(dbClient, serviceError);
    }
    if (opCreationFailed) {
      for (Volume vol : volumes) {
        vol.setInactive(true);
        dbClient.persistObject(vol);
      }
    }

    logMsgBuilder =
        new StringBuilder(
            String.format(
                "Create Volumes End - Array:%s, Pool:%s",
                storageSystem.getSerialNumber(), storagePool.getNativeGuid()));
    for (Volume volume : volumes) {
      logMsgBuilder.append(String.format("%nVolume:%s", volume.getLabel()));
    }
    log.info(logMsgBuilder.toString());
  }
  private TaskResourceRep initiateBucketCreation(
      BucketParam param, Project project, TenantOrg tenant, DataObject.Flag[] flags)
      throws InternalException {
    ArgValidator.checkFieldUriType(param.getVpool(), VirtualPool.class, "vpool");
    ArgValidator.checkFieldUriType(param.getVarray(), VirtualArray.class, "varray");

    Long softQuota = SizeUtil.translateSize(param.getSoftQuota());
    Long hardQuota = SizeUtil.translateSize(param.getHardQuota());
    Integer retention = Integer.valueOf(param.getRetention());

    // Hard Quota should be more than SoftQuota
    verifyQuotaValues(softQuota, hardQuota, param.getLabel());

    // check varray
    VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, param.getVarray());
    ArgValidator.checkEntity(neighborhood, param.getVarray(), false);
    _permissionsHelper.checkTenantHasAccessToVirtualArray(tenant.getId(), neighborhood);

    // check vpool reference
    VirtualPool cos = _dbClient.queryObject(VirtualPool.class, param.getVpool());
    _permissionsHelper.checkTenantHasAccessToVirtualPool(tenant.getId(), cos);
    ArgValidator.checkEntity(cos, param.getVpool(), false);
    if (!VirtualPool.Type.object.name().equals(cos.getType())) {
      throw APIException.badRequests.virtualPoolNotForObjectStorage(VirtualPool.Type.object.name());
    }

    // verify retention. Its validated only if Retention is configured.
    if (retention != 0 && cos.getMaxRetention() != 0 && retention > cos.getMaxRetention()) {
      throw APIException.badRequests.insufficientRetentionForVirtualPool(cos.getLabel(), "bucket");
    }

    VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper();

    capabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, Integer.valueOf(1));
    capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.FALSE);

    List<BucketRecommendation> placement =
        _bucketScheduler.placeBucket(neighborhood, cos, capabilities);
    if (placement.isEmpty()) {
      throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray(
          cos.getId(), neighborhood.getId());
    }

    // Randomly select a recommended pool
    Collections.shuffle(placement);
    BucketRecommendation recommendation = placement.get(0);

    String task = UUID.randomUUID().toString();
    Bucket bucket = prepareBucket(param, project, tenant, neighborhood, cos, flags, recommendation);

    _log.info(
        String.format(
            "createBucket --- Bucket: %1$s, StoragePool: %2$s, StorageSystem: %3$s",
            bucket.getId(),
            recommendation.getSourceStoragePool(),
            recommendation.getSourceStorageSystem()));

    Operation op =
        _dbClient.createTaskOpStatus(
            Bucket.class, bucket.getId(), task, ResourceOperationTypeEnum.CREATE_BUCKET);
    op.setDescription("Bucket Create");

    // Controller invocation
    StorageSystem system =
        _dbClient.queryObject(StorageSystem.class, recommendation.getSourceStorageSystem());
    ObjectController controller = getController(ObjectController.class, system.getSystemType());
    controller.createBucket(
        recommendation.getSourceStorageSystem(),
        recommendation.getSourceStoragePool(),
        bucket.getId(),
        bucket.getName(),
        bucket.getNamespace(),
        bucket.getRetention(),
        bucket.getHardQuota(),
        bucket.getSoftQuota(),
        bucket.getOwner(),
        task);

    auditOp(
        OperationTypeEnum.CREATE_BUCKET,
        true,
        AuditLogManager.AUDITOP_BEGIN,
        param.getLabel(),
        param.getHardQuota(),
        neighborhood.getId().toString(),
        project == null ? null : project.getId().toString());

    return toTask(bucket, task, op);
  }
  /**
   * Release a file system from its current tenant & project for internal object usage
   *
   * @param id the URN of a ViPR file system to be released
   * @return the updated file system
   * @throws InternalException
   */
  @POST
  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
  @Path("/{id}/release")
  public FileShareRestRep releaseFileSystemInternal(@PathParam("id") URI id)
      throws InternalException {

    ArgValidator.checkFieldUriType(id, FileShare.class, "id");
    FileShare fs = _fileService.queryResource(id);

    // if the FS is already marked as internal, we can skip all this logic
    // and just return success down at the bottom
    if (!fs.checkInternalFlags(Flag.INTERNAL_OBJECT)) {
      URI tenantURI = fs.getTenant().getURI();
      if (!_permissionsHelper.userHasGivenRole(
          getUserFromContext(), tenantURI, Role.TENANT_ADMIN)) {
        throw APIException.forbidden.onlyAdminsCanReleaseFileSystems(Role.TENANT_ADMIN.toString());
      }

      // we can't release a fs that has exports
      FSExportMap exports = fs.getFsExports();
      if ((exports != null) && (!exports.isEmpty())) {
        throw APIException.badRequests.cannotReleaseFileSystemExportExists(
            exports.keySet().toString());
      }

      // we can't release a fs that has shares
      SMBShareMap shares = fs.getSMBFileShares();
      if ((shares != null) && (!shares.isEmpty())) {
        throw APIException.badRequests.cannotReleaseFileSystemSharesExists(
            shares.keySet().toString());
      }

      // files systems with pending operations can't be released
      if (fs.getOpStatus() != null) {
        for (String opId : fs.getOpStatus().keySet()) {
          Operation op = fs.getOpStatus().get(opId);
          if (Operation.Status.pending.name().equals(op.getStatus())) {
            throw APIException.badRequests.cannotReleaseFileSystemWithTasksPending();
          }
        }
      }

      // file systems with snapshots can't be released
      Integer snapCount = _fileService.getNumSnapshots(fs);
      if (snapCount > 0) {
        throw APIException.badRequests.cannotReleaseFileSystemSnapshotExists(snapCount);
      }

      TenantOrg rootTenant = _permissionsHelper.getRootTenant();

      // we can't release the file system to the root tenant if the root tenant has no access
      // to the filesystem's virtual pool
      ArgValidator.checkFieldNotNull(fs.getVirtualPool(), "virtualPool");
      VirtualPool virtualPool =
          _permissionsHelper.getObjectById(fs.getVirtualPool(), VirtualPool.class);
      ArgValidator.checkEntity(virtualPool, fs.getVirtualPool(), false);
      if (!_permissionsHelper.tenantHasUsageACL(rootTenant.getId(), virtualPool)) {
        throw APIException.badRequests.cannotReleaseFileSystemRootTenantLacksVPoolACL(
            virtualPool.getId().toString());
      }

      fs.setOriginalProject(fs.getProject().getURI());
      fs.setTenant(new NamedURI(rootTenant.getId(), fs.getLabel()));
      fs.setProject(new NamedURI(_internalProject.getId(), fs.getLabel()));
      fs.addInternalFlags(INTERNAL_FILESHARE_FLAGS);
      _dbClient.updateAndReindexObject(fs);

      // audit against the source project, not the new dummy internal project
      auditOp(
          OperationTypeEnum.RELEASE_FILE_SYSTEM,
          true,
          null,
          fs.getId().toString(),
          fs.getOriginalProject().toString());
    }

    return map(fs);
  }
 // replace all Special Characters ; /-+!@#$%^&())";:[]{}\ |
 public String getTenantNameWithNoSpecialCharacters() {
   return stripSpecialCharacters(tenantOrg.getLabel());
 }