public async Task <Response> Update()
        {
            var oldProps = Request.OldResourceProperties;
            var newProps = Request.ResourceProperties;
            IAmazonCertificateManager acmClient = await acmFactory.Create(newProps.CreationRoleArn);

            Task.WaitAll(new Task[] {
                // add new tags
                Task.Run(async delegate {
                    var upsertTagsResponse = await acmClient.AddTagsToCertificateAsync(new AddTagsToCertificateRequest {
                        Tags           = UpsertedTags.ToList(),
                        CertificateArn = Request.PhysicalResourceId
                    });

                    Console.WriteLine($"Received upsert tags response: {JsonSerializer.Serialize(upsertTagsResponse)}");
                }),

                // delete old tags
                Task.Run(async delegate {
                    var deleteTagsResponse = await acmClient.RemoveTagsFromCertificateAsync(new RemoveTagsFromCertificateRequest {
                        Tags           = DeletedTags.ToList(),
                        CertificateArn = Request.PhysicalResourceId
                    });

                    Console.WriteLine($"Received delete tags response: {JsonSerializer.Serialize(deleteTagsResponse)}");
                }),

                // update options
                Task.Run(async delegate {
                    if (newProps?.Options?.CertificateTransparencyLoggingPreference != oldProps?.Options?.CertificateTransparencyLoggingPreference)
                    {
                        var updateOptionsResponse = await acmClient.UpdateCertificateOptionsAsync(new UpdateCertificateOptionsRequest {
                            CertificateArn = Request.PhysicalResourceId,
                            Options        = newProps?.Options
                        });

                        Console.WriteLine($"Received update options response: {JsonSerializer.Serialize(updateOptionsResponse)}");
                    }
                })
            });

            return(new Response
            {
                PhysicalResourceId = Request.PhysicalResourceId
            });
        }
 private Amazon.CertificateManager.Model.AddTagsToCertificateResponse CallAWSServiceOperation(IAmazonCertificateManager client, Amazon.CertificateManager.Model.AddTagsToCertificateRequest request)
 {
     Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "AWS Certificate Manager", "AddTagsToCertificate");
     try
     {
         #if DESKTOP
         return(client.AddTagsToCertificate(request));
         #elif CORECLR
         return(client.AddTagsToCertificateAsync(request).GetAwaiter().GetResult());
         #else
                 #error "Unknown build edition"
         #endif
     }
     catch (AmazonServiceException exc)
     {
         var webException = exc.InnerException as System.Net.WebException;
         if (webException != null)
         {
             throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
         }
         throw;
     }
 }
        public async Task <Response?> Create()
        {
            var props = Request.ResourceProperties;

            IAmazonCertificateManager acmClient = await acmFactory.Create(props.CreationRoleArn);

            IAmazonRoute53 route53Client = await route53Factory.Create(props.ValidationRoleArn);

            var request = new RequestCertificateRequest
            {
                DomainName       = props.DomainName,
                ValidationMethod = props.ValidationMethod
            };

            if (props.CertificateAuthorityArn != null)
            {
                request.CertificateAuthorityArn = props.CertificateAuthorityArn;
            }
            if (props.DomainValidationOptions != null)
            {
                request.DomainValidationOptions = props.DomainValidationOptions;
            }
            if (props.Options != null)
            {
                request.Options = props.Options;
            }
            if (props.SubjectAlternativeNames != null)
            {
                request.SubjectAlternativeNames = props.SubjectAlternativeNames;
            }

            var requestCertificateResponse = await acmClient.RequestCertificateAsync(request);

            Console.WriteLine($"Got Request Certificate Response: {JsonSerializer.Serialize(requestCertificateResponse)}");

            PhysicalResourceId = requestCertificateResponse.CertificateArn;
            var describeCertificateRequest = new DescribeCertificateRequest {
                CertificateArn = PhysicalResourceId
            };
            var tasks = new List <Task>();

            Thread.Sleep(500);
            bool foundValidationOptions = false;
            List <DomainValidation> validationOptions = new List <DomainValidation>();

            // For some reason, the domain validation options aren't immediately populated.
            while (!foundValidationOptions)
            {
                var describeCertificateResponse = await acmClient.DescribeCertificateAsync(describeCertificateRequest);

                Console.WriteLine($"Got Describe Certificate Response: {JsonSerializer.Serialize(describeCertificateResponse)}");

                validationOptions      = describeCertificateResponse.Certificate.DomainValidationOptions;
                foundValidationOptions = true;

                if (validationOptions.Count() == 0)
                {
                    foundValidationOptions = false;
                }

                foreach (var option in validationOptions)
                {
                    if (option.ResourceRecord?.Name == null)
                    {
                        foundValidationOptions = false;
                    }
                }

                Thread.Sleep(1000);
            }

            if (props.Tags != null)
            {
                tasks.Add(Task.Run(async delegate
                {
                    var addTagsResponse = await acmClient.AddTagsToCertificateAsync(new AddTagsToCertificateRequest
                    {
                        Tags           = props.Tags,
                        CertificateArn = PhysicalResourceId,
                    });

                    Console.WriteLine($"Got Add Tags Response: {JsonSerializer.Serialize(addTagsResponse)}");
                }));
            }

            // add DNS validation records if applicable
            var names   = new HashSet <string>();
            var changes = new List <Change>();

            if (props.ValidationMethod == ValidationMethod.DNS)
            {
                foreach (var option in validationOptions)
                {
                    var query = from name in names where name == option.ResourceRecord.Name select name;

                    if (query.Count() != 0)
                    {
                        continue;
                    }

                    names.Add(option.ResourceRecord.Name);
                    changes.Add(new Change
                    {
                        Action            = ChangeAction.UPSERT,
                        ResourceRecordSet = new ResourceRecordSet
                        {
                            Name            = option.ResourceRecord.Name,
                            Type            = new RRType(option.ResourceRecord.Type.Value),
                            SetIdentifier   = PhysicalResourceId,
                            Weight          = 1,
                            TTL             = 60,
                            ResourceRecords = new List <ResourceRecord> {
                                new ResourceRecord {
                                    Value = option.ResourceRecord.Value
                                }
                            }
                        }
                    });
                }

                tasks.Add(
                    Task.Run(async delegate
                {
                    var changeRecordsResponse = await route53Client.ChangeResourceRecordSetsAsync(new ChangeResourceRecordSetsRequest
                    {
                        HostedZoneId = props.HostedZoneId,
                        ChangeBatch  = new ChangeBatch
                        {
                            Changes = changes
                        }
                    });

                    Console.WriteLine($"Got Change Record Sets Response: {JsonSerializer.Serialize(changeRecordsResponse)}");
                })
                    );
            }

            Task.WaitAll(tasks.ToArray());

            Request.PhysicalResourceId = PhysicalResourceId;
            Request.RequestType        = RequestType.Wait;

            return(await Wait());
        }