A complex type that describes how CloudFront processes requests.

You must create at least as many cache behaviors (including the default cache behavior) as you have origins if you want CloudFront to distribute objects from all of the origins. Each cache behavior specifies the one origin from which you want CloudFront to get objects. If you have two origins and only the default cache behavior, the default cache behavior will cause CloudFront to get objects from one of the origins, but the other origin is never used.

For the current limit on the number of cache behaviors that you can add to a distribution, see Amazon CloudFront Limits in the AWS General Reference.

If you don't want to specify any cache behaviors, include only an empty CacheBehaviors element. Don't include an empty CacheBehavior element, or CloudFront returns a MalformedXML error.

To delete all cache behaviors in an existing distribution, update the distribution configuration and include only an empty CacheBehaviors element.

To add, change, or remove one or more cache behaviors, update the distribution configuration and specify all of the cache behaviors that you want to include in the updated distribution.

For more information about cache behaviors, see Cache Behaviors in the Amazon CloudFront Developer Guide.

        public async Task MapBinaryRoutesInCloudFrontAsync(string beanstalkUrl, string subdomain, string deploymentEnvironmentName)
        {
            var distributionResponse = await GetDistributionByCNAMEAsync();
            var domainHost = GetHostFromUrl(beanstalkUrl);

            if (distributionResponse.Distribution == null)
            {
                loggerProvider.GetLogger().Debug($"No action being taken, could not find distribution associated with CNAME. [CNAME: {cfConfigurationProvider.CNAME}]");
                return;
            }

            bool originAdded = false;
            var origin = distributionResponse.Distribution.DistributionConfig.Origins.Items.FirstOrDefault(o => o.DomainName == domainHost);
            if (origin == null)
            {
                loggerProvider.GetLogger().Debug($"Origin not found.  Creating new origin. [DomainName: {domainHost}]");
                origin = new Origin
                {

                    Id = $"{Capitalize(subdomain)} API {Capitalize(deploymentEnvironmentName)} Beanstalk",
                    DomainName = domainHost,
                    OriginPath = string.Empty,
                    CustomOriginConfig = new CustomOriginConfig
                    {
                        HTTPPort = 80,
                        HTTPSPort = 443,
                        OriginProtocolPolicy = new OriginProtocolPolicy("https-only"), 
                        OriginSslProtocols = new OriginSslProtocols
                        {
                            Items = new List<string> { "TLSv1", "TLSv1.1", "TLSv1.2" },
                            Quantity = 3
                        }
                    },
                    CustomHeaders = new CustomHeaders
                    {
                        Quantity = 1,
                        Items = new List<OriginCustomHeader>
                        {
                            new OriginCustomHeader { HeaderName = "x-mat-gateway-secret", HeaderValue = cfConfigurationProvider.MaterialGatewaySecret}
                        }
                    }

                };
                distributionResponse.Distribution.DistributionConfig.Origins.Items.Add(origin);
                distributionResponse.Distribution.DistributionConfig.Origins.Quantity++;
                originAdded = true;
            }

            bool cacheBehaviorAdded = false;
            var routes = GetListOfBinaryRoutesAsync();
            foreach(var route in routes)
            {
                var cacheBehavior = distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items.FirstOrDefault(behavior => behavior.TargetOriginId == origin.Id && behavior.PathPattern.IsEqualIgnoreCase(route));
                if(cacheBehavior == null)
                {
                    loggerProvider.GetLogger().Debug($"Cache Behavior not found. Creating new Cache behavior. [OriginId: {origin.Id}] [Route: {route}]");
                    cacheBehavior = new CacheBehavior
                    {
                        TargetOriginId = origin.Id,
                        PathPattern = route,
                        AllowedMethods = new AllowedMethods
                        {
                            Items = new List<string> {"GET","HEAD","POST","PUT","PATCH","OPTIONS","DELETE"},
                            Quantity = 7,
                            CachedMethods = new CachedMethods
                            {
                                Items = new List<string> { "GET", "HEAD", "OPTIONS" },
                                Quantity = 3
                            }
                        },
                        ForwardedValues = new ForwardedValues
                        {
                            QueryString = true,
                            Cookies = new CookiePreference
                            {
                                Forward = new ItemSelection("none"),
                                WhitelistedNames = new CookieNames
                                {
                                    Quantity = 0
                                }
                            },
                            Headers = new Headers
                            {
                                Items = new List<string> {"x-vol-tenant", "x-vol-test", "accept", "authorization"},
                                Quantity = 4
                            }
                        },
                        ViewerProtocolPolicy = new ViewerProtocolPolicy("redirect-to-https"),
                        TrustedSigners = new TrustedSigners
                        {
                            Enabled = false,
                            Quantity = 0
                        },
                        MinTTL = 0,
                        MaxTTL = 0,
                        DefaultTTL = 0,
                        Compress = true,
                        SmoothStreaming = false
                    };
                    distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items.Add(cacheBehavior);
                    distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Quantity++;
                    cacheBehaviorAdded = true;
                }
            }

            loggerProvider.GetLogger().Debug("Removing CacheBehavior routes that are no longer listed in the binary routes path.");
            var originalList = distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items;
            distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items = originalList.Where(behavior => behavior.TargetOriginId != origin.Id || (behavior.TargetOriginId == origin.Id && routes.Contains(behavior.PathPattern))).ToList();
            var itemsRemoved = originalList.Count != distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items.Count;

            if (cacheBehaviorAdded || originAdded || itemsRemoved)
            {
                loggerProvider.GetLogger().Debug($"New Origin or Cache Behavior.  Updating CloudFront instance. [CacheBehaviorAdded: {cacheBehaviorAdded}] [OriginAdded: {originAdded}] [ItemsRemoved: {itemsRemoved}]");
                loggerProvider.GetLogger().Debug("Sorting order of cache behaviors.");

                //verify that new cacheBehaviors are ahead of their API Gateway cache behaviors for order of precendent issues!!
                distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items = new List<CacheBehavior>(distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items.OrderByDescending(behavior => behavior.PathPattern));
                distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Quantity = distributionResponse.Distribution.DistributionConfig.CacheBehaviors.Items.Count;



                //update distribution
                using (var client = new AmazonCloudFrontClient(cfConfigurationProvider.AccessKey, cfConfigurationProvider.SecretKey, cfConfigurationProvider.RegionEndpoint))
                {
                    var response = await client.UpdateDistributionAsync(new UpdateDistributionRequest { DistributionConfig = distributionResponse.Distribution.DistributionConfig, Id = distributionResponse.Distribution.Id, IfMatch = distributionResponse.ETag });
                    await WaitUntilDistributionIsDeployedAsync(response.Distribution);
                    loggerProvider.GetLogger().Debug("Finished updating/verifying the cloudfront distribution.");
                }
            }
        }