1

I'm having difficulties trying to add a new Alternative Domain Name (CNAMEs) to an existing CloudFront resource using the AWS SDK for Java v2.x

This is the code snippet I'm using so far:

// First I get the actual resource from AWS
GetDistributionResponse distributionInformation = cloudFrontclient
        .getDistribution(GetDistributionRequest.builder().id(input.getDistributionId())
        .build());

// Then I extract the part I want to edit
DistributionConfig config = distributionInformation.distribution().distributionConfig();

// so far so good, I'm able to see my data as intended 

// The next thing is to try adding the new alias, and of course I can't as that array is Unmodifiable! 
// Meaning that I'm  always getting an: java.lang.UnsupportedOperationException
config.aliases().items().add(input.getAlternativeDomain()); 

// If the previous line worked or I find an alternative solution I'm planning to make the following update request
UpdateDistributionRequest updateDistributionRequest = UpdateDistributionRequest
                .builder()
                .distributionConfig(config)
                .build();

cloudFrontclient.updateDistribution(updateDistributionRequest);

I'm kind of lost here, I'm not exactly sure how this is supposed to work.

I'll appreciate any help I can get

Thanks in advance

William Añez
  • 730
  • 6
  • 25

2 Answers2

2

I confirmed that the methods that belong to DistributionConfig - even comment - seem to be read-only when you use the object returned from distributionConfig

    Distribution disObject = response.distribution();
    DistributionConfig config = disObject.distributionConfig();

The solution is to create a new DistributionConfig object by using the builder method (see below). Add the new values and then also read in the values that do not change. Otherwise a Java exception is thrown.

Here I add a new comment as an example of modifying a Distribution.

public static void main(String[] args) {

        CloudFrontClient cloudFrontClient = CloudFrontClient.builder()
                .region(Region.AWS_GLOBAL)
                .build();

        try {

            // Lets get the Distribution to modify
            GetDistributionRequest disRequest = GetDistributionRequest.builder()
                    .id("E90U7J6Pxxxxx")
                    .build();

            GetDistributionResponse response = cloudFrontClient.getDistribution(disRequest);
            Distribution disObject = response.distribution();
            DistributionConfig config = disObject.distributionConfig();

            // Create a new  DistributionConfig object and add new values to comment and aliases
            DistributionConfig config1 = DistributionConfig.builder()
                    .aliases(config.aliases()) // You can pass in new values here
                    .comment("New Comment")
                    .cacheBehaviors(config.cacheBehaviors())
                    .priceClass(config.priceClass())
                    .defaultCacheBehavior(config.defaultCacheBehavior())
                    .enabled(config.enabled())
                    .callerReference(config.callerReference())
                    .logging(config.logging())
                    .originGroups(config.originGroups())
                    .origins(config.origins())
                    .restrictions(config.restrictions())
                    .defaultRootObject(config.defaultRootObject())
                    .webACLId(config.webACLId())
                    .httpVersion(config.httpVersion())
                    .viewerCertificate(config.viewerCertificate())
                    .customErrorResponses(config.customErrorResponses())
                    .build();


                UpdateDistributionRequest updateDistributionRequest = UpdateDistributionRequest.builder()
                    .distributionConfig(config1)
                    .id(disObject.id())
                    .ifMatch(response.eTag())
                     .build();

            cloudFrontClient.updateDistribution(updateDistributionRequest);


        } catch (CloudFrontException e){
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}

This worked and you can see the new comment:

enter image description here

smac2020
  • 9,637
  • 4
  • 24
  • 38
  • 1
    Thank you Scott for your reply, I was imagining that this will be the solution and I really appreciate you taking the time to review it, it helped me alot, however I have to say that this is kind of dangerous, I mean, I can see a couple of reasons for having this unmutable in the first place, but it should be also an "API intended mechanism" to adding information to existing resources that avoid the user to be responsable of manually copy all values. Imagine what will happen if tomorrow a new param is added? it will generate problems and developers wont even realized what could be wrong. – William Añez Feb 22 '21 at 12:27
0

Alternative approach...

    DistributionConfig.Builder newConfigBuilder = configResponse.distributionConfig().toBuilder()
    
    //Do what you want with newConfigBuilder
    
    ...
    
    ...
    
    
    DistributionConfig newConfig = newConfigBuilder.build();

https://sdk.amazonaws.com/java/api/latest/

Isaac Pindado
  • 81
  • 1
  • 3