@Test void buildTestWhenNoVolumesAtAll() throws Exception { Group group = createGroup(emptyList(), Map.of(AwsInstanceTemplate.EBS_ENCRYPTION_ENABLED, false)); when(encryptedSnapshotService.isEncryptedVolumeRequested(group)).thenReturn(false); List<CloudResource> result = underTest.build(awsContext, PRIVATE_ID, authenticatedContext, group, emptyList(), cloudStack); assertThat(result).isEmpty(); verify(encryptedSnapshotService, never()).createSnapshotIfNeeded(authenticatedContext, cloudStack, group, resourceNotifier); }
@Override public List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group, List<CloudResource> buildableResource, CloudStack cloudStack) throws Exception { LOGGER.debug("Create volumes on provider"); AmazonEc2RetryClient client = getAmazonEC2Client(auth); Map<String, List<Volume>> volumeSetMap = Collections.synchronizedMap(new HashMap<>()); List<Future<?>> futures = new ArrayList<>(); String snapshotId = getEbsSnapshotIdIfNeeded(auth, cloudStack, group); boolean encryptedVolumeUsingFastApproach = isEncryptedVolumeUsingFastApproachRequested(group); String volumeEncryptionKey = getVolumeEncryptionKey(group, encryptedVolumeUsingFastApproach); TagSpecification tagSpecification = new TagSpecification() .withResourceType(com.amazonaws.services.ec2.model.ResourceType.Volume) .withTags(awsTaggingService.prepareEc2Tags(auth, cloudStack.getTags())); List<CloudResource> requestedResources = buildableResource.stream() .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus())) .collect(Collectors.toList()); Long ephemeralCount = group.getReferenceInstanceTemplate().getVolumes().stream() .filter(vol -> AwsDiskType.Ephemeral.value().equalsIgnoreCase(vol.getType())).collect(Collectors.counting()); LOGGER.debug("Start creating data volumes for stack: '{}' group: '{}'", auth.getCloudContext().getName(), group.getName()); for (CloudResource resource : requestedResources) { volumeSetMap.put(resource.getName(), Collections.synchronizedList(new ArrayList<>())); VolumeSetAttributes volumeSet = resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class); DeviceNameGenerator generator = new DeviceNameGenerator(DEVICE_NAME_TEMPLATE, ephemeralCount.intValue()); futures.addAll(volumeSet.getVolumes().stream() .map(createVolumeRequest(snapshotId, encryptedVolumeUsingFastApproach, volumeEncryptionKey, tagSpecification, volumeSet)) .map(request -> intermediateBuilderExecutor.submit(() -> { CreateVolumeResult result = client.createVolume(request); String volumeId = result.getVolume().getVolumeId(); Volume volume = new Volume(volumeId, generator.next(), request.getSize(), request.getVolumeType()); volumeSetMap.get(resource.getName()).add(volume); })) .collect(Collectors.toList())); } for (Future<?> future : futures) { future.get(); } return buildableResource.stream() .peek(resource -> { List<Volume> volumes = volumeSetMap.get(resource.getName()); if (!CollectionUtils.isEmpty(volumes)) { resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class).setVolumes(volumes); } }) .map(copyResourceWithNewStatus(CommonStatus.CREATED)) .collect(Collectors.toList()); }
AwsVolumeResourceBuilder extends AbstractAwsComputeBuilder { @Override public List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group, List<CloudResource> buildableResource, CloudStack cloudStack) throws Exception { LOGGER.debug("Create volumes on provider"); AmazonEc2RetryClient client = getAmazonEC2Client(auth); Map<String, List<Volume>> volumeSetMap = Collections.synchronizedMap(new HashMap<>()); List<Future<?>> futures = new ArrayList<>(); String snapshotId = getEbsSnapshotIdIfNeeded(auth, cloudStack, group); boolean encryptedVolumeUsingFastApproach = isEncryptedVolumeUsingFastApproachRequested(group); String volumeEncryptionKey = getVolumeEncryptionKey(group, encryptedVolumeUsingFastApproach); TagSpecification tagSpecification = new TagSpecification() .withResourceType(com.amazonaws.services.ec2.model.ResourceType.Volume) .withTags(awsTaggingService.prepareEc2Tags(auth, cloudStack.getTags())); List<CloudResource> requestedResources = buildableResource.stream() .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus())) .collect(Collectors.toList()); Long ephemeralCount = group.getReferenceInstanceTemplate().getVolumes().stream() .filter(vol -> AwsDiskType.Ephemeral.value().equalsIgnoreCase(vol.getType())).collect(Collectors.counting()); LOGGER.debug("Start creating data volumes for stack: '{}' group: '{}'", auth.getCloudContext().getName(), group.getName()); for (CloudResource resource : requestedResources) { volumeSetMap.put(resource.getName(), Collections.synchronizedList(new ArrayList<>())); VolumeSetAttributes volumeSet = resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class); DeviceNameGenerator generator = new DeviceNameGenerator(DEVICE_NAME_TEMPLATE, ephemeralCount.intValue()); futures.addAll(volumeSet.getVolumes().stream() .map(createVolumeRequest(snapshotId, encryptedVolumeUsingFastApproach, volumeEncryptionKey, tagSpecification, volumeSet)) .map(request -> intermediateBuilderExecutor.submit(() -> { CreateVolumeResult result = client.createVolume(request); String volumeId = result.getVolume().getVolumeId(); Volume volume = new Volume(volumeId, generator.next(), request.getSize(), request.getVolumeType()); volumeSetMap.get(resource.getName()).add(volume); })) .collect(Collectors.toList())); } for (Future<?> future : futures) { future.get(); } return buildableResource.stream() .peek(resource -> { List<Volume> volumes = volumeSetMap.get(resource.getName()); if (!CollectionUtils.isEmpty(volumes)) { resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class).setVolumes(volumes); } }) .map(copyResourceWithNewStatus(CommonStatus.CREATED)) .collect(Collectors.toList()); } }
AwsVolumeResourceBuilder extends AbstractAwsComputeBuilder { @Override public List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group, List<CloudResource> buildableResource, CloudStack cloudStack) throws Exception { LOGGER.debug("Create volumes on provider"); AmazonEc2RetryClient client = getAmazonEC2Client(auth); Map<String, List<Volume>> volumeSetMap = Collections.synchronizedMap(new HashMap<>()); List<Future<?>> futures = new ArrayList<>(); String snapshotId = getEbsSnapshotIdIfNeeded(auth, cloudStack, group); boolean encryptedVolumeUsingFastApproach = isEncryptedVolumeUsingFastApproachRequested(group); String volumeEncryptionKey = getVolumeEncryptionKey(group, encryptedVolumeUsingFastApproach); TagSpecification tagSpecification = new TagSpecification() .withResourceType(com.amazonaws.services.ec2.model.ResourceType.Volume) .withTags(awsTaggingService.prepareEc2Tags(auth, cloudStack.getTags())); List<CloudResource> requestedResources = buildableResource.stream() .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus())) .collect(Collectors.toList()); Long ephemeralCount = group.getReferenceInstanceTemplate().getVolumes().stream() .filter(vol -> AwsDiskType.Ephemeral.value().equalsIgnoreCase(vol.getType())).collect(Collectors.counting()); LOGGER.debug("Start creating data volumes for stack: '{}' group: '{}'", auth.getCloudContext().getName(), group.getName()); for (CloudResource resource : requestedResources) { volumeSetMap.put(resource.getName(), Collections.synchronizedList(new ArrayList<>())); VolumeSetAttributes volumeSet = resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class); DeviceNameGenerator generator = new DeviceNameGenerator(DEVICE_NAME_TEMPLATE, ephemeralCount.intValue()); futures.addAll(volumeSet.getVolumes().stream() .map(createVolumeRequest(snapshotId, encryptedVolumeUsingFastApproach, volumeEncryptionKey, tagSpecification, volumeSet)) .map(request -> intermediateBuilderExecutor.submit(() -> { CreateVolumeResult result = client.createVolume(request); String volumeId = result.getVolume().getVolumeId(); Volume volume = new Volume(volumeId, generator.next(), request.getSize(), request.getVolumeType()); volumeSetMap.get(resource.getName()).add(volume); })) .collect(Collectors.toList())); } for (Future<?> future : futures) { future.get(); } return buildableResource.stream() .peek(resource -> { List<Volume> volumes = volumeSetMap.get(resource.getName()); if (!CollectionUtils.isEmpty(volumes)) { resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class).setVolumes(volumes); } }) .map(copyResourceWithNewStatus(CommonStatus.CREATED)) .collect(Collectors.toList()); }  }
AwsVolumeResourceBuilder extends AbstractAwsComputeBuilder { @Override public List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group, List<CloudResource> buildableResource, CloudStack cloudStack) throws Exception { LOGGER.debug("Create volumes on provider"); AmazonEc2RetryClient client = getAmazonEC2Client(auth); Map<String, List<Volume>> volumeSetMap = Collections.synchronizedMap(new HashMap<>()); List<Future<?>> futures = new ArrayList<>(); String snapshotId = getEbsSnapshotIdIfNeeded(auth, cloudStack, group); boolean encryptedVolumeUsingFastApproach = isEncryptedVolumeUsingFastApproachRequested(group); String volumeEncryptionKey = getVolumeEncryptionKey(group, encryptedVolumeUsingFastApproach); TagSpecification tagSpecification = new TagSpecification() .withResourceType(com.amazonaws.services.ec2.model.ResourceType.Volume) .withTags(awsTaggingService.prepareEc2Tags(auth, cloudStack.getTags())); List<CloudResource> requestedResources = buildableResource.stream() .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus())) .collect(Collectors.toList()); Long ephemeralCount = group.getReferenceInstanceTemplate().getVolumes().stream() .filter(vol -> AwsDiskType.Ephemeral.value().equalsIgnoreCase(vol.getType())).collect(Collectors.counting()); LOGGER.debug("Start creating data volumes for stack: '{}' group: '{}'", auth.getCloudContext().getName(), group.getName()); for (CloudResource resource : requestedResources) { volumeSetMap.put(resource.getName(), Collections.synchronizedList(new ArrayList<>())); VolumeSetAttributes volumeSet = resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class); DeviceNameGenerator generator = new DeviceNameGenerator(DEVICE_NAME_TEMPLATE, ephemeralCount.intValue()); futures.addAll(volumeSet.getVolumes().stream() .map(createVolumeRequest(snapshotId, encryptedVolumeUsingFastApproach, volumeEncryptionKey, tagSpecification, volumeSet)) .map(request -> intermediateBuilderExecutor.submit(() -> { CreateVolumeResult result = client.createVolume(request); String volumeId = result.getVolume().getVolumeId(); Volume volume = new Volume(volumeId, generator.next(), request.getSize(), request.getVolumeType()); volumeSetMap.get(resource.getName()).add(volume); })) .collect(Collectors.toList())); } for (Future<?> future : futures) { future.get(); } return buildableResource.stream() .peek(resource -> { List<Volume> volumes = volumeSetMap.get(resource.getName()); if (!CollectionUtils.isEmpty(volumes)) { resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class).setVolumes(volumes); } }) .map(copyResourceWithNewStatus(CommonStatus.CREATED)) .collect(Collectors.toList()); }  @Override List<CloudResource> create(AwsContext context, long privateId, AuthenticatedContext auth, Group group, Image image); @Override List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group,
            List<CloudResource> buildableResource, CloudStack cloudStack); @Override CloudResource delete(AwsContext context, AuthenticatedContext auth, CloudResource resource); @Override ResourceType resourceType(); @Override int order(); }
