1313namespace NuGet . Services . Validation . Orchestrator
1414{
1515 /// <summary>
16- /// Provides an access layer to the validation information stored in DB
16+ /// Provides an access layer to the validation information stored in DB and blob storage.
1717 /// </summary>
1818 public class ValidationStorageService : IValidationStorageService
1919 {
2020 private readonly IValidationEntitiesContext _validationContext ;
21+ private readonly IValidationPackageFileService _packageFileService ;
22+ private readonly IValidatorProvider _validatorProvider ;
2123 private readonly ITelemetryService _telemetryService ;
2224 private readonly ILogger < ValidationStorageService > _logger ;
2325
2426 public ValidationStorageService (
2527 IValidationEntitiesContext validationContext ,
28+ IValidationPackageFileService packageFileService ,
29+ IValidatorProvider validatorProvider ,
2630 ITelemetryService telemetryService ,
2731 ILogger < ValidationStorageService > logger )
2832 {
2933 _validationContext = validationContext ?? throw new ArgumentNullException ( nameof ( validationContext ) ) ;
34+ _packageFileService = packageFileService ?? throw new ArgumentNullException ( nameof ( packageFileService ) ) ;
35+ _validatorProvider = validatorProvider ?? throw new ArgumentNullException ( nameof ( validatorProvider ) ) ;
3036 _telemetryService = telemetryService ?? throw new ArgumentNullException ( nameof ( telemetryService ) ) ;
3137 _logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
3238 }
@@ -58,12 +64,14 @@ public async Task<PackageValidationSet> CreateValidationSetAsync(PackageValidati
5864 public async Task MarkValidationStartedAsync ( PackageValidation packageValidation , IValidationResult validationResult )
5965 {
6066 packageValidation = packageValidation ?? throw new ArgumentNullException ( nameof ( packageValidation ) ) ;
67+
6168 _logger . LogInformation ( "Marking validation {ValidationName} {ValidationId} {PackageId} {PackageVersion} as started with status {ValidationStatus}" ,
6269 packageValidation . Type ,
6370 packageValidation . PackageValidationSet . ValidationTrackingId ,
6471 packageValidation . PackageValidationSet . PackageId ,
6572 packageValidation . PackageValidationSet . PackageNormalizedVersion ,
6673 validationResult . Status ) ;
74+
6775 if ( validationResult . Status == ValidationStatus . NotStarted )
6876 {
6977 throw new ArgumentOutOfRangeException (
@@ -74,20 +82,10 @@ public async Task MarkValidationStartedAsync(PackageValidation packageValidation
7482 $ "with status { ValidationStatus . NotStarted } ") ;
7583 }
7684
77- packageValidation . ValidationStatus = validationResult . Status ;
78-
79- // If the validation has completed, save the validation issues to the package's validation.
80- if ( validationResult . Status != ValidationStatus . Incomplete )
81- {
82- AddValidationIssues ( packageValidation , validationResult . Issues ) ;
83- }
84-
8585 var now = DateTime . UtcNow ;
86- packageValidation . ValidationStatusTimestamp = now ;
8786 packageValidation . Started = now ;
88- await _validationContext . SaveChangesAsync ( ) ;
8987
90- TrackValidationStatus ( packageValidation ) ;
88+ await SetValidationStatusAsync ( packageValidation , validationResult , now ) ;
9189 }
9290
9391 public Task UpdateValidationSetAsync ( PackageValidationSet packageValidationSet )
@@ -107,24 +105,56 @@ public Task UpdateValidationSetAsync(PackageValidationSet packageValidationSet)
107105 public async Task UpdateValidationStatusAsync ( PackageValidation packageValidation , IValidationResult validationResult )
108106 {
109107 packageValidation = packageValidation ?? throw new ArgumentNullException ( nameof ( packageValidation ) ) ;
108+
109+ if ( packageValidation . ValidationStatus == validationResult . Status )
110+ {
111+ _logger . LogInformation ( "Validation {ValidationName} {ValidationId} {PackageId} {PackageVersion} already has status {ValidationStatus}" ,
112+ packageValidation . Type ,
113+ packageValidation . PackageValidationSet . ValidationTrackingId ,
114+ packageValidation . PackageValidationSet . PackageId ,
115+ packageValidation . PackageValidationSet . PackageNormalizedVersion ,
116+ validationResult . Status ) ;
117+
118+ return ;
119+ }
120+
110121 _logger . LogInformation ( "Updating the status of the validation {ValidationName} {ValidationId} {PackageId} {PackageVersion} to {ValidationStatus}" ,
111122 packageValidation . Type ,
112123 packageValidation . PackageValidationSet . ValidationTrackingId ,
113124 packageValidation . PackageValidationSet . PackageId ,
114125 packageValidation . PackageValidationSet . PackageNormalizedVersion ,
115126 validationResult . Status ) ;
116127
117- if ( packageValidation . ValidationStatus == validationResult . Status )
128+ await SetValidationStatusAsync ( packageValidation , validationResult , DateTime . UtcNow ) ;
129+ }
130+
131+ private async Task SetValidationStatusAsync (
132+ PackageValidation packageValidation ,
133+ IValidationResult validationResult ,
134+ DateTime now )
135+ {
136+ if ( validationResult . Status != ValidationStatus . Incomplete )
118137 {
119- return ;
138+ AddValidationIssues ( packageValidation , validationResult . Issues ) ;
120139 }
121140
122- var previousValidationStatus = packageValidation . ValidationStatus ;
141+ if ( validationResult . Status == ValidationStatus . Succeeded
142+ && validationResult . NupkgUrl != null )
143+ {
144+ if ( ! _validatorProvider . IsProcessor ( packageValidation . Type ) )
145+ {
146+ throw new InvalidOperationException (
147+ $ "The validator '{ packageValidation . Type } ' is not a processor but returned a .nupkg URL as " +
148+ $ "part of the validation result.") ;
149+ }
123150
124- AddValidationIssues ( packageValidation , validationResult . Issues ) ;
151+ await _packageFileService . CopyPackageUrlForValidationSetAsync (
152+ packageValidation . PackageValidationSet ,
153+ validationResult . NupkgUrl ) ;
154+ }
125155
126156 packageValidation . ValidationStatus = validationResult . Status ;
127- packageValidation . ValidationStatusTimestamp = DateTime . UtcNow ;
157+ packageValidation . ValidationStatusTimestamp = now ;
128158 await _validationContext . SaveChangesAsync ( ) ;
129159
130160 TrackValidationStatus ( packageValidation ) ;
0 commit comments