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

Commit d436073

Browse files
committed
Merge branch 'dev' into merge-master
2 parents b327fdf + eafa854 commit d436073

48 files changed

Lines changed: 1234 additions & 143 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.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,5 @@ Results.*.xml
207207
AssemblyInfo.*.cs
208208
/tests/Validation.Helper.Tests/Validation.Helper.Tests.nuget.props
209209
/tests/Validation.Common.Tests/Validation.Common.Tests.nuget.props
210+
/tests/Validation.Common.Tests/Validation.Common.Tests.nuget.targets
211+
/tests/Validation.Helper.Tests/Validation.Helper.Tests.nuget.targets

src/NuGet.Services.Validation.Orchestrator/IValidationSetProvider.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ public interface IValidationSetProvider
1717
/// </summary>
1818
/// <param name="validationTrackingId">Validation tracking id</param>
1919
/// <param name="package">Package details from Gallery DB</param>
20-
/// <returns><see cref="PackageValidationSet"/> object with information about requested <paramref name="validationTrackingId"/></returns>
21-
Task<PackageValidationSet> GetOrCreateValidationSetAsync(Guid validationTrackingId, Package package);
20+
/// <returns><see cref="PackageValidationSet"/> object with information about
21+
/// requested <paramref name="validationTrackingId"/>. Null if no further processing
22+
/// should be made (e.g. duplicate validation request was detected).
23+
/// </returns>
24+
Task<PackageValidationSet> TryGetOrCreateValidationSetAsync(Guid validationTrackingId, Package package);
2225
}
2326
}

src/NuGet.Services.Validation.Orchestrator/IValidationStorageService.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ public interface IValidationStorageService
2525
/// <returns>Validation set instance if found, null otherwise.</returns>
2626
Task<PackageValidationSet> GetValidationSetAsync(Guid validationTrackingId);
2727

28+
/// <summary>
29+
/// Gets the number of validation sets that the provided package key has.
30+
/// </summary>
31+
/// <param name="packageKey">The package key.</param>
32+
/// <returns>The count.</returns>
33+
Task<int> GetValidationSetCountAsync(int packageKey);
34+
2835
/// <summary>
2936
/// Updates the passed <see cref="PackageValidation"/> with the validation result's status,
3037
/// updates the <see cref="PackageValidation.ValidationStatusTimestamp"/> to current timestamp,
@@ -50,5 +57,20 @@ public interface IValidationStorageService
5057
/// <param name="validationResult">The result of the validation.</param>
5158
/// <returns>Task object tracking the async operation status.</returns>
5259
Task UpdateValidationStatusAsync(PackageValidation packageValidation, IValidationResult validationResult);
60+
61+
/// <summary>
62+
/// Checks whether a validation set was created within the time range specified
63+
/// by <paramref name="recentDuration"/> argument with tracking id that is different
64+
/// from the supplied as a <paramref name="currentValidationSetTrackingId"/> argument.
65+
/// </summary>
66+
/// <param name="packageId">Package ID for which recent validation sets are to be looked up.</param>
67+
/// <param name="normalizedVersion">Normalized version of the package.</param>
68+
/// <param name="recentDuration">Max amount of time to look back.</param>
69+
/// <param name="currentValidationSetTrackingId">Validation set tracking for the currently processed request.</param>
70+
/// <returns>True if validation set exists, false otherwise.</returns>
71+
Task<bool> OtherRecentValidationSetForPackageExists(
72+
int packageKey,
73+
TimeSpan recentDuration,
74+
Guid currentValidationSetTrackingId);
5375
}
5476
}

src/NuGet.Services.Validation.Orchestrator/Job.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Autofac;
1111
using Autofac.Core;
1212
using Autofac.Extensions.DependencyInjection;
13+
using Microsoft.ApplicationInsights;
1314
using Microsoft.Extensions.Configuration;
1415
using Microsoft.Extensions.DependencyInjection;
1516
using Microsoft.Extensions.Logging;
@@ -22,7 +23,9 @@
2223
using NuGet.Jobs.Validation.PackageSigning.Storage;
2324
using NuGet.Services.Configuration;
2425
using NuGet.Services.KeyVault;
26+
using NuGet.Services.Logging;
2527
using NuGet.Services.ServiceBus;
28+
using NuGet.Services.Validation.Orchestrator.Telemetry;
2629
using NuGet.Services.Validation.PackageCertificates;
2730
using NuGet.Services.Validation.PackageSigning;
2831
using NuGet.Services.Validation.Vcs;
@@ -207,6 +210,8 @@ private void ConfigureJobServices(IServiceCollection services, IConfigurationRoo
207210
services.AddTransient<ICoreMessageServiceConfiguration, CoreMessageServiceConfiguration>();
208211
services.AddTransient<ICoreMessageService, CoreMessageService>();
209212
services.AddTransient<IMessageService, MessageService>();
213+
services.AddTransient<ITelemetryService, TelemetryService>();
214+
services.AddSingleton(new TelemetryClient());
210215
}
211216

212217
private static IServiceProvider CreateProvider(IServiceCollection services)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
<Compile Include="Properties\AssemblyInfo.cs" />
7373
<Compile Include="Properties\AssemblyInfo.*.cs" />
7474
<Compile Include="SmtpConfiguration.cs" />
75+
<Compile Include="Telemetry\ITelemetryService.cs" />
76+
<Compile Include="Telemetry\TelemetryService.cs" />
7577
<Compile Include="ValidationConfiguration.cs" />
7678
<Compile Include="ValidationConfigurationItem.cs" />
7779
<Compile Include="ValidationFailureBehavior.cs" />
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 NuGetGallery;
6+
7+
namespace NuGet.Services.Validation.Orchestrator.Telemetry
8+
{
9+
/// <summary>
10+
/// The interface used for emitting telemetry from the validation orchestrator.
11+
/// </summary>
12+
public interface ITelemetryService
13+
{
14+
/// <summary>
15+
/// The duration from when the package was created to when the first validation set was created. This metric
16+
/// is not emitted for revalidation requests.
17+
/// </summary>
18+
void TrackDurationToValidationSetCreation(TimeSpan duration);
19+
20+
/// <summary>
21+
/// A counter metric emitted when a package changes package status. This metric is not emitted if package status
22+
/// does not change. This metric is emitted for revalidation if the terminal state changes.
23+
/// </summary>
24+
/// <param name="fromStatus">The status that the package moved from.</param>
25+
/// <param name="toStatus">The status that the package moved tp.</param>
26+
void TrackPackageStatusChange(PackageStatus fromStatus, PackageStatus toStatus);
27+
28+
/// <summary>
29+
/// The total duration of all validators. This is the time that the validation set is first created until all of
30+
/// the validators have completed. This metric is also emitted for revalidations.
31+
/// </summary>
32+
/// <param name="duration">The duration.</param>
33+
/// <param name="isSuccess">Whether or not all of the validations succeeded.</param>
34+
void TrackTotalValidationDuration(TimeSpan duration, bool isSuccess);
35+
36+
/// <summary>
37+
/// A counter metric emitted when a validator fails due to the <see cref="ValidationConfigurationItem.FailAfter"/>
38+
/// configuration.
39+
/// </summary>
40+
/// <param name="validatorType">The validator type (name).</param>
41+
void TrackValidatorTimeout(string validatorType);
42+
43+
/// <summary>
44+
/// The total duration of a single validator. This is the time from when the validation is first started until
45+
/// when the validation either completes or times out.
46+
/// </summary>
47+
/// <param name="duration">The duration.</param>
48+
/// <param name="validatorType">The validator type (name).</param>
49+
/// <param name="isSuccess">Whether or not the validation succeeded.</param>
50+
void TrackValidatorDuration(TimeSpan duration, string validatorType, bool isSuccess);
51+
52+
/// <summary>
53+
/// A counter metric emitted when a validator is started.
54+
/// </summary>
55+
/// <param name="validatorType">The validator type (name).</param>
56+
void TrackValidatorStarted(string validatorType);
57+
58+
/// <summary>
59+
/// A counter metric emmitted when a validator reaches a terminal state and potentially persists validation
60+
/// issues. A count of zero is emitted if the validator does not produce any issues. This metric is not emitted
61+
/// if the validation is still at a non-terminal state.
62+
/// </summary>
63+
/// <param name="count">The number of issues.</param>
64+
/// <param name="validatorType">The validator type (name) that returned the issue list.</param>
65+
/// <param name="isSuccess">Whether or not the validation succeeded.</param>
66+
void TrackValidationIssueCount(int count, string validatorType, bool isSuccess);
67+
68+
/// <summary>
69+
/// A counter metric emitted when a validation issue is created.
70+
/// </summary>
71+
/// <param name="validatorType">The validator type (name) the produced the issue.</param>
72+
/// <param name="code">The issue code.</param>
73+
void TrackValidationIssue(string validatorType, ValidationIssueCode code);
74+
75+
/// <summary>
76+
/// A counter metric emitted when a client-mastered validation issue is emitted.
77+
/// </summary>
78+
/// <param name="validatorType">The validator type (name) the produced the issue.</param>
79+
/// <param name="clientCode">The client code.</param>
80+
void TrackClientValidationIssue(string validatorType, string clientCode);
81+
}
82+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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 Microsoft.ApplicationInsights;
7+
using NuGetGallery;
8+
9+
namespace NuGet.Services.Validation.Orchestrator.Telemetry
10+
{
11+
public class TelemetryService : ITelemetryService
12+
{
13+
private const string Prefix = "Orchestrator.";
14+
15+
private const string DurationToValidationSetCreationSeconds = Prefix + "DurationToValidationSetCreationSeconds";
16+
private const string PackageStatusChange = Prefix + "PackageStatusChange";
17+
private const string TotalValidationDurationSeconds = Prefix + "TotalValidationDurationSeconds";
18+
private const string ValidationIssue = Prefix + "ValidationIssue";
19+
private const string ValidationIssueCount = Prefix + "ValidationIssueCount";
20+
private const string ValidatorTimeout = Prefix + "ValidatorTimeout";
21+
private const string ValidatorDurationSeconds = Prefix + "ValidatorDurationSeconds";
22+
private const string ValidatorStarted = Prefix + "ValidatorStarted";
23+
private const string ClientValidationIssue = Prefix + "ClientValidationIssue";
24+
25+
private const string FromStatus = "FromStatus";
26+
private const string ToStatus = "ToStatus";
27+
private const string IsSuccess = "IsSuccess";
28+
private const string ValidatorType = "ValidatorType";
29+
private const string IssueCode = "IssueCode";
30+
private const string ClientCode = "ClientCode";
31+
32+
private readonly TelemetryClient _telemetryClient;
33+
34+
public TelemetryService(TelemetryClient telemetryClient)
35+
{
36+
_telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient));
37+
}
38+
39+
public void TrackDurationToValidationSetCreation(TimeSpan duration)
40+
{
41+
_telemetryClient.TrackMetric(
42+
DurationToValidationSetCreationSeconds,
43+
duration.TotalSeconds);
44+
}
45+
46+
public void TrackPackageStatusChange(PackageStatus fromStatus, PackageStatus toStatus)
47+
{
48+
_telemetryClient.TrackMetric(
49+
PackageStatusChange,
50+
1,
51+
new Dictionary<string, string>
52+
{
53+
{ FromStatus, fromStatus.ToString() },
54+
{ ToStatus, toStatus.ToString() },
55+
});
56+
}
57+
58+
public void TrackTotalValidationDuration(TimeSpan duration, bool isSuccess)
59+
{
60+
_telemetryClient.TrackMetric(
61+
TotalValidationDurationSeconds,
62+
duration.TotalSeconds,
63+
new Dictionary<string, string>
64+
{
65+
{ IsSuccess, isSuccess.ToString() },
66+
});
67+
}
68+
69+
public void TrackValidationIssue(string validatorType, ValidationIssueCode code)
70+
{
71+
_telemetryClient.TrackMetric(
72+
ValidationIssue,
73+
1,
74+
new Dictionary<string, string>
75+
{
76+
{ ValidatorType, validatorType },
77+
{ IssueCode, code.ToString() },
78+
});
79+
}
80+
81+
public void TrackValidationIssueCount(int count, string validatorType, bool isSuccess)
82+
{
83+
_telemetryClient.TrackMetric(
84+
ValidationIssueCount,
85+
count,
86+
new Dictionary<string, string>
87+
{
88+
{ ValidatorType, validatorType },
89+
{ IsSuccess, isSuccess.ToString() },
90+
});
91+
}
92+
93+
public void TrackValidatorTimeout(string validatorType)
94+
{
95+
_telemetryClient.TrackMetric(
96+
ValidatorTimeout,
97+
1,
98+
new Dictionary<string, string>
99+
{
100+
{ ValidatorType, validatorType },
101+
});
102+
}
103+
104+
public void TrackValidatorDuration(TimeSpan duration, string validatorType, bool isSuccess)
105+
{
106+
_telemetryClient.TrackMetric(
107+
ValidatorDurationSeconds,
108+
duration.TotalSeconds,
109+
new Dictionary<string, string>
110+
{
111+
{ ValidatorType, validatorType },
112+
{ IsSuccess, isSuccess.ToString() },
113+
});
114+
}
115+
116+
public void TrackValidatorStarted(string validatorType)
117+
{
118+
_telemetryClient.TrackMetric(
119+
ValidatorStarted,
120+
1,
121+
new Dictionary<string, string>
122+
{
123+
{ ValidatorType, validatorType },
124+
});
125+
}
126+
127+
public void TrackClientValidationIssue(string validatorType, string clientCode)
128+
{
129+
_telemetryClient.TrackMetric(
130+
ClientValidationIssue,
131+
1,
132+
new Dictionary<string, string>
133+
{
134+
{ ValidatorType, validatorType },
135+
{ ClientCode, clientCode },
136+
});
137+
}
138+
}
139+
}

src/NuGet.Services.Validation.Orchestrator/ValidationConfiguration.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ public class ValidationConfiguration
2525
/// Time to wait between checking the state of a certain validation.
2626
/// </summary>
2727
public TimeSpan ValidationMessageRecheckPeriod { get; set; }
28+
29+
/// <summary>
30+
/// The duplication detection window used for new validation requests.
31+
/// Validation requests will be ignored if there exists another validation
32+
/// request for the same package id and version that was created within
33+
/// this window.
34+
/// </summary>
35+
public TimeSpan NewValidationRequestDeduplicationWindow { get; set; }
2836
}
2937
}

src/NuGet.Services.Validation.Orchestrator/ValidationFailureBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace NuGet.Services.Validation.Orchestrator
55
{
66
/// <summary>
7-
/// Options for orchestrator for how to handle valiation failure
7+
/// Options for orchestrator for how to handle validation failure
88
/// </summary>
99
public enum ValidationFailureBehavior
1010
{

src/NuGet.Services.Validation.Orchestrator/ValidationMessageHandler.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ public async Task<bool> HandleAsync(PackageValidationMessageData message)
4646

4747
using (_logger.BeginScope("Handling message for {PackageId} {PackageVersion} validation set {ValidationSetId}", message.PackageId, message.PackageVersion, message.ValidationTrackingId))
4848
{
49-
var validationSet = await _validationSetProvider.GetOrCreateValidationSetAsync(message.ValidationTrackingId, package);
49+
var validationSet = await _validationSetProvider.TryGetOrCreateValidationSetAsync(message.ValidationTrackingId, package);
50+
51+
if (validationSet == null)
52+
{
53+
_logger.LogInformation("The validation request for {PackageId} {PackageVersion} validation set {ValidationSetId} is a duplicate. Discarding.",
54+
message.PackageId,
55+
message.PackageVersion,
56+
message.ValidationTrackingId);
57+
return true;
58+
}
5059

5160
await _validationSetProcessor.ProcessValidationsAsync(validationSet, package);
5261
await _validationOutcomeProcessor.ProcessValidationOutcomeAsync(validationSet, package);

0 commit comments

Comments
 (0)