Skip to content

Commit 94d9f26

Browse files
authored
Merge branch 'dev' into main for job deployment.
See PR #10562.
2 parents 770e248 + 1c17122 commit 94d9f26

File tree

14 files changed

+259
-229
lines changed

14 files changed

+259
-229
lines changed

NuGetGallery.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 17
4-
VisualStudioVersion = 17.8.34118.359
3+
# Visual Studio Version 18
4+
VisualStudioVersion = 18.0.10925.136
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2. Frontend", "2. Frontend", "{05998089-58F5-4A84-8C11-C5C6244A6F89}"
77
EndProject

src/GitHubVulnerabilities2Db/Configuration/GitHubVulnerabilities2DbConfiguration.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using NuGet.Services.GitHub.Configuration;
@@ -21,5 +21,10 @@ public class GitHubVulnerabilities2DbConfiguration : GraphQLQueryConfiguration
2121
/// The name of the blob to save the job's advisories cursor in.
2222
/// </summary>
2323
public string AdvisoryCursorBlobName { get; set; } = "cursor.json";
24+
25+
/// <summary>
26+
/// The User-Agent header to send with each request to GitHub.
27+
/// </summary>
28+
public override string UserAgent { get; set; } = "NuGet.GitHubVulnerabilities2Db";
2429
}
25-
}
30+
}

src/GitHubVulnerabilities2v3/Configuration/GitHubVulnerabilities2v3Configuration.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using NuGet.Services.GitHub.Configuration;
@@ -50,5 +50,10 @@ public class GitHubVulnerabilities2v3Configuration : GraphQLQueryConfiguration
5050
/// Enable/disable HTTP file compression.
5151
/// </summary>
5252
public bool GzipFileContent { get; set; } = true;
53+
54+
/// <summary>
55+
/// The User-Agent header to send with each request to GitHub.
56+
/// </summary>
57+
public override string UserAgent { get; set; } = "NuGet.GitHubVulnerabilities2v3";
5358
}
54-
}
59+
}
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
55

66
namespace NuGet.Services.GitHub.Configuration
77
{
8-
public class GraphQLQueryConfiguration
8+
public abstract class GraphQLQueryConfiguration
99
{
1010
/// <summary>
1111
/// GitHub's v4 GraphQL API endpoint.
@@ -16,5 +16,15 @@ public class GraphQLQueryConfiguration
1616
/// The personal access token to use to authenticate with GitHub.
1717
/// </summary>
1818
public string GitHubPersonalAccessToken { get; set; }
19+
20+
/// <summary>
21+
/// The User-Agent header to send with each request to GitHub.
22+
/// </summary>
23+
public abstract string UserAgent { get; set; }
24+
25+
/// <summary>
26+
/// Time to wait between retries when a request to GitHub fails.
27+
/// </summary>
28+
public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(3);
1929
}
20-
}
30+
}

src/NuGet.Services.GitHub/GraphQL/QueryService.cs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Net;
56
using System.Net.Http;
67
using System.Net.Http.Headers;
78
using System.Text;
89
using System.Threading;
910
using System.Threading.Tasks;
10-
using NuGet.Services.GitHub.Configuration;
11+
using Microsoft.Extensions.Logging;
1112
using Newtonsoft.Json;
1213
using Newtonsoft.Json.Linq;
14+
using NuGet.Services.GitHub.Configuration;
1315

1416
namespace NuGet.Services.GitHub.GraphQL
1517
{
1618
public class QueryService : IQueryService
1719
{
18-
/// <remarks>
19-
/// GitHub requires that every request includes a UserAgent.
20-
/// </remarks>
21-
public const string UserAgent = "NuGet.Services.GitHub";
22-
2320
private readonly GraphQLQueryConfiguration _configuration;
2421
private readonly HttpClient _client;
22+
private readonly ILogger<QueryService> _logger;
2523

2624
public QueryService(
2725
GraphQLQueryConfiguration configuration,
28-
HttpClient client)
26+
HttpClient client,
27+
ILogger<QueryService> logger)
2928
{
3029
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
3130
_client = client ?? throw new ArgumentNullException(nameof(client));
31+
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
3232
}
3333

3434
public async Task<QueryResponse> QueryAsync(string query, CancellationToken token)
@@ -53,18 +53,32 @@ public async Task<QueryResponse> QueryAsync(string query, CancellationToken toke
5353

5454
private async Task<string> MakeWebRequestAsync(string query, CancellationToken token)
5555
{
56-
using (var request = CreateRequest(query))
57-
using (var response = await _client.SendAsync(request, token))
56+
var attempt = 0;
57+
const int maxAttempts = 5;
58+
HttpStatusCode? lastStatusCode = null;
59+
while (true)
5860
{
59-
var responseBody = await response.Content.ReadAsStringAsync();
60-
if (!response.IsSuccessStatusCode)
61+
try
6162
{
62-
throw new InvalidOperationException(
63-
$"The GitHub GraphQL response returned status code {(int)response.StatusCode} {response.ReasonPhrase}. " +
64-
$"Response body:{Environment.NewLine}{responseBody}");
63+
attempt++;
64+
lastStatusCode = null;
65+
using (var request = CreateRequest(query))
66+
using (var response = await _client.SendAsync(request, token))
67+
{
68+
lastStatusCode = response.StatusCode;
69+
response.EnsureSuccessStatusCode();
70+
return await response.Content.ReadAsStringAsync();
71+
}
72+
}
73+
catch (Exception ex) when (
74+
!token.IsCancellationRequested
75+
&& attempt < maxAttempts
76+
&& (!lastStatusCode.HasValue || lastStatusCode >= HttpStatusCode.InternalServerError)) // do not retry for 4XX errors
77+
{
78+
var delay = _configuration.RetryDelay;
79+
_logger.LogWarning(ex, "Failed attempt {Attempt} to query GitHub GraphQL API. Last HTTP status code: {Status}. Waiting {Seconds} seconds.", attempt, lastStatusCode, delay.TotalSeconds);
80+
await Task.Delay(delay, token);
6581
}
66-
67-
return responseBody;
6882
}
6983
}
7084

@@ -79,7 +93,7 @@ private HttpRequestMessage CreateRequest(string query)
7993

8094
message.Headers.Authorization = new AuthenticationHeaderValue(
8195
"Bearer", _configuration.GitHubPersonalAccessToken);
82-
message.Headers.UserAgent.TryParseAdd(UserAgent);
96+
message.Headers.UserAgent.TryParseAdd(_configuration.UserAgent);
8397
return message;
8498
}
8599
}
Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using NuGet.Services.GitHub.Configuration;
56

67
namespace VerifyGitHubVulnerabilities.Configuration
78
{
8-
public class VerifyGitHubVulnerabilitiesConfiguration
9+
public class VerifyGitHubVulnerabilitiesConfiguration : GraphQLQueryConfiguration
910
{
10-
/// <summary>
11-
/// GitHub's v4 GraphQL API endpoint.
12-
/// </summary>
13-
public Uri GitHubGraphQLQueryEndpoint { get; set; } = new Uri("https://api.github.com/graphql");
14-
15-
/// <summary>
16-
/// The personal access token to use to authenticate with GitHub.
17-
/// </summary>
18-
public string GitHubPersonalAccessToken { get; set; }
19-
2011
/// <summary>
2112
/// The v3 index URI string for fetching registration metadata
2213
/// </summary>
@@ -31,5 +22,10 @@ public class VerifyGitHubVulnerabilitiesConfiguration
3122
/// Whether to verify GitHubVulnerabilities in the registration blobs
3223
/// </summary>
3324
public bool VerifyRegistrationMetadata { get; set; } = true;
25+
26+
/// <summary>
27+
/// The User-Agent header to send with each request to GitHub.
28+
/// </summary>
29+
public override string UserAgent { get; set; } = "NuGet.VerifyGitHubVulnerabilities";
3430
}
35-
}
31+
}

src/VerifyGitHubVulnerabilities/GraphQL/QueryService.cs

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/VerifyGitHubVulnerabilities/Job.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -7,19 +7,20 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99
using Autofac;
10-
using NuGet.Services.GitHub.Collector;
11-
using NuGet.Services.GitHub.GraphQL;
12-
using NuGet.Services.GitHub.Ingest;
10+
using GitHubVulnerabilities2Db.Gallery;
1311
using Microsoft.Extensions.Configuration;
1412
using Microsoft.Extensions.DependencyInjection;
1513
using Microsoft.Extensions.Logging;
1614
using Microsoft.Extensions.Options;
1715
using NuGet.Jobs;
1816
using NuGet.Jobs.Configuration;
17+
using NuGet.Services.GitHub.Collector;
18+
using NuGet.Services.GitHub.Configuration;
19+
using NuGet.Services.GitHub.GraphQL;
20+
using NuGet.Services.GitHub.Ingest;
1921
using NuGetGallery;
2022
using VerifyGitHubVulnerabilities.Configuration;
2123
using VerifyGitHubVulnerabilities.Verify;
22-
using GitHubVulnerabilities2Db.Gallery;
2324

2425
namespace VerifyGitHubVulnerabilities
2526
{
@@ -60,6 +61,8 @@ protected override void ConfigureAutofacServices(ContainerBuilder containerBuild
6061
{
6162
containerBuilder
6263
.RegisterAdapter<IOptionsSnapshot<VerifyGitHubVulnerabilitiesConfiguration>, VerifyGitHubVulnerabilitiesConfiguration>(c => c.Value);
64+
containerBuilder
65+
.RegisterAdapter<IOptionsSnapshot<VerifyGitHubVulnerabilitiesConfiguration>, GraphQLQueryConfiguration>(c => c.Value);
6366

6467
ConfigureQueryServices(containerBuilder);
6568
ConfigureIngestionServices(containerBuilder);
@@ -110,7 +113,7 @@ protected void ConfigureQueryServices(ContainerBuilder containerBuilder)
110113
.As<HttpClient>();
111114

112115
containerBuilder
113-
.RegisterType<VerifyGitHubVulnerabilities.GraphQL.QueryService>()
116+
.RegisterType<QueryService>()
114117
.As<IQueryService>();
115118

116119
containerBuilder

tests/AccountDeleter.Facts/AccountDeleter.Facts.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
</PropertyGroup>
55
<ItemGroup>
66
<ProjectReference Include="..\..\src\AccountDeleter\AccountDeleter.csproj" />
7+
<ProjectReference Include="..\NuGetGallery.Core.Facts\NuGetGallery.Core.Facts.csproj" />
78
</ItemGroup>
89
<ItemGroup>
910
<PackageReference Include="Moq" />

tests/GitHubVulnerabilities2Db.Facts/GitHubVulnerabilities2Db.Facts.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
</PropertyGroup>
55
<ItemGroup>
66
<ProjectReference Include="..\..\src\GitHubVulnerabilities2Db\GitHubVulnerabilities2Db.csproj" />
7+
<ProjectReference Include="..\NuGetGallery.Core.Facts\NuGetGallery.Core.Facts.csproj" />
8+
<ProjectReference Include="..\NuGetGallery.Facts\NuGetGallery.Facts.csproj" />
79
</ItemGroup>
810
<ItemGroup>
911
<PackageReference Include="Moq" />

0 commit comments

Comments
 (0)