Esempio n. 1
0
        protected async Task DeleteTestDataAsync()
        {
            var response = (JObject)await this.TenancyService.GetTenantAsync(this.ClientTenantId);

            Tenancy.Client.Models.Tenant clientTenant = JsonConvert.DeserializeObject <Tenancy.Client.Models.Tenant>(response.ToString());

            var tenant = new Tenant(clientTenant.Id, clientTenant.Name, this.PropertyBagFactory.Create(clientTenant.Properties));

            BlobContainerClient claimPermissionsContainer =
                await this.TenantBlobContainerClientFactory.GetBlobContainerClientFromTenantAsync(
                    tenant,
                    "StorageConfiguration__claimpermissions",
                    "StorageConfigurationV3__claimpermissions");

            BlobContainerClient resourceAccessRuleSetsContainer =
                await this.TenantBlobContainerClientFactory.GetBlobContainerClientFromTenantAsync(
                    tenant,
                    "StorageConfiguration__resourceaccessrulesets",
                    "StorageConfigurationV3__resourceaccessrulesets");

            foreach (BlobItem blob in claimPermissionsContainer.GetBlobs())
            {
                await claimPermissionsContainer.DeleteBlobAsync(blob.Name);
            }

            foreach (BlobItem blob in resourceAccessRuleSetsContainer.GetBlobs())
            {
                await claimPermissionsContainer.DeleteBlobAsync(blob.Name);
            }
        }
Esempio n. 2
0
        public async Task <IActionResult> DeleteMap(int id)
        {
            string currentUser = User.FindFirstValue(ClaimTypes.NameIdentifier);

            Map mapToDelete = await _context.Maps.FindAsync(id);

            if (mapToDelete.UserId != currentUser)
            {
                return(BadRequest());
            }

            try
            {
                BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(currentUser);
                await containerClient.DeleteBlobAsync(mapToDelete.FileName);
            }
            catch (Exception exc)
            {
                _logger.AddSystemLog($"An Exception occured while deleting a map file: {exc}");
                return(StatusCode(500));
            }

            _context.Remove(mapToDelete);
            await _context.SaveChangesAsync();

            return(Ok());
        }
Esempio n. 3
0
        private async Task <Result> CleanContainerFolderStorageAsync(string container, string folder,
                                                                     CancellationToken token)
        {
            var containerClient = new BlobContainerClient(_storageOptions.ConnectionString, container);

            var blobClient = containerClient.GetBlobClient(folder);

            if (!await blobClient.ExistsAsync(token))
            {
                return(Success());
            }

            var    success = true;
            string reason  = null;

            await foreach (var blob in containerClient.GetBlobsAsync(prefix: folder, cancellationToken: token))
            {
                var response = await containerClient.DeleteBlobAsync(blob.Name, cancellationToken : token);

                if (response.Status >= 400)
                {
                    success = false;
                    reason  = response.ReasonPhrase;
                }
            }

            return(success ? Success() : Failure(reason));
        }
        /// <summary>
        /// Deletes the previously recorded checkpoints if the current checkpoint blob path (corresponding to the input event hub) has changed.
        /// </summary>
        public async Task ResetCheckpointsAsync()
        {
            try
            {
                _log.LogTrace($"Entering {nameof(ResetCheckpointsAsync)}...");

                foreach (BlobItem blob in _storageClient.GetBlobs(states: BlobStates.All, prefix: _blobCheckpointPrefix, cancellationToken: CancellationToken.None))
                {
                    if (!blob.Name.Contains(_blobPath, StringComparison.OrdinalIgnoreCase))
                    {
                        try
                        {
                            await _storageClient.DeleteBlobAsync(blob.Name, cancellationToken : CancellationToken.None);

                            _log.LogTrace($"Blob checkpoint path changed to {_blobPath}. Deleted checkpoint {blob.Name}.");
                        }
#pragma warning disable CA1031
                        catch (Exception ex)
#pragma warning restore CA1031
                        {
                            _log.LogError(new Exception($"Unable to delete checkpoint {blob.Name} with error {ex.Message}"));
                        }
                    }
                }

                _log.LogTrace($"Exiting {nameof(ResetCheckpointsAsync)}.");
            }
#pragma warning disable CA1031
            catch (Exception ex)
#pragma warning restore CA1031
            {
                _log.LogError(new Exception($"Unable to reset checkpoints. {ex.Message}"));
            }
        }