AwsVolumeResourceBuilder extends AbstractAwsComputeBuilder { @Override public List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group, List<CloudResource> buildableResource, CloudStack cloudStack) throws Exception { LOGGER.debug("Create volumes on provider"); AmazonEc2RetryClient client = getAmazonEC2Client(auth); Map<String, List<Volume>> volumeSetMap = Collections.synchronizedMap(new HashMap<>()); List<Future<?>> futures = new ArrayList<>(); String snapshotId = getEbsSnapshotIdIfNeeded(auth, cloudStack, group); boolean encryptedVolumeUsingFastApproach = isEncryptedVolumeUsingFastApproachRequested(group); String volumeEncryptionKey = getVolumeEncryptionKey(group, encryptedVolumeUsingFastApproach); TagSpecification tagSpecification = new TagSpecification() .withResourceType(com.amazonaws.services.ec2.model.ResourceType.Volume) .withTags(awsTaggingService.prepareEc2Tags(auth, cloudStack.getTags())); List<CloudResource> requestedResources = buildableResource.stream() .filter(cloudResource -> CommonStatus.REQUESTED.equals(cloudResource.getStatus())) .collect(Collectors.toList()); Long ephemeralCount = group.getReferenceInstanceTemplate().getVolumes().stream() .filter(vol -> AwsDiskType.Ephemeral.value().equalsIgnoreCase(vol.getType())).collect(Collectors.counting()); LOGGER.debug("Start creating data volumes for stack: '{}' group: '{}'", auth.getCloudContext().getName(), group.getName()); for (CloudResource resource : requestedResources) { volumeSetMap.put(resource.getName(), Collections.synchronizedList(new ArrayList<>())); VolumeSetAttributes volumeSet = resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class); DeviceNameGenerator generator = new DeviceNameGenerator(DEVICE_NAME_TEMPLATE, ephemeralCount.intValue()); futures.addAll(volumeSet.getVolumes().stream() .map(createVolumeRequest(snapshotId, encryptedVolumeUsingFastApproach, volumeEncryptionKey, tagSpecification, volumeSet)) .map(request -> intermediateBuilderExecutor.submit(() -> { CreateVolumeResult result = client.createVolume(request); String volumeId = result.getVolume().getVolumeId(); Volume volume = new Volume(volumeId, generator.next(), request.getSize(), request.getVolumeType()); volumeSetMap.get(resource.getName()).add(volume); })) .collect(Collectors.toList())); } for (Future<?> future : futures) { future.get(); } return buildableResource.stream() .peek(resource -> { List<Volume> volumes = volumeSetMap.get(resource.getName()); if (!CollectionUtils.isEmpty(volumes)) { resource.getParameter(CloudResource.ATTRIBUTES, VolumeSetAttributes.class).setVolumes(volumes); } }) .map(copyResourceWithNewStatus(CommonStatus.CREATED)) .collect(Collectors.toList()); }  @Override List<CloudResource> create(AwsContext context, long privateId, AuthenticatedContext auth, Group group, Image image); @Override List<CloudResource> build(AwsContext context, long privateId, AuthenticatedContext auth, Group group,
            List<CloudResource> buildableResource, CloudStack cloudStack); @Override CloudResource delete(AwsContext context, AuthenticatedContext auth, CloudResource resource); @Override ResourceType resourceType(); @Override int order();  }