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); }
/** * Places and prepares the HA volumes when copying a distributed VPLEX volume. * * @param name The base name for the volume. * @param copyCount The number of copies to be made. * @param size The size for the HA volume. * @param vplexSystem A reference to the VPLEX storage system. * @param vplexSystemProject A reference to the VPLEX system project. * @param srcVarray The virtual array for the VPLEX volume being copied. * @param srcHAVolume The HA volume of the VPLEX volume being copied. * @param taskId The task identifier. * @param volumeDescriptors The list of descriptors. * @return A list of the prepared HA volumes for the VPLEX volume copy. */ private List<Volume> prepareFullCopyHAVolumes( String name, int copyCount, Long size, StorageSystem vplexSystem, Project vplexSystemProject, VirtualArray srcVarray, Volume srcHAVolume, String taskId, List<VolumeDescriptor> volumeDescriptors) { List<Volume> copyHAVolumes = new ArrayList<Volume>(); // Get the storage placement recommendations for the volumes. // Placement must occur on the same VPLEX system Set<URI> vplexSystemURIS = new HashSet<URI>(); vplexSystemURIS.add(vplexSystem.getId()); VirtualArray haVarray = _dbClient.queryObject(VirtualArray.class, srcHAVolume.getVirtualArray()); VirtualPool haVpool = _dbClient.queryObject(VirtualPool.class, srcHAVolume.getVirtualPool()); VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper(); haCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, size); haCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, copyCount); VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(srcHAVolume, _dbClient); if (VirtualPool.ProvisioningType.Thin.toString() .equalsIgnoreCase(vpool.getSupportedProvisioningType())) { haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE); // To guarantee that storage pool for a copy has enough physical // space to contain current allocated capacity of thin source volume haCapabilities.put( VirtualPoolCapabilityValuesWrapper.THIN_VOLUME_PRE_ALLOCATE_SIZE, BlockFullCopyUtils.getAllocatedCapacityForFullCopySource(srcHAVolume, _dbClient)); } List<Recommendation> recommendations = ((VPlexScheduler) _scheduler) .scheduleStorageForImport( srcVarray, vplexSystemURIS, haVarray, haVpool, haCapabilities); if (recommendations.isEmpty()) { throw APIException.badRequests.noStorageForHaVolumesForVplexVolumeCopies(); } // Prepare the HA volumes for the VPLEX volume copy. int copyIndex = 1; for (Recommendation recommendation : recommendations) { VPlexRecommendation haRecommendation = (VPlexRecommendation) recommendation; for (int i = 0; i < haRecommendation.getResourceCount(); i++) { // Determine the name for the HA volume copy. StringBuilder nameBuilder = new StringBuilder(name); nameBuilder.append("-1"); if (copyCount > 1) { nameBuilder.append("-"); nameBuilder.append(copyIndex++); } // Prepare the volume. Volume volume = VPlexBlockServiceApiImpl.prepareVolumeForRequest( size, vplexSystemProject, haVarray, haVpool, haRecommendation.getSourceDevice(), haRecommendation.getSourcePool(), nameBuilder.toString(), null, taskId, _dbClient); volume.addInternalFlags(Flag.INTERNAL_OBJECT); _dbClient.persistObject(volume); copyHAVolumes.add(volume); // Create the volume descriptor and add it to the passed list. VolumeDescriptor volumeDescriptor = new VolumeDescriptor( VolumeDescriptor.Type.BLOCK_DATA, volume.getStorageController(), volume.getId(), volume.getPool(), haCapabilities); volumeDescriptors.add(volumeDescriptor); } } return copyHAVolumes; }