Esempio n. 5
0
        public static async Task AutoCleanup(
            [TimerTrigger("0 0 0 * * *", RunOnStartup = true)] TimerInfo timer
            , [Blob("backups", FileAccess.Read)] BlobContainerClient blobReader
            , [Blob("backups", FileAccess.Write)] BlobContainerClient backupClient
            , [Blob("archives", FileAccess.Write)] BlobContainerClient archiveClient
            )
        {
            var pages = blobReader.GetBlobsAsync();

            var blobsToMove = new List <BlobItem>();
            var current     = DateTime.Now;

            await foreach (var blob in pages)
            {
                var date = DateTime.ParseExact(blob.Name.Replace(".zip", string.Empty),
                                               dateFormat,
                                               null);
                if ((date - current).Days > 7)
                {
                    blobsToMove.Add(blob);
                }
            }

            foreach (var blob in blobsToMove)
            {
                await using var stream = (await blobReader.GetBlobClient(blob.Name).DownloadStreamingAsync()).Value.Content;
                string blobName = $"Weekly-{blob.Name}";
                var    newBlob  = await archiveClient.UploadBlobAsync(blobName, stream);

                await archiveClient.GetBlobClient(blobName).SetAccessTierAsync(AccessTier.Archive);

                await backupClient.DeleteBlobAsync(blob.Name);
            }
        }
Esempio n. 6
0
 public async Task DeleteBlobAsync(string containername
                                   , string blobname)
 {
     BlobContainerClient containerClient =
         this.service.GetBlobContainerClient(containername);
     await containerClient.DeleteBlobAsync(blobname);
 }
