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

Commit 01298d9

Browse files
authored
Merge pull request #502 from NuGet/dev
[ReleasePrep][2018.07.31]RI of dev into master
2 parents 377a83b + 94dbf50 commit 01298d9

99 files changed

Lines changed: 4899 additions & 16 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/NuGet.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<packageSources>
77
<add key="nugetbuild" value="https://dotnet.myget.org/F/nuget-build/api/v3/index.json" />
88
<add key="nuget.org" value="https://www.nuget.org/api/v2" />
9+
<add key="dotnet.core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
910
</packageSources>
1011
<disabledPackageSources>
1112
<clear />

NuGet.Jobs.sln

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Common.Job", "sr
107107
EndProject
108108
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PackageHash", "src\PackageHash\PackageHash.csproj", "{40843020-6F0A-48F0-AC28-42FFE3A5C21E}"
109109
EndProject
110+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusAggregator", "src\StatusAggregator\StatusAggregator.csproj", "{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB}"
111+
EndProject
110112
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Common.Job.Tests", "tests\Validation.Common.Job.Tests\Validation.Common.Job.Tests.csproj", "{430F63C7-20C2-4872-AC3E-DDE846E50AA4}"
111113
EndProject
112114
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.PackageSigning.ProcessSignature", "src\Validation.PackageSigning.ProcessSignature\Validation.PackageSigning.ProcessSignature.csproj", "{DD043977-6BCD-475A-BEE2-8C34309EC622}"
@@ -135,12 +137,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Services.Revalidate",
135137
EndProject
136138
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}"
137139
EndProject
140+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusAggregator.Tests", "tests\StatusAggregator.Tests\StatusAggregator.Tests.csproj", "{784F938D-4142-4C1C-B654-0978FEAD1731}"
141+
EndProject
138142
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Symbols.Core", "src\Validation.Symbols.Core\Validation.Symbols.Core.csproj", "{17510A22-176F-4E96-A867-E79F1B54F54F}"
139143
EndProject
140144
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring.RebootSearchInstance", "src\Monitoring.RebootSearchInstance\Monitoring.RebootSearchInstance.csproj", "{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66}"
141145
EndProject
142146
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring.RebootSearchInstance.Tests", "tests\Monitoring.RebootSearchInstance.Tests\Monitoring.RebootSearchInstance.Tests.csproj", "{21C0A0EE-8696-4013-950F-D6495D0C6E40}"
143147
EndProject
148+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Symbols", "src\Validation.Symbols\Validation.Symbols.csproj", "{2DD07A73-8C88-4429-BB24-C2813586EF92}"
149+
EndProject
150+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validation.Symbols.Tests", "tests\Validation.Symbols.Tests\Validation.Symbols.Tests.csproj", "{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503}"
151+
EndProject
144152
Global
145153
GlobalSection(SolutionConfigurationPlatforms) = preSolution
146154
Debug|Any CPU = Debug|Any CPU
@@ -305,6 +313,10 @@ Global
305313
{40843020-6F0A-48F0-AC28-42FFE3A5C21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
306314
{40843020-6F0A-48F0-AC28-42FFE3A5C21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
307315
{40843020-6F0A-48F0-AC28-42FFE3A5C21E}.Release|Any CPU.Build.0 = Release|Any CPU
316+
{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
317+
{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
318+
{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
319+
{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB}.Release|Any CPU.Build.0 = Release|Any CPU
308320
{430F63C7-20C2-4872-AC3E-DDE846E50AA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
309321
{430F63C7-20C2-4872-AC3E-DDE846E50AA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
310322
{430F63C7-20C2-4872-AC3E-DDE846E50AA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -357,6 +369,10 @@ Global
357369
{19780DCB-B307-4254-B10C-4335FC784DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
358370
{19780DCB-B307-4254-B10C-4335FC784DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
359371
{19780DCB-B307-4254-B10C-4335FC784DEA}.Release|Any CPU.Build.0 = Release|Any CPU
372+
{784F938D-4142-4C1C-B654-0978FEAD1731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
373+
{784F938D-4142-4C1C-B654-0978FEAD1731}.Debug|Any CPU.Build.0 = Debug|Any CPU
374+
{784F938D-4142-4C1C-B654-0978FEAD1731}.Release|Any CPU.ActiveCfg = Release|Any CPU
375+
{784F938D-4142-4C1C-B654-0978FEAD1731}.Release|Any CPU.Build.0 = Release|Any CPU
360376
{17510A22-176F-4E96-A867-E79F1B54F54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
361377
{17510A22-176F-4E96-A867-E79F1B54F54F}.Debug|Any CPU.Build.0 = Debug|Any CPU
362378
{17510A22-176F-4E96-A867-E79F1B54F54F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -369,6 +385,14 @@ Global
369385
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Debug|Any CPU.Build.0 = Debug|Any CPU
370386
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Release|Any CPU.ActiveCfg = Release|Any CPU
371387
{21C0A0EE-8696-4013-950F-D6495D0C6E40}.Release|Any CPU.Build.0 = Release|Any CPU
388+
{2DD07A73-8C88-4429-BB24-C2813586EF92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
389+
{2DD07A73-8C88-4429-BB24-C2813586EF92}.Debug|Any CPU.Build.0 = Debug|Any CPU
390+
{2DD07A73-8C88-4429-BB24-C2813586EF92}.Release|Any CPU.ActiveCfg = Release|Any CPU
391+
{2DD07A73-8C88-4429-BB24-C2813586EF92}.Release|Any CPU.Build.0 = Release|Any CPU
392+
{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
393+
{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503}.Debug|Any CPU.Build.0 = Debug|Any CPU
394+
{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503}.Release|Any CPU.ActiveCfg = Release|Any CPU
395+
{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503}.Release|Any CPU.Build.0 = Release|Any CPU
372396
EndGlobalSection
373397
GlobalSection(SolutionProperties) = preSolution
374398
HideSolutionNode = FALSE
@@ -413,6 +437,7 @@ Global
413437
{B4B7564A-965B-447B-927F-6749E2C08880} = {6A776396-02B1-475D-A104-26940ADB04AB}
414438
{FA87D075-A934-4443-8D0B-5DB32640B6D7} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
415439
{40843020-6F0A-48F0-AC28-42FFE3A5C21E} = {FA5644B5-4F08-43F6-86B3-039374312A47}
440+
{D357FDB5-BF19-41A5-82B0-14C8CEC2A5EB} = {FA5644B5-4F08-43F6-86B3-039374312A47}
416441
{430F63C7-20C2-4872-AC3E-DDE846E50AA4} = {6A776396-02B1-475D-A104-26940ADB04AB}
417442
{DD043977-6BCD-475A-BEE2-8C34309EC622} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
418443
{ED2D370C-D921-433A-A0B9-A601F936EDD3} = {FA5644B5-4F08-43F6-86B3-039374312A47}
@@ -426,9 +451,12 @@ Global
426451
{60152AB1-2EB4-4D44-B6D6-EEE24209A1F7} = {6A776396-02B1-475D-A104-26940ADB04AB}
427452
{1963909D-8BE3-4CB8-B57E-AB6A8CB22FED} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
428453
{19780DCB-B307-4254-B10C-4335FC784DEA} = {6A776396-02B1-475D-A104-26940ADB04AB}
454+
{784F938D-4142-4C1C-B654-0978FEAD1731} = {6A776396-02B1-475D-A104-26940ADB04AB}
429455
{17510A22-176F-4E96-A867-E79F1B54F54F} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
430456
{ECD8DFCE-8E3C-4510-AFE3-D7EC168E8D66} = {814F9B31-4AF3-46CC-AD61-CEB40F47083A}
431457
{21C0A0EE-8696-4013-950F-D6495D0C6E40} = {6A776396-02B1-475D-A104-26940ADB04AB}
458+
{2DD07A73-8C88-4429-BB24-C2813586EF92} = {678D7B14-F8BC-4193-99AF-2EE8AA390A02}
459+
{640D29AB-4D1B-4FC7-AE67-AD12EE5AC503} = {6A776396-02B1-475D-A104-26940ADB04AB}
432460
EndGlobalSection
433461
GlobalSection(ExtensibilityGlobals) = postSolution
434462
SolutionGuid = {284A7AC3-FB43-4F1F-9C9C-2AF0E1F46C2B}

build.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Invoke-BuildStep 'Set version metadata in AssemblyInfo.cs' { `
115115
"$PSScriptRoot\src\Validation.Common.Job\Properties\AssemblyInfo.g.cs",
116116
"$PSScriptRoot\src\Validation.ScanAndSign.Core\Properties\AssemblyInfo.g.cs",
117117
"$PSScriptRoot\src\PackageLagMonitor\Properties\AssemblyInfo.g.cs",
118+
"$PSScriptRoot\src\StatusAggregator\Properties\AssemblyInfo.g.cs",
118119
"$PSScriptRoot\src\Validation.Symbols.Core\Properties\AssemblyInfo.g.cs",
119120
"$PSScriptRoot\src\Monitoring.RebootSearchInstance\Properties\AssemblyInfo.g.cs"
120121

@@ -149,7 +150,8 @@ Invoke-BuildStep 'Creating artifacts' {
149150
$ProjectsWithSymbols =
150151
"src/NuGet.Jobs.Common/NuGet.Jobs.Common.csproj",
151152
"src/Validation.Common.Job/Validation.Common.Job.csproj",
152-
"src/Validation.ScanAndSign.Core/Validation.ScanAndSign.Core.csproj"
153+
"src/Validation.ScanAndSign.Core/Validation.ScanAndSign.Core.csproj",
154+
"src/Validation.Symbols.Core/Validation.Symbols.Core.csproj"
153155

154156
$Projects = `
155157
"src/Stats.CollectAzureCdnLogs/Stats.CollectAzureCdnLogs.csproj", `
@@ -176,8 +178,9 @@ Invoke-BuildStep 'Creating artifacts' {
176178
"src/Validation.PackageSigning.ValidateCertificate/Validation.PackageSigning.ValidateCertificate.csproj", `
177179
"src/Validation.PackageSigning.RevalidateCertificate/Validation.PackageSigning.RevalidateCertificate.csproj", `
178180
"src/PackageLagMonitor/Monitoring.PackageLag.csproj", `
181+
"src/StatusAggregator/StatusAggregator.csproj", `
179182
"src/Validation.Symbols.Core/Validation.Symbols.Core.csproj", `
180-
"src/Monitoring.RebootSearchInstance/Monitoring.RebootSearchInstance.csproj" `
183+
"src/Validation.Symbols/Validation.Symbols.csproj" `
181184
+ $ProjectsWithSymbols
182185

183186
Foreach ($Project in $Projects) {

src/NuGet.Jobs.Common/Configuration/JobArgumentNames.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ public static class JobArgumentNames
118118
public const string MailFrom = "MailFrom";
119119
public const string SmtpUri = "SmtpUri";
120120

121+
// Arguments specific to StatusAggregator
122+
public const string StatusStorageAccount = "StatusStorageAccount";
123+
public const string StatusContainerName = "StatusContainerName";
124+
public const string StatusTableName = "StatusTableName";
125+
public const string StatusEnvironment = "StatusEnvironment";
126+
public const string StatusMaximumSeverity = "StatusMaximumSeverity";
127+
public const string StatusIncidentApiBaseUri = "StatusIncidentApiBaseUri";
128+
public const string StatusIncidentApiCertificate = "StatusIncidentApiCertificate";
129+
public const string StatusIncidentApiTeamId = "StatusIncidentApiTeamId";
130+
public const string StatusEventStartMessageDelayMinutes = "StatusEventStartMessageDelayMinutes";
131+
public const string StatusEventEndDelayMinutes = "StatusEventEndDelayMinutes";
132+
public const string StatusEventVisibilityPeriodDays = "StatusEventVisibilityPeriodDays";
133+
121134
// Arguments specific to Stats.AggregateCdnDownloadsInGallery
122135
public static string BatchSleepSeconds = "BatchSleepSeconds";
123136
}

src/NuGet.Jobs.Common/Configuration/JobConfigurationManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
using System.Collections.Generic;
66
using System.ComponentModel.Design;
77
using System.Linq;
8+
using Microsoft.Extensions.DependencyInjection;
89
using Microsoft.Extensions.Logging;
10+
using NuGet.Jobs.Extensions;
911
using NuGet.Services.Configuration;
1012
using NuGet.Services.KeyVault;
1113

@@ -190,7 +192,7 @@ private static Dictionary<string, string> ReadCommandLineArguments(ILogger logge
190192

191193
private static IDictionary<string, string> InjectSecrets(IServiceContainer serviceContainer, Dictionary<string, string> argsDictionary)
192194
{
193-
var secretReaderFactory = (ISecretReaderFactory)serviceContainer.GetService(typeof(ISecretReaderFactory));
195+
var secretReaderFactory = serviceContainer.GetRequiredService<ISecretReaderFactory>();
194196

195197
var secretReader = secretReaderFactory.CreateSecretReader(argsDictionary);
196198
if (secretReader == null)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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 Microsoft.Extensions.Logging;
5+
using System;
6+
7+
namespace NuGet.Jobs.Extensions
8+
{
9+
public static class LoggerExtensions
10+
{
11+
/// <summary>
12+
/// Calls <see cref="ILogger.BeginScope{TState}(TState)"/> and logs a message when entering and leaving the scope.
13+
/// </summary>
14+
public static IDisposable Scope(
15+
this ILogger logger,
16+
string message,
17+
params object[] args)
18+
{
19+
return new LoggerScopeHelper(logger, message, args);
20+
}
21+
22+
private class LoggerScopeHelper : IDisposable
23+
{
24+
private readonly ILogger _logger;
25+
private readonly IDisposable _scope;
26+
27+
private readonly string _message;
28+
private readonly object[] _args;
29+
30+
private bool _isDisposed = false;
31+
32+
public LoggerScopeHelper(
33+
ILogger logger, string message, object[] args)
34+
{
35+
_logger = logger;
36+
_message = message;
37+
_args = args;
38+
39+
_scope = logger.BeginScope(_message, _args);
40+
_logger.LogInformation("Entering scope: " + _message, _args);
41+
}
42+
43+
public void Dispose()
44+
{
45+
if (!_isDisposed)
46+
{
47+
_logger.LogInformation("Leaving scope: " + _message, _args);
48+
_scope?.Dispose(); // ILogger can return a null scope (most notably during testing with a Mock<ILogger>)
49+
_isDisposed = true;
50+
}
51+
}
52+
}
53+
}
54+
}

src/NuGet.Jobs.Common/NuGet.Jobs.Common.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<Compile Include="Configuration\ServiceBusConfiguration.cs" />
5050
<Compile Include="Configuration\ValidationDbConfiguration.cs" />
5151
<Compile Include="Configuration\ValidationStorageConfiguration.cs" />
52+
<Compile Include="Extensions\LoggerExtensions.cs" />
5253
<Compile Include="Extensions\SqlConnectionStringBuilderExtensions.cs" />
5354
<Compile Include="Extensions\XElementExtensions.cs" />
5455
<Compile Include="SecretReader\ISecretReaderFactory.cs" />

src/NuGet.Services.Validation.Orchestrator/NuGet.Services.Validation.Orchestrator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
<Version>2.26.0-master-34394</Version>
128128
</PackageReference>
129129
<PackageReference Include="NuGet.Services.Validation.Issues">
130-
<Version>2.26.0-master-34394</Version>
130+
<Version>2.27.0-master-35351</Version>
131131
</PackageReference>
132132
</ItemGroup>
133133
<ItemGroup>

src/NuGet.Services.Validation.Orchestrator/PackageSigning/ScanAndSign/ScanAndSignProcessor.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
using System.Collections.Generic;
66
using System.Data.Entity;
77
using System.Linq;
8+
using System.Text.RegularExpressions;
89
using System.Threading.Tasks;
910
using Microsoft.Extensions.Logging;
1011
using Microsoft.Extensions.Options;
1112
using NuGet.Jobs.Validation;
12-
using NuGet.Jobs.Validation.Storage;
1313
using NuGet.Jobs.Validation.ScanAndSign;
14+
using NuGet.Jobs.Validation.Storage;
1415
using NuGet.Services.Validation.Vcs;
1516
using NuGetGallery;
1617

@@ -19,6 +20,8 @@ namespace NuGet.Services.Validation.Orchestrator.PackageSigning.ScanAndSign
1920
[ValidatorName(ValidatorName.ScanAndSign)]
2021
public class ScanAndSignProcessor : IProcessor
2122
{
23+
private const string UsernameRegex = @"^[A-Za-z0-9][A-Za-z0-9_\.-]+[A-Za-z0-9]$";
24+
2225
private readonly IValidationEntitiesContext _validationContext;
2326
private readonly IValidatorStateService _validatorStateService;
2427
private readonly ICorePackageService _packageService;
@@ -131,10 +134,10 @@ public async Task<IValidationResult> StartAsync(IValidationRequest request)
131134
return processorStatus.ToValidationResult();
132135
}
133136

134-
if (await ShouldRepositorySignAsync(request))
135-
{
136-
var owners = FindPackageOwners(request);
137+
var owners = FindPackageOwners(request);
137138

139+
if (await ShouldRepositorySignAsync(request, owners))
140+
{
138141
_logger.LogInformation(
139142
"Repository signing {PackageId} {PackageVersion} with {ServiceIndex} and {Owners}",
140143
request.PackageId,
@@ -197,7 +200,7 @@ private bool ShouldSkipScan(IValidationRequest request)
197200
return false;
198201
}
199202

200-
private async Task<bool> ShouldRepositorySignAsync(IValidationRequest request)
203+
private async Task<bool> ShouldRepositorySignAsync(IValidationRequest request, List<string> owners)
201204
{
202205
var hasRepositorySignature = await _validationContext
203206
.PackageSignatures
@@ -215,7 +218,18 @@ private async Task<bool> ShouldRepositorySignAsync(IValidationRequest request)
215218
return false;
216219
}
217220

218-
return true;
221+
if (owners.Any(IsInvalidUsername))
222+
{
223+
_logger.LogWarning(
224+
"Package {PackageId} {PackageVersion} has an owner with an invalid username. Scanning instead of signing. {Owners}",
225+
request.PackageId,
226+
request.PackageVersion,
227+
owners);
228+
229+
return false;
230+
}
231+
232+
return true;
219233
}
220234

221235
private List<string> FindPackageOwners(IValidationRequest request)
@@ -234,5 +248,10 @@ private List<string> FindPackageOwners(IValidationRequest request)
234248
.Select(o => o.Username)
235249
.ToList();
236250
}
251+
252+
private bool IsInvalidUsername(string username)
253+
{
254+
return !Regex.IsMatch(username, UsernameRegex, RegexOptions.None, TimeSpan.FromSeconds(5));
255+
}
237256
}
238257
}

src/StatusAggregator/Cursor.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
using Microsoft.Extensions.Logging;
7+
using NuGet.Jobs.Extensions;
8+
using NuGet.Services.Status.Table;
9+
using StatusAggregator.Table;
10+
11+
namespace StatusAggregator
12+
{
13+
public class Cursor : ICursor
14+
{
15+
public Cursor(
16+
ITableWrapper table,
17+
ILogger<Cursor> logger)
18+
{
19+
_table = table ?? throw new ArgumentNullException(nameof(table));
20+
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
21+
}
22+
23+
private readonly ITableWrapper _table;
24+
25+
private readonly ILogger<Cursor> _logger;
26+
27+
public async Task<DateTime> Get()
28+
{
29+
using (_logger.Scope("Fetching cursor."))
30+
{
31+
var cursor = await _table.Retrieve<CursorEntity>(
32+
CursorEntity.DefaultPartitionKey, CursorEntity.DefaultRowKey);
33+
34+
DateTime value;
35+
if (cursor == null)
36+
{
37+
// If we can't find a cursor, the job is likely uninitialized, so start at the beginning of time.
38+
value = DateTime.MinValue;
39+
_logger.LogInformation("Could not fetch cursor, reinitializing cursor at {Cursor}.", value);
40+
}
41+
else
42+
{
43+
value = cursor.Value;
44+
_logger.LogInformation("Fetched cursor with value {Cursor}.", value);
45+
}
46+
47+
return value;
48+
}
49+
}
50+
51+
public Task Set(DateTime value)
52+
{
53+
using (_logger.Scope("Updating cursor to {Cursor}.", value))
54+
{
55+
var cursorEntity = new CursorEntity(value);
56+
return _table.InsertOrReplaceAsync(cursorEntity);
57+
}
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)