private async Task SetValidationStatusAsync( PackageValidation packageValidation, INuGetValidationResponse validationResponse, DateTime now) { if (validationResponse.Status != ValidationStatus.Incomplete) { AddValidationIssues(packageValidation, validationResponse.Issues); } if (validationResponse.Status == ValidationStatus.Succeeded && validationResponse.NupkgUrl != null) { if (!_validatorProvider.IsNuGetProcessor(packageValidation.Type)) { throw new InvalidOperationException( $"The validator '{packageValidation.Type}' is not a processor but returned a .nupkg URL as " + $"part of the validation step response."); } await _packageFileService.CopyPackageUrlForValidationSetAsync( packageValidation.PackageValidationSet, validationResponse.NupkgUrl); } packageValidation.ValidationStatus = validationResponse.Status; packageValidation.ValidationStatusTimestamp = now; await _validationContext.SaveChangesAsync(); TrackValidationStatus(packageValidation); }
private void CheckForCyclesAndParallelProcessors() { var processorNames = _configuration .Validations .Select(x => x.Name) .Where(x => _validatorProvider.IsNuGetProcessor(x)) .ToList(); TopologicalSort.Validate(_configuration.Validations, processorNames); }
public async Task <PackageValidationSet> TryGetOrCreateValidationSetAsync(ProcessValidationSetData message, IValidatingEntity <T> validatingEntity) { var validationSet = await _validationStorageService.GetValidationSetAsync(message.ValidationTrackingId); if (validationSet == null) { var shouldSkip = await _validationStorageService.OtherRecentValidationSetForPackageExists( validatingEntity, _validationConfiguration.NewValidationRequestDeduplicationWindow, message.ValidationTrackingId); if (shouldSkip) { return(null); } validationSet = InitializeValidationSet(message, validatingEntity); if (validatingEntity.Status == PackageStatus.Available) { var packageETag = await _packageFileService.CopyPackageFileForValidationSetAsync(validationSet); // This indicates that the package in the package container is expected to not change. validationSet.PackageETag = packageETag; } else { await _packageFileService.CopyValidationPackageForValidationSetAsync(validationSet); // A symbols package for the same id and version can be re-submitted. // When this happens a new validation is submitted. After validation the new symbols package will overwrite the old symbols package. // Because of this when a new validation for a symbols package is received it can already exist a symbols package in the public symbols container. if (validatingEntity.ValidatingType == ValidatingType.SymbolPackage) { validationSet.PackageETag = await _packageFileService.GetPublicPackageBlobETagOrNullAsync(validationSet); } else { // This indicates that the package in the packages container is expected to not exist (i.e. it has // has no etag at all). validationSet.PackageETag = null; } } // If there are any processors in the validation set, back up the original. We back up from the // validation set copy to avoid concurrency issues. if (validationSet.PackageValidations.Any(x => _validatorProvider.IsNuGetProcessor(x.Type))) { await _packageFileService.BackupPackageFileFromValidationSetPackageAsync(validationSet, _sasDefinitionConfiguration.ValidationSetProviderSasDefinition); } validationSet = await PersistValidationSetAsync(validationSet, validatingEntity); } else { var sameKey = validatingEntity.Key == validationSet.PackageKey; if (!sameKey) { throw new InvalidOperationException($"Validation set key ({validationSet.PackageKey}) " + $"does not match expected {validatingEntity.EntityRecord.GetType().Name} key ({validatingEntity.Key})."); } } return(validationSet); }