예제 #1
0
        public async Task WriteAsync(DataRepositoryManifest manifest)
        {
            this.logger.LogInformation($"Writing manifest for {this.ManifestFilePath}");
            var tmpFile = this.ManifestFilePath + ".tmp";

            using var fs = File.Create(tmpFile);
            await JsonSerializer.SerializeAsync(fs, manifest);

            File.Move(tmpFile, this.ManifestFilePath, overwrite: true);
        }
예제 #2
0
        public async Task <DataRepositoryKnownGoods> GetOrUpdateAsync(string ns, DataRepositoryManifest manifest, IReadOnlyList <PodDataRequestInfo> pods, CancellationToken token)
        {
            var lkg = await this.client.GetEndpointAnnotationsAsync(ns, AutoCraneLastKnownGoodEndpointName, token);

            var itemsToAdd = new Dictionary <string, string>();

            foreach (var source in manifest.Sources)
            {
                if (source.Value.Count > 0)
                {
                    bool shouldUpgrade = false;

                    if (!lkg.ContainsKey(source.Key))
                    {
                        // LKG entry does not exist
                        shouldUpgrade = true;
                    }
                    else if (lkg.TryGetValue(source.Key, out var req))
                    {
                        var lkgRequest = DataDownloadRequestDetails.FromBase64Json(req);

                        // if the manifest no longer contains the LKG, we shouldn't send people to download the LKG
                        shouldUpgrade = !source.Value.Any(sv => sv.ArchiveFilePath == lkgRequest?.Path);
                    }

                    if (shouldUpgrade)
                    {
                        var mostRecentData = source.Value.ToList().OrderByDescending(k => k.Timestamp).First();
                        var req            = new DataDownloadRequestDetails(mostRecentData.ArchiveFilePath, mostRecentData.Hash);

                        this.logger.LogInformation($"Setting LKG for {source.Key} to hash={req.Hash} filePath={req.Path}");
                        itemsToAdd[source.Key] = req.ToBase64String();
                    }
                }
            }

            foreach (var knownGood in lkg)
            {
                var dataSource           = knownGood.Key;
                var currentVersionString = knownGood.Value;

                var requestsForThisSource = pods.Select(p => p.Requests.FirstOrDefault(r => r.Key == dataSource).Value)
                                            .Select(r => r == null ? null : DataDownloadRequestDetails.FromBase64Json(r))
                                            .ToList();

                var distinctRequestsForThisSource = requestsForThisSource.Select(r => r?.Path).Distinct().ToList();
                var firstRequestForThisSource     = requestsForThisSource.FirstOrDefault();
                if (distinctRequestsForThisSource.Count == 1 && firstRequestForThisSource != null)
                {
                    var everyPodHasThisPath = distinctRequestsForThisSource.First();
                    var currentVersion      = DataDownloadRequestDetails.FromBase64Json(currentVersionString);
                    if (currentVersion == null)
                    {
                        this.logger.LogError($"Couldn't read current version of data {dataSource}, value: {currentVersionString}");
                    }
                    else
                    {
                        if (currentVersion.Path != everyPodHasThisPath)
                        {
                            this.logger.LogInformation($"Upgrading LKG for {dataSource} to hash={firstRequestForThisSource!.Hash} filePath={firstRequestForThisSource!.Path}");
                            itemsToAdd[dataSource] = firstRequestForThisSource.ToBase64String();
                        }
                    }
                }
            }

            if (itemsToAdd.Any())
            {
                await this.client.PutEndpointAnnotationsAsync(ns, AutoCraneLastKnownGoodEndpointName, itemsToAdd, token);
            }

            var newDict = new Dictionary <string, string>(lkg);

            foreach (var item in itemsToAdd)
            {
                newDict[item.Key] = item.Value;
            }

            return(new DataRepositoryKnownGoods(newDict));
        }
예제 #3
0
        public async Task <DataRepositoryLatestVersionInfo> GetOrUpdateAsync(string ns, DataRepositoryManifest manifest, CancellationToken token)
        {
            var currentVer = await this.client.GetEndpointAnnotationsAsync(ns, AutoCraneDataDeployEndpointName, token);

            var itemsToAdd = new Dictionary <string, string>();

            foreach (var item in manifest.Sources)
            {
                var recentData = item.Value.ToList().OrderByDescending(k => k.Timestamp);
                if (!recentData.Any())
                {
                    this.logger.LogWarning($"Missing recent data for {item.Key}/{item.Value}");
                    continue;
                }

                var mostRecentData = recentData.First();
                var req            = new DataDownloadRequestDetails(mostRecentData.ArchiveFilePath, mostRecentData.Hash);

                var latestVersion = req.ToBase64String();
                if (currentVer.TryGetValue(item.Key, out var currentVerString))
                {
                    var currentVerJson = DataDownloadRequestDetails.FromBase64Json(currentVerString);
                    if (currentVerJson?.Path == req.Path)
                    {
                        continue;
                    }
                }

                this.logger.LogInformation($"Setting Latest for {item.Key} to hash={req.Hash} filePath={req.Path}");
                itemsToAdd[item.Key] = latestVersion;
            }

            if (itemsToAdd.Any())
            {
                await this.client.PutEndpointAnnotationsAsync(ns, AutoCraneDataDeployEndpointName, itemsToAdd, token);
            }

            var union = itemsToAdd;

            foreach (var item in currentVer)
            {
                union.TryAdd(item.Key, item.Value);
            }

            return(new DataRepositoryLatestVersionInfo(union));
        }