Esempio n. 7
0
 public async Task ClearStorage()
 {
     foreach (var blob in _solutionIdsToGuids.Values.SelectMany(directory => _blobContainer.GetBlobs(prefix: directory)))
     {
         await _blobContainer.DeleteBlobAsync(blob.Name);
     }
 }
        public override async Task DeleteDirectoryAsync(string path, CancellationToken cancellationToken = default)
        {
            await GetDirectoryAsync(path, cancellationToken);

            path = PrependRootPath(path);
            path = path.EndsWith("/") ? path : path + "/";

            try
            {
                await foreach (var item in client.GetBlobsAsync(BlobTraits.None, BlobStates.None, path))
                {
                    await client.DeleteBlobAsync(item.Name, DeleteSnapshotsOption.IncludeSnapshots, cancellationToken : cancellationToken);
                }
            }
            catch (Exception exception)
            {
                throw Exception(exception);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Delete picture thumbs
        /// </summary>
        /// <param name="picture">Picture</param>
        protected override async Task DeletePictureThumbs(Picture picture)
        {
            string filter = string.Format("{0}", picture.Id);
            var    blobs  = container.GetBlobs(Azure.Storage.Blobs.Models.BlobTraits.All, Azure.Storage.Blobs.Models.BlobStates.All, filter);

            foreach (var blob in blobs)
            {
                await container.DeleteBlobAsync(blob.Name);
            }
        }
        public static async Task DeleteDirectoryAsync(string dir)
        {
            dir = RemoveContainerFromPathIfPresent(dir);

            foreach (var blobItem in BlobContainerClient.GetBlobs())
            {
                if (blobItem.Name.StartsWith(dir))
                {
                    await BlobContainerClient.DeleteBlobAsync(blobItem.Name);
                }
            }
        }
Esempio n. 11
0
    private static async Async.Task AssertCanCRUD(Uri sasUrl)
    {
        var client = new BlobContainerClient(sasUrl);
        await client.UploadBlobAsync("blob", new BinaryData("content"));   // create

        var b = Assert.Single(await client.GetBlobsAsync().ToListAsync()); // list

        using (var s = await client.GetBlobClient(b.Name).OpenReadAsync())
            using (var sr = new StreamReader(s)) {
                Assert.Equal("content", await sr.ReadToEndAsync()); // read
            }
        await client.DeleteBlobAsync("blob");                       // delete
    }
 public async Task <IActionResult> ClearBlobs()
 {
     try
     {
         await foreach (var blob in _blobClient.GetBlobsAsync(BlobTraits.Metadata))
         {
             await _blobClient.DeleteBlobAsync(blob.Name);
         }
     }
     catch
     {
     }
     return(Ok("Deleted all Blobs"));
 }
Esempio n. 13
0
        private async Task <IActionResult> DeleteOldImageBlobIfNotEqual(WikiPage wikiPage)
        {
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(wikiPage.UserId);
            BlobClient          blobClient      = containerClient.GetBlobClient(wikiPage.PageName);
            var blobProps = await blobClient.GetPropertiesAsync();

            int oldSize = Convert.ToInt32(blobProps.Value.ContentLength);

            if (oldSize != wikiPage.ImageFile.Length)
            {
                await containerClient.DeleteBlobAsync(wikiPage.PageName);
            }

            return(Ok());
        }
Esempio n. 14
0
        public async Task DeleteFile(string fileName, string containerName)
        {
            BlobContainerClient container = blobServiceClient.GetBlobContainerClient(containerName);

            try
            {
                await container.DeleteBlobAsync(fileName);
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
                throw;
            }
        }
Esempio n. 15
0
        public async Task <bool> RemovePhotoAsync(string blobPath)
        {
            var typeContainerClient = new BlobContainerClient(_connectionString, "photos");
            var blobs = typeContainerClient.GetBlobsAsync(prefix: blobPath);

            await foreach (var blob in blobs)
            {
                var result = await typeContainerClient.DeleteBlobAsync(blob.Name, DeleteSnapshotsOption.IncludeSnapshots);

                if ((HttpStatusCode)result.Status != HttpStatusCode.Accepted)
                {
                    return(false);
                }
            }
            return(true);
        }
        private static async Task UpdateAzureBlobStorageAsync(int count, ILogger logger)
        {
            logger.LogInformation("Start rebuilding search index");


            logger.LogInformation("Retrieving data urls.");
            var dataUrls = GetDataUrls(count);
            // container name "index-storage"
            var blobContainerClient = new BlobContainerClient(
                Environment.GetEnvironmentVariable("AzureBlogStorageConnectionString"),
                Environment.GetEnvironmentVariable("IndexContainerName"));


            logger.LogInformation("Clear blob storage");
            await foreach (var blob in blobContainerClient.GetBlobsAsync())
            {
                await blobContainerClient.DeleteBlobAsync(blob.Name, DeleteSnapshotsOption.IncludeSnapshots);
            }

            logger.LogInformation("Upload data files into blob storage.");
            dataUrls.ToList().ForEach(async dataUrl =>
            {
                using var httpClient = new HttpClient();
                logger.LogInformation($"Retrieving data for url: {dataUrl}");
                var response = await httpClient.GetAsync(dataUrl);
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    logger.LogInformation($"Received response with status code {response.StatusCode} for request with url {dataUrl}. skipping...");
                    return;
                }
                try
                {
                    await blobContainerClient.UploadBlobAsync($"{Guid.NewGuid()}.json", await response.Content.ReadAsStreamAsync());
                }
                catch (RequestFailedException)
                {
                    logger.LogInformation("Blob did not change, skipping upload");
                }
            });
        }
Esempio n. 17
0
        /// <summary>
        /// Deletes the previously recorded checkpoints if the current checkpoint blob path (corresponding to the input event hub) has changed.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token</param>
        /// <returns><see cref="Task"/></returns>
        public async Task ResetCheckpointsAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogTrace($"Entering {nameof(ResetCheckpointsAsync)}...");

                var hasEventHubChanged = false;

                var blobs = _storageClient.GetBlobs(states: BlobStates.All, prefix: _blobCheckpointPrefix, cancellationToken: cancellationToken);

                foreach (BlobItem blob in blobs)
                {
                    if (!blob.Name.Contains(_blobPath, StringComparison.OrdinalIgnoreCase))
                    {
                        try
                        {
                            await _storageClient.DeleteBlobAsync(blob.Name, cancellationToken : cancellationToken);

                            _logger.LogTrace($"Blob checkpoint path changed to {_blobPath}. Deleted checkpoint {blob.Name}.");
                            hasEventHubChanged = true;
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(new StorageCheckpointClientException($"Unable to delete checkpoint {blob.Name} with error {ex.Message}", ex));
                        }
                    }
                }

                if (blobs.Count() == 0 || hasEventHubChanged)
                {
                    _logger.LogMetric(EventMetrics.EventHubChanged(_blobPath.Replace(_blobCheckpointPrefix, string.Empty)), 1);
                }

                _logger.LogTrace($"Exiting {nameof(ResetCheckpointsAsync)}.");
            }
            catch (Exception ex)
            {
                _logger.LogError(new StorageCheckpointClientException($"Unable to reset checkpoints. {ex.Message}", ex));
            }
        }
        public async Task <ActionResult> DeleteAll()
        {
            try
            {
                InitClient();

                await foreach (BlobItem blob in blobContainer.GetBlobsAsync())
                {
                    if (blob.Properties.BlobType == BlobType.Block)
                    {
                        await blobContainer.DeleteBlobAsync(blob.Name);
                    }
                }

                return(RedirectToAction("Index"));
            }
            catch (Exception ex)
            {
                ViewData["message"] = ex.Message;
                ViewData["trace"]   = ex.StackTrace;
                return(View("Error"));
            }
        }
Esempio n. 19
0
        public Task <Response> DeleteBlobAsync(string blobName, string containerName)
        {
            _blobContainerClient = new BlobContainerClient(_connectionString, containerName);

            return(_blobContainerClient.DeleteBlobAsync(blobName));
        }
Esempio n. 20
0
        private static async Task RunAsync(CrawledSubscriptionList subscriptionList, bool reindex, bool pullLatest, bool randomReindex, bool uploadToAzure, string startingRepoName, string outputPath)
        {
            var reindexIntervalInDays = 28;
            var today = DateTime.Today;

            var connectionString = GetAzureStorageConnectionString();

            // TODO: We should avoid having to use a temp directory

            var tempDirectory = Path.Combine(Path.GetTempPath(), "ghcrawler");

            if (Directory.Exists(tempDirectory))
            {
                Directory.Delete(tempDirectory, recursive: true);
            }

            Directory.CreateDirectory(tempDirectory);

            var cacheContainerName   = "cache";
            var cacheContainerClient = new BlobContainerClient(connectionString, cacheContainerName);

            if (!reindex || startingRepoName is not null)
            {
                var startingBlobName    = $"{startingRepoName}.crcache";
                var reachedStartingBlob = false;

                await foreach (var blob in cacheContainerClient.GetBlobsAsync())
                {
                    if (!subscriptionList.Contains(blob.Name.Replace(".crcache", "")))
                    {
                        continue;
                    }

                    if (blob.Name == startingBlobName)
                    {
                        reachedStartingBlob = true;
                    }

                    if (reachedStartingBlob)
                    {
                        continue;
                    }

                    Console.WriteLine($"Downloading {blob.Name}...");

                    var localPath      = Path.Combine(tempDirectory, blob.Name);
                    var localDirectory = Path.GetDirectoryName(localPath);
                    Directory.CreateDirectory(localDirectory);

                    var blobClient = new BlobClient(connectionString, cacheContainerName, blob.Name);
                    await blobClient.DownloadToAsync(localPath);
                }
            }

            var factory = CreateGitHubClientFactory();
            var client  = await factory.CreateAsync();

            var jsonOptions = new JsonSerializerOptions()
            {
                WriteIndented = true
            };

            var repos = new List <CrawledRepo>();

            var reachedStartingRepo = reindex && startingRepoName is null;

            foreach (var org in subscriptionList.Orgs)
            {
                var orgDirectory = Path.Join(tempDirectory, org);
                Directory.CreateDirectory(orgDirectory);

                var existingRepos = Directory.GetFiles(orgDirectory, "*.crcache")
                                    .Select(p => Path.GetFileNameWithoutExtension(p));

                if (!pullLatest)
                {
                    Console.WriteLine($"Loading repos for {org}...");

                    foreach (var repoName in existingRepos)
                    {
                        var blobName = $"{repoName}.crcache";
                        var repoPath = Path.Join(orgDirectory, blobName);
                        var repo     = await CrawledRepo.LoadAsync(repoPath);

                        if (repo is not null)
                        {
                            repos.Add(repo);
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"Requesting repos for {org}...");
                    var availableRepos = await RequestReposAsync(factory, client, org);

                    var deletedRepos = existingRepos.ToHashSet(StringComparer.OrdinalIgnoreCase);
                    deletedRepos.ExceptWith(availableRepos.Select(r => r.Name));

                    foreach (var deletedRepo in deletedRepos)
                    {
                        var blobName = $"{org}/{deletedRepo}.crcache";
                        var repoPath = Path.Join(tempDirectory, blobName);

                        Console.WriteLine($"Deleting local file {blobName}...");
                        File.Delete(repoPath);

                        if (uploadToAzure)
                        {
                            Console.WriteLine($"Deleting Azure blob {blobName}...");
                            await cacheContainerClient.DeleteBlobAsync(blobName);
                        }
                    }

                    foreach (var repo in availableRepos)
                    {
                        if (!subscriptionList.Contains(org, repo.Name))
                        {
                            continue;
                        }

                        var blobName = $"{org}/{repo.Name}.crcache";
                        var repoPath = Path.Join(tempDirectory, blobName);

                        if (string.Equals($"{org}/{repo.Name}", startingRepoName, StringComparison.OrdinalIgnoreCase))
                        {
                            reachedStartingRepo = true;
                        }

                        CrawledRepo crawledRepo;
                        try
                        {
                            crawledRepo = await CrawledRepo.LoadAsync(repoPath);
                        }
                        catch (JsonException)
                        {
                            Console.WriteLine($"WARNING: Couldn't parse {blobName}");
                            crawledRepo = null;
                        }

                        if (crawledRepo is null)
                        {
                            crawledRepo = new CrawledRepo
                            {
                                Id   = repo.Id,
                                Org  = org,
                                Name = repo.Name
                            };
                        }

                        crawledRepo.IsArchived = repo.Archived;
                        crawledRepo.Size       = repo.Size;

                        repos.Add(crawledRepo);

                        var repoIsDueForReindexing = crawledRepo.LastReindex is null ||
                                                     crawledRepo.LastReindex?.AddDays(reindexIntervalInDays) <= today;

                        if (reachedStartingRepo)
                        {
                            Console.WriteLine($"Marking {repo.FullName} to be re-indexed because we reached the starting repo {startingRepoName}.");
                        }

                        if (repoIsDueForReindexing)
                        {
                            if (crawledRepo.LastReindex is null)
                            {
                                Console.WriteLine($"Marking {repo.FullName} to be re-indexed because it was never fully indexed.");
                            }
                            else
                            {
                                Console.WriteLine($"Marking {repo.FullName} to be re-indexed because it was more than {reindexIntervalInDays} days ago, on {crawledRepo.LastReindex}.");
                            }
                        }

                        if (reachedStartingRepo || repoIsDueForReindexing)
                        {
                            crawledRepo.Clear();
                        }
                    }
                }
            }

            // We want to ensure that all repos are fully-reindexed at least once every four weeks.
            // That means we need to reindex at least #Repos / 28 per day.
            //
            // On top of that, we need to ensure that all repos which were never fully indexed (e.g.
            // they are new or were forced to be reindexed) are also reindexed.

            if (randomReindex)
            {
                var reposThatNeedReindexing = repos.Where(r => r.LastReindex is null).ToHashSet();

                var minimumNumberOfReposToBeReindexed = (int)Math.Ceiling(repos.Count / (float)reindexIntervalInDays);
                var numberOfReposThatNeedReindexing   = reposThatNeedReindexing.Count;

                if (numberOfReposThatNeedReindexing < minimumNumberOfReposToBeReindexed)
                {
                    // OK, there are fewer repos that need reindexing than what we want to reindex
                    // per day. So let's randomly pick some repos to reindex.

                    var remainingRepos = repos.Except(reposThatNeedReindexing).ToList();
                    var choiceCount    = minimumNumberOfReposToBeReindexed - numberOfReposThatNeedReindexing;

                    var random = new Random();

                    for (var choice = 0; choice < choiceCount; choice++)
                    {
                        var i    = random.Next(0, remainingRepos.Count);
                        var repo = remainingRepos[i];

                        Console.WriteLine($"Marking {repo.FullName} to be re-indexed because it was randomly chosen.");

                        repo.Clear();
                        reposThatNeedReindexing.Add(repo);
                        remainingRepos.RemoveAt(i);
                    }
                }
            }

            if (pullLatest)
            {
                Console.WriteLine($"Listing events...");

                var eventStore = new GitHubEventStore(connectionString);
                var events     = await eventStore.ListAsync();

                Console.WriteLine($"Crawling {repos.Count:N0} repos, fully reindexing {repos.Count(r => r.LastReindex is null):N0} repos...");

                foreach (var crawledRepo in repos)
                {
                    var blobName = $"{crawledRepo.FullName}.crcache";
                    var repoPath = Path.Join(tempDirectory, blobName);
                    var since    = crawledRepo.IncrementalUpdateStart;

                    var messages = new List <GitHubEventMessage>();

                    if (since is null)
                    {
                        Console.WriteLine($"Crawling {crawledRepo.FullName}...");
                    }
                    else
                    {
                        var toBeDownloaded = events.Where(n => string.Equals(n.Org, crawledRepo.Org, StringComparison.OrdinalIgnoreCase) &&
                                                          string.Equals(n.Repo, crawledRepo.Name, StringComparison.OrdinalIgnoreCase))
                                             .ToArray();

                        if (toBeDownloaded.Any())
                        {
                            Console.WriteLine($"Loading {toBeDownloaded.Length:N0} events for {crawledRepo.FullName}...");

                            var i           = 0;
                            var lastPercent = 0;

                            foreach (var name in toBeDownloaded)
                            {
                                var percent = (int)Math.Ceiling((float)i / toBeDownloaded.Length * 100);
                                i++;
                                if (percent % 10 == 0)
                                {
                                    if (percent != lastPercent)
                                    {
                                        Console.Write($"{percent}%...");
                                    }

                                    lastPercent = percent;
                                }

                                var payload = await eventStore.LoadAsync(name);

                                var headers = payload.Headers.ToDictionary(kv => kv.Key, kv => new StringValues(kv.Value.ToArray()));
                                var body    = payload.Body;
                                var message = GitHubEventMessage.Parse(headers, body);
                                messages.Add(message);
                            }

                            Console.WriteLine("done.");
                        }

                        Console.WriteLine($"Crawling {crawledRepo.FullName} since {since}...");
                    }

                    if (crawledRepo.LastReindex is null)
                    {
                        crawledRepo.LastReindex = DateTimeOffset.UtcNow;
                    }

                    crawledRepo.AreaOwners = await GetAreaOwnersAsync(crawledRepo.Org, crawledRepo.Name);

                    var currentLabels = await RequestLabelsAsync(factory, client, crawledRepo.Org, crawledRepo.Name);

                    SyncLabels(crawledRepo, currentLabels, out var labelById);

                    var currentMilestones = await RequestMilestonesAsync(factory, client, crawledRepo.Org, crawledRepo.Name);

                    SyncMilestones(crawledRepo, currentMilestones, out var milestoneById);

                    // NOTE: GitHub's Issues.GetAllForeRepository() doesn't include issues that were transferred
                    //
                    // That's the good part. The bad part is that for the new repository where
                    // it shows up, we have no way of knowing which repo it came from and which
                    // number it used to have (even when looking at the issues timeline data),
                    // so we can't remove the issue from the source repo.
                    //
                    // However, since we're persisting GitHub events we received, we'll can look
                    // up which issues were transferred and remove them from the repo. This avoids
                    // having to wait until we fully reindex the repo.
                    //
                    // Note, we remove transferred issues before pulling issues in case the issues
                    // were being transferred back; it seems GitHub is reusing the numbers in that
                    // case.

                    foreach (var message in messages.Where(m => m.Body.Action == "transferred"))
                    {
                        Console.WriteLine($"Removing {message.Body?.Repository?.FullName}#{message.Body?.Issue?.Number}: {message.Body?.Issue?.Title}");

                        var number = message.Body?.Issue?.Number;
                        if (number is not null)
                        {
                            crawledRepo.Issues.Remove(number.Value);
                        }
                    }

                    foreach (var issue in await RequestIssuesAsync(factory, client, crawledRepo.Org, crawledRepo.Name, since))
                    {
                        var crawledIssue = ConvertIssue(crawledRepo, issue, labelById, milestoneById);
                        crawledRepo.Issues[issue.Number] = crawledIssue;
                    }

                    foreach (var pullRequest in await RequestPullRequestsAsync(factory, client, crawledRepo.Org, crawledRepo.Name, since))
                    {
                        if (crawledRepo.Issues.TryGetValue(pullRequest.Number, out var issue))
                        {
                            UpdateIssue(issue, pullRequest);
                        }

                        // TODO: Get PR reviews
                        // TODO: Get PR commits
                        // TODO: Get PR status
                    }

                    await crawledRepo.SaveAsync(repoPath);

                    if (uploadToAzure)
                    {
                        Console.WriteLine($"Uploading {blobName} to Azure...");
                        var repoClient = new BlobClient(connectionString, cacheContainerName, blobName);
                        await repoClient.UploadAsync(repoPath, overwrite : true);

                        if (since is null)
                        {
                            var eventsToBeDeleted = events.Where(e => string.Equals($"{e.Org}/{e.Repo}", crawledRepo.FullName, StringComparison.OrdinalIgnoreCase))
                                                    .ToArray();

                            Console.WriteLine($"Deleting {eventsToBeDeleted.Length:N0} events for {crawledRepo.FullName}...");
                            foreach (var e in eventsToBeDeleted)
                            {
                                await eventStore.DeleteAsync(e);
                            }
                        }
                    }
                }
            }

            foreach (var repo in repos)
            {
                var milestones = repo.Milestones.ToHashSet();
                var labels     = repo.Labels.ToHashSet();

                foreach (var issue in repo.Issues.Values)
                {
                    foreach (var label in issue.Labels.Where(l => !labels.Contains(l)))
                    {
                        Console.Error.WriteLine($"error: {repo.FullName}#{issue.Number}: label '{label.Name}' doesn't exist");
                    }

                    if (issue.Milestone is not null && !milestones.Contains(issue.Milestone))
                    {
                        Console.Error.WriteLine($"error: {repo.FullName}#{issue.Number}: milestone '{issue.Milestone.Title}' doesn't exist");
                    }
                }
            }

            Console.WriteLine("Creating trie...");

            var trie = new CrawledTrie <CrawledIssue>();

            foreach (var repo in repos)
            {
                foreach (var issue in repo.Issues.Values)
                {
                    trie.Add(issue);
                }
            }

            Console.WriteLine("Creating index...");

            var index = new CrawledIndex()
            {
                Repos = repos.ToList(),
                Trie  = trie
            };

            var indexName = "index.cicache";
            var indexPath = string.IsNullOrEmpty(outputPath)
                                ? Path.Join(tempDirectory, indexName)
                                : outputPath;

            await index.SaveAsync(indexPath);

            if (uploadToAzure)
            {
                Console.WriteLine("Uploading index to Azure...");

                var indexClient = new BlobClient(connectionString, "index", indexName);
                await indexClient.UploadAsync(indexPath, overwrite : true);
            }

            Console.WriteLine("Deleting temp files...");

            Directory.Delete(tempDirectory, recursive: true);
        }
Esempio n. 21
0
        static async Task Main(string[] args)
        {
            string sourceFolder        = null;
            string repoName            = null;
            string blobContainerSasUrl = null;
            var    options             = new OptionSet
            {
                { "i=", "The source folder", i => sourceFolder = i },
                { "n=", "The repo name", n => repoName = n },
                { "o=", "The destination blob container url, can also be in the BLOB_CONTAINER_URL environment variable", o => blobContainerSasUrl = o },
            };

            List <string> extra = options.Parse(args);

            if (extra.Any())
            {
                Fatal($"Unexpected argument {extra.First()}");
            }

            if (string.IsNullOrEmpty(sourceFolder))
            {
                Fatal("Missing argument -i");
            }

            if (string.IsNullOrEmpty(repoName))
            {
                Fatal("Missing argument -n");
            }

            if (string.IsNullOrEmpty(blobContainerSasUrl))
            {
                blobContainerSasUrl = Environment.GetEnvironmentVariable("BLOB_CONTAINER_URL");
            }

            if (string.IsNullOrEmpty(blobContainerSasUrl))
            {
                Fatal("Missing argument -o");
            }

            var        containerClient = new BlobContainerClient(new Uri(blobContainerSasUrl));
            string     newBlobName     = $"{repoName}/{DateTime.UtcNow:O}.tar.gz";
            BlobClient newBlobClient   = containerClient.GetBlobClient(newBlobName);

            Console.WriteLine($"Uploading folder {sourceFolder} to blob {new UriBuilder(newBlobClient.Uri) {Fragment = "", Query = ""}.Uri.AbsoluteUri}");

            await using (var outputFileStream = new MemoryStream())
            {
                await using (var gzoStream = new GZipOutputStream(outputFileStream)
                {
                    IsStreamOwner = false
                })
                    using (var tarArchive = TarArchive.CreateOutputTarArchive(gzoStream, Encoding.UTF8))
                    {
                        string sourceRoot = Path.GetFullPath(sourceFolder).Replace('\\', '/').TrimEnd('/');

                        void AddEntry(string path)
                        {
                            string normalizedPath = Path.GetFullPath(path).Replace('\\', '/');
                            var    e = TarEntry.CreateEntryFromFile(path);

                            e.Name = normalizedPath.Substring(sourceRoot.Length).TrimStart('/');
                            Console.WriteLine($"Adding {path} as {e.Name}");
                            tarArchive.WriteEntry(e, false);
                        }

                        void AddFolder(string path)
                        {
                            AddEntry(path);

                            foreach (string file in Directory.GetFiles(path))
                            {
                                AddEntry(file);
                            }

                            foreach (string dir in Directory.GetDirectories(path))
                            {
                                AddFolder(dir);
                            }
                        }

                        AddFolder(sourceRoot);
                    }

                outputFileStream.Position = 0;
                await newBlobClient.UploadAsync(outputFileStream);
            }

            Console.WriteLine("Cleaning up old blobs");
            List <BlobItem> blobs    = containerClient.GetBlobs(prefix: repoName + "/").ToList();
            List <BlobItem> toDelete = blobs.OrderByDescending(b => b.Name).Skip(10).ToList();

            foreach (BlobItem d in toDelete)
            {
                Console.WriteLine($"Deleting blob {d.Name}");
                await containerClient.DeleteBlobAsync(d.Name);
            }
            Console.WriteLine("Finished.");
        }
Esempio n. 22
0
 public async Task <Response> DeleteBlobAsync(string blobName)
 {
     return(await _client.DeleteBlobAsync(blobName));
 }
Esempio n. 23
0
        public async Task <DeletionResult> DeletePhotoAsync(string publicId)
        {
            await _containerClient.DeleteBlobAsync(publicId);

            return(new DeletionResult());
        }
Esempio n. 24
0
 public async Task DeleteAsync(string file)
 {
     await client.DeleteBlobAsync(file);
 }
Esempio n. 25
0
 /// <inheritdoc/>
 public Task <OperationResult> DeleteAsync(string name)
 {
     return(SafeExecuteAsync(() => container.DeleteBlobAsync(name), name));
 }
 public async Task DeleteBlobAsync(string blobName)
 {
     await _blobContainerClient.DeleteBlobAsync(blobName, DeleteSnapshotsOption.IncludeSnapshots);
 }