Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Commit 9d423ad

Browse files
committed
Merge branch 'dev' into master
2 parents 8f606a4 + 9061408 commit 9d423ad

82 files changed

Lines changed: 2571 additions & 137 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NuGet.Jobs.sln

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Services.Revalidate",
135135
EndProject
136136
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Services.Revalidate.Tests", "tests\NuGet.Services.Revalidate.Tests\NuGet.Services.Revalidate.Tests.csproj", "{19780DCB-B307-4254-B10C-4335FC784DEA}"
137137
EndProject
138+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Symbols.Core", "src\Validation.Symbols.Core\Validation.Symbols.Core.csproj", "{17510A22-176F-4E96-A867-E79F1B54F54F}"
139+
EndProject
140+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring.RebootSearchInstance", "src\Monitoring.RebootSearchInstance\Monitoring.RebootSearchInstance.csproj", "{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}"
141+
EndProject
142+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring.RebootSearchInstance.Tests", "tests\Monitoring.RebootSearchInstance.Tests\Monitoring.RebootSearchInstance.Tests.csproj", "{21C0A0EE-8696-4013-950F-D6495D0C6E40}"
143+
EndProject
138144
Global
139145
GlobalSection(SolutionConfigurationPlatforms) = preSolution
140146
Debug|Any CPU = Debug|Any CPU
@@ -351,6 +357,18 @@ Global
351357
{19780DCB-B307-4254-B10C-4335FC784DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
352358
{19780DCB-B307-4254-B10C-4335FC784DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
353359
{19780DCB-B307-4254-B10C-4335FC784DEA}.Release|Any CPU.Build.0 = Release|Any CPU
360+
{17510A22-176F-4E96-A867-E79F1B54F54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
361+
{17510A22-176F-4E96-A867-E79F1B54F54F}.Debug|Any CPU.Build.0 = Debug|Any CPU
362+
{17510A22-176F-4E96-A867-E79F1B54F54F}.Release|Any CPU.ActiveCfg = Release|Any CPU
363+
{17510A22-176F-4E96-A867-E79F1B54F54F}.Release|Any CPU.Build.0 = Release|Any CPU
364+
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
365+
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}.Debug|Any CPU.Build.0 = Debug|Any CPU
366+
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}.Release|Any CPU.ActiveCfg = Release|Any CPU
367+
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}.Release|Any CPU.Build.0 = Release|Any CPU
368+
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
369+
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Debug|Any CPU.Build.0 = Debug|Any CPU
370+
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Release|Any CPU.ActiveCfg = Release|Any CPU
371+
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Release|Any CPU.Build.0 = Release|Any CPU
354372
EndGlobalSection
355373
GlobalSection(SolutionProperties) = preSolution
356374
HideSolutionNode = FALSE
@@ -408,6 +426,9 @@ Global
408426
{60152AB1-2EB4-4D44-B6D6-EEE24209A1F7} = {6A776396-02B1-475D-A104-26940ADB04AB}
409427
{1963909D-8BE3-4CB8-B57E-AB6A8CB22FED} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
410428
{19780DCB-B307-4254-B10C-4335FC784DEA} = {6A776396-02B1-475D-A104-26940ADB04AB}
429+
{17510A22-176F-4E96-A867-E79F1B54F54F} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
430+
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66} = {814F9B31-4AF3-46CC-AD61-CEB40F47083A}
431+
{21C0A0EE-8696-4013-950F-D6495D0C6E40} = {6A776396-02B1-475D-A104-26940ADB04AB}
411432
EndGlobalSection
412433
GlobalSection(ExtensibilityGlobals) = postSolution
413434
SolutionGuid = {284A7AC3-FB43-4F1F-9C9C-2AF0E1F46C2B}

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ NuGet.Jobs
2020
2121
7. Also, add settings.job file to mark the job as singleton, if the job will be run as a webjob, and it be a continuously running singleton
2222
23+
## Specific instructions
24+
25+
This repository has a lot of jobs used for completely different purposes. For this reason, each should should have its
26+
own documentation. This specific documentation is far from complete... but you have to start somewhere!
27+
28+
- [Monitoring.RebootSearchInstance](src/Monitoring.RebootSearchInstance/README.md) - check each region for stuck search instances and restart them
29+
2330
Open Source Code of Conduct
2431
===================
2532
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

build.ps1

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ Invoke-BuildStep 'Set version metadata in AssemblyInfo.cs' { `
114114
"$PSScriptRoot\src\NuGet.Jobs.Common\Properties\AssemblyInfo.g.cs",
115115
"$PSScriptRoot\src\Validation.Common.Job\Properties\AssemblyInfo.g.cs",
116116
"$PSScriptRoot\src\Validation.ScanAndSign.Core\Properties\AssemblyInfo.g.cs",
117-
"$PSScriptRoot\src\PackageLagMonitor\Properties\AssemblyInfo.g.cs"
117+
"$PSScriptRoot\src\PackageLagMonitor\Properties\AssemblyInfo.g.cs",
118+
"$PSScriptRoot\src\Validation.Symbols.Core\Properties\AssemblyInfo.g.cs",
119+
"$PSScriptRoot\src\Monitoring.RebootSearchInstance\Properties\AssemblyInfo.g.cs"
118120

119121
$versionMetadata | ForEach-Object {
120122
Set-VersionInfo -Path $_ -Version $SimpleVersion -Branch $Branch -Commit $CommitSHA
@@ -173,7 +175,9 @@ Invoke-BuildStep 'Creating artifacts' {
173175
"src/Validation.PackageSigning.ProcessSignature/Validation.PackageSigning.ProcessSignature.csproj", `
174176
"src/Validation.PackageSigning.ValidateCertificate/Validation.PackageSigning.ValidateCertificate.csproj", `
175177
"src/Validation.PackageSigning.RevalidateCertificate/Validation.PackageSigning.RevalidateCertificate.csproj", `
176-
"src/PackageLagMonitor/Monitoring.PackageLag.csproj" `
178+
"src/PackageLagMonitor/Monitoring.PackageLag.csproj", `
179+
"src/Validation.Symbols.Core/Validation.Symbols.Core.csproj", `
180+
"src/Monitoring.RebootSearchInstance/Monitoring.RebootSearchInstance.csproj" `
177181
+ $ProjectsWithSymbols
178182

179183
Foreach ($Project in $Projects) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
5+
</startup>
6+
</configuration>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Globalization;
7+
using System.Linq;
8+
using System.Net.Http;
9+
using System.Threading.Tasks;
10+
using System.Xml.Linq;
11+
using Autofac;
12+
using Microsoft.Extensions.Logging;
13+
using Microsoft.Extensions.Options;
14+
15+
namespace NuGet.Monitoring.RebootSearchInstance
16+
{
17+
public class FeedClient : IFeedClient
18+
{
19+
private const string FeedRelativeUrl =
20+
"api/v2/Packages?" +
21+
"$filter={0}%20ne%20null&" +
22+
"$top=1&" +
23+
"$orderby={0}%20desc&" +
24+
"$select={0}";
25+
26+
private static readonly IEnumerable<string> TimeStampProperties = new string[]
27+
{
28+
"Created",
29+
"LastEdited",
30+
};
31+
32+
private readonly HttpClient _httpClient;
33+
private readonly IOptionsSnapshot<MonitorConfiguration> _configuration;
34+
private readonly ILogger<FeedClient> _logger;
35+
36+
public FeedClient(HttpClient httpClient, IOptionsSnapshot<MonitorConfiguration> configuration, ILogger<FeedClient> logger)
37+
{
38+
_httpClient = httpClient;
39+
_configuration = configuration;
40+
_logger = logger;
41+
}
42+
43+
public async Task<DateTimeOffset> GetLatestFeedTimeStampAsync()
44+
{
45+
var tasks = TimeStampProperties
46+
.Select(GetLatestFeedTimeStampAsync)
47+
.ToList();
48+
49+
await Task.WhenAll(tasks);
50+
51+
return tasks.Max(t => t.Result);
52+
}
53+
54+
private async Task<DateTimeOffset> GetLatestFeedTimeStampAsync(string propertyName)
55+
{
56+
var galleryBaseUrl = _configuration.Value.FeedUrl;
57+
var feedUrl = new Uri(galleryBaseUrl).GetLeftPart(UriPartial.Authority);
58+
var url = $"{feedUrl}/{string.Format(FeedRelativeUrl, propertyName)}";
59+
using (var stream = await _httpClient.GetStreamAsync(url))
60+
{
61+
var packagesResultObject = XDocument.Load(stream);
62+
var propertyValue = DateTimeOffset.Parse(
63+
packagesResultObject.Descendants()
64+
.Where(a => a.Name.LocalName == propertyName)
65+
.FirstOrDefault().Value,
66+
formatProvider: null,
67+
styles: DateTimeStyles.AssumeUniversal);
68+
_logger.LogInformation("Feed at {GalleryBaseUrl} has {TimeStampPropertyName} cursor at {TimeStampPropertyValue}", galleryBaseUrl, propertyName, propertyValue);
69+
return propertyValue;
70+
}
71+
}
72+
}
73+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Threading.Tasks;
6+
7+
namespace NuGet.Monitoring.RebootSearchInstance
8+
{
9+
public interface IFeedClient
10+
{
11+
Task<DateTimeOffset> GetLatestFeedTimeStampAsync();
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace NuGet.Monitoring.RebootSearchInstance
8+
{
9+
public interface ISearchInstanceRebooter
10+
{
11+
Task RunAsync(CancellationToken token);
12+
}
13+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace NuGet.Monitoring.RebootSearchInstance
7+
{
8+
public interface ITelemetryService
9+
{
10+
void TrackHealthyInstanceCount(string region, int count);
11+
void TrackInstanceCount(string region, int count);
12+
void TrackInstanceReboot(string region, int index);
13+
void TrackInstanceRebootDuration(string region, int index, TimeSpan duration, InstanceHealth health);
14+
void TrackUnhealthyInstanceCount(string region, int count);
15+
void TrackUnknownInstanceCount(string region, int count);
16+
}
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace NuGet.Monitoring.RebootSearchInstance
5+
{
6+
public enum InstanceHealth
7+
{
8+
Healthy,
9+
Unhealthy,
10+
Unknown,
11+
}
12+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Net;
6+
using System.Net.Http;
7+
using System.Reflection;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Autofac;
11+
using Microsoft.Extensions.Configuration;
12+
using Microsoft.Extensions.DependencyInjection;
13+
using Microsoft.Extensions.Options;
14+
using NuGet.Jobs.Montoring.PackageLag;
15+
using NuGet.Jobs.Validation;
16+
using NuGet.Services.AzureManagement;
17+
18+
namespace NuGet.Monitoring.RebootSearchInstance
19+
{
20+
public class Job : JsonConfigurationJob
21+
{
22+
private const string AzureManagementSectionName = "AzureManagement";
23+
private const string MonitorConfigurationSectionName = "MonitorConfiguration";
24+
25+
public override async Task Run()
26+
{
27+
using (var scope = _serviceProvider.CreateScope())
28+
{
29+
var rebooter = scope.ServiceProvider.GetRequiredService<ISearchInstanceRebooter>();
30+
await rebooter.RunAsync(CancellationToken.None);
31+
}
32+
}
33+
34+
protected override void ConfigureJobServices(IServiceCollection services, IConfigurationRoot configurationRoot)
35+
{
36+
services.Configure<MonitorConfiguration>(configurationRoot.GetSection(MonitorConfigurationSectionName));
37+
services.Configure<SearchServiceConfiguration>(configurationRoot.GetSection(MonitorConfigurationSectionName));
38+
services.Configure<AzureManagementAPIWrapperConfiguration>(configurationRoot.GetSection(AzureManagementSectionName));
39+
40+
services.AddTransient<ITelemetryService, TelemetryService>();
41+
services.AddTransient<ISearchInstanceRebooter, SearchInstanceRebooter>();
42+
services.AddTransient<IFeedClient, FeedClient>();
43+
services.AddTransient<ISearchServiceClient, SearchServiceClient>();
44+
services.AddSingleton<IAzureManagementAPIWrapper, AzureManagementAPIWrapper>();
45+
services.AddTransient<IAzureManagementAPIWrapperConfiguration>(p => p.GetService<IOptionsSnapshot<AzureManagementAPIWrapperConfiguration>>().Value);
46+
47+
services.AddSingleton(p =>
48+
{
49+
var assembly = Assembly.GetEntryAssembly();
50+
var assemblyName = assembly.GetName().Name;
51+
var assemblyVersion = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "0.0.0";
52+
53+
var client = new HttpClient(new WebRequestHandler
54+
{
55+
AllowPipelining = true,
56+
AutomaticDecompression = (DecompressionMethods.GZip | DecompressionMethods.Deflate),
57+
ServerCertificateCustomValidationCallback =
58+
(httpRequestMessage, cert, cetChain, policyErrors) =>
59+
{
60+
if (policyErrors == System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch || policyErrors == System.Net.Security.SslPolicyErrors.None)
61+
{
62+
return true;
63+
}
64+
65+
return false;
66+
},
67+
});
68+
69+
client.DefaultRequestHeaders.Add("User-Agent", $"{assemblyName}/{assemblyVersion}");
70+
client.Timeout = TimeSpan.FromSeconds(10);
71+
72+
return client;
73+
});
74+
}
75+
76+
protected override void ConfigureAutofacServices(ContainerBuilder containerBuilder)
77+
{
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)