Example #1
0
        private void SynchronizedLoadAllHistory(Guid profileId)
        {
            IAwsClient client;
            AwsProfile profile;

            if (!TryInitialize(profileId, out client, out profile))
            {
                return;
            }

            if (string.IsNullOrEmpty(profile.DetailedBillingS3Bucket))
            {
                // detailed billing not configured for this profile
                return;
            }

            if (profile.IsBillingHistoryLoading)
            {
                return;
            }

            // Prevent other processes from trying to load at the same time.
            // This still has a race condition that would be eliminated using optimistic concurrency.
            profile.IsBillingHistoryLoading = true;
            _awsProfileRepository.Update(profile);

            // http://s3.amazonaws.com/509438855493-aws-billing-detailed-line-items-with-resources-and-tags-2014-08.csv.zip
            var pattern = new Regex(@"\A\d+-aws-billing-detailed-line-items-with-resources-and-tags-(\d+\-\d+).csv.zip\z");

            var           rootPath         = new S3PathParts(profile.DetailedBillingS3Bucket, "");
            List <string> availablePeriods = client.StorageService
                                             .ListFiles(rootPath.ToString())
                                             .Select(path => _pathParser.Parse(path))
                                             .Select(parsedPath => pattern.Match(parsedPath.Key))
                                             .Where(match => match.Success)
                                             .Select(match => match.Groups[1].Captures[0].Value)
                                             .OrderBy(period => period, StringComparer.InvariantCulture)
                                             .ToList();

            // Forget that we have pulled CSVs before...
            profile.BillingMetadata.Clear();
            // ... or loaded them into the ledger.
            _billingManager.WipeAllData();

            DateTime utcNow = _clock.UtcNow;

            foreach (string period in availablePeriods)
            {
                RefreshDataForPeriod(profile, period, client, utcNow);
            }

            profile.IsBillingHistoryLoaded  = true;
            profile.IsBillingHistoryLoading = false;
            _awsProfileRepository.Update(profile);
        }