public async Task GivenAMatchingJob_WhenGettingByHash_ThenTheMatchingJobShouldBeReturned() { var jobRecord = await InsertNewExportJobRecordAsync(); ExportJobOutcome outcome = await _operationDataStore.GetExportJobByHashAsync(jobRecord.Hash, CancellationToken.None); Assert.Equal(jobRecord.Id, outcome?.JobRecord?.Id); }
public async Task <CreateExportResponse> Handle(CreateExportRequest request, CancellationToken cancellationToken) { EnsureArg.IsNotNull(request, nameof(request)); if (await _authorizationService.CheckAccess(DataActions.Export) != DataActions.Export) { throw new UnauthorizedFhirActionException(); } IReadOnlyCollection <KeyValuePair <string, string> > requestorClaims = _claimsExtractor.Extract()? .OrderBy(claim => claim.Key, StringComparer.Ordinal).ToList(); // Compute the hash of the job. var hashObject = new { request.RequestUri, RequestorClaims = requestorClaims, }; string hash = JsonConvert.SerializeObject(hashObject).ComputeHash(); // Check to see if a matching job exists or not. If a matching job exists, we will return that instead. // Otherwise, we will create a new export job. This will be a best effort since the likelihood of this happen should be small. ExportJobOutcome outcome = await _fhirOperationDataStore.GetExportJobByHashAsync(hash, cancellationToken); if (outcome == null) { var jobRecord = new ExportJobRecord(request.RequestUri, request.ResourceType, hash, requestorClaims, request.Since); outcome = await _fhirOperationDataStore.CreateExportJobAsync(jobRecord, cancellationToken); } return(new CreateExportResponse(outcome.JobRecord.Id)); }
public async Task <CreateExportResponse> Handle(CreateExportRequest request, CancellationToken cancellationToken) { EnsureArg.IsNotNull(request, nameof(request)); if (await _authorizationService.CheckAccess(DataActions.Export, cancellationToken) != DataActions.Export) { throw new UnauthorizedFhirActionException(); } IReadOnlyCollection <KeyValuePair <string, string> > requestorClaims = _claimsExtractor.Extract()? .OrderBy(claim => claim.Key, StringComparer.Ordinal).ToList(); // Compute the hash of the job. var hashObject = new { request.RequestUri, RequestorClaims = requestorClaims, }; string hash = JsonConvert.SerializeObject(hashObject).ComputeHash(); string storageAccountConnectionHash = string.IsNullOrEmpty(_exportJobConfiguration.StorageAccountConnection) ? string.Empty : StringExtensions.ComputeHash(_exportJobConfiguration.StorageAccountConnection); // Check to see if a matching job exists or not. If a matching job exists, we will return that instead. // Otherwise, we will create a new export job. This will be a best effort since the likelihood of this happen should be small. ExportJobOutcome outcome = await _fhirOperationDataStore.GetExportJobByHashAsync(hash, cancellationToken); var filters = ParseFilter(request.Filters); ExportJobFormatConfiguration formatConfiguration = ParseFormat(request.FormatName, request.ContainerName != null); if (outcome == null) { var jobRecord = new ExportJobRecord( request.RequestUri, request.RequestType, formatConfiguration.Format, request.ResourceType, filters, hash, _exportJobConfiguration.RollingFileSizeInMB, requestorClaims, request.Since, request.GroupId, storageAccountConnectionHash, _exportJobConfiguration.StorageAccountUri, request.AnonymizationConfigurationLocation, request.AnonymizationConfigurationFileETag, _exportJobConfiguration.MaximumNumberOfResourcesPerQuery, _exportJobConfiguration.NumberOfPagesPerCommit, request.ContainerName); outcome = await _fhirOperationDataStore.CreateExportJobAsync(jobRecord, cancellationToken); } return(new CreateExportResponse(outcome.JobRecord.Id)); }
public async Task <CreateExportResponse> Handle(CreateExportRequest request, CancellationToken cancellationToken) { EnsureArg.IsNotNull(request, nameof(request)); IReadOnlyCollection <KeyValuePair <string, string> > requestorClaims = _claimsExtractor.Extract()? .OrderBy(claim => claim.Key, StringComparer.Ordinal).ToList(); // Compute the hash of the job. var hashObject = new { request.RequestUri, RequestorClaims = requestorClaims, request.DestinationInfo, }; string hash = JsonConvert.SerializeObject(hashObject).ComputeHash(); // Check to see if a matching job exists or not. If a matching job exists, we will return that instead. // Otherwise, we will create a new export job. This will be a best effort since the likelihood of this happen should be small. ExportJobOutcome outcome = await _fhirOperationDataStore.GetExportJobByHashAsync(hash, cancellationToken); if (outcome == null) { // Remove the connection settings from the request URI before we store it in the secret store. NameValueCollection queryParameters = HttpUtility.ParseQueryString(request.RequestUri.Query); queryParameters.Remove(KnownQueryParameterNames.DestinationType); queryParameters.Remove(KnownQueryParameterNames.DestinationConnectionSettings); var uriBuilder = new UriBuilder(request.RequestUri); uriBuilder.Query = queryParameters.ToString(); var jobRecord = new ExportJobRecord(uriBuilder.Uri, request.ResourceType, hash, requestorClaims); // Store the destination secret. try { await _secretStore.SetSecretAsync(jobRecord.SecretName, request.DestinationInfo.ToJson(), cancellationToken); } catch (SecretStoreException sse) { throw new OperationFailedException(string.Format(Resources.OperationFailed, OperationsConstants.Export, sse.Message), sse.ResponseStatusCode); } outcome = await _fhirOperationDataStore.CreateExportJobAsync(jobRecord, cancellationToken); } return(new CreateExportResponse(outcome.JobRecord.Id)); }
public async Task <CreateExportResponse> Handle(CreateExportRequest request, CancellationToken cancellationToken) { EnsureArg.IsNotNull(request, nameof(request)); if (await _authorizationService.CheckAccess(DataActions.Export) != DataActions.Export) { throw new UnauthorizedFhirActionException(); } IReadOnlyCollection <KeyValuePair <string, string> > requestorClaims = _claimsExtractor.Extract()? .OrderBy(claim => claim.Key, StringComparer.Ordinal).ToList(); // Compute the hash of the job. var hashObject = new { request.RequestUri, RequestorClaims = requestorClaims, }; string hash = JsonConvert.SerializeObject(hashObject).ComputeHash(); string storageAccountConnectionHash = string.IsNullOrEmpty(_exportJobConfiguration.StorageAccountConnection) ? string.Empty : Microsoft.Health.Core.Extensions.StringExtensions.ComputeHash(_exportJobConfiguration.StorageAccountConnection); // Check to see if a matching job exists or not. If a matching job exists, we will return that instead. // Otherwise, we will create a new export job. This will be a best effort since the likelihood of this happen should be small. ExportJobOutcome outcome = await _fhirOperationDataStore.GetExportJobByHashAsync(hash, cancellationToken); ExportJobFormatConfiguration formatConfiguration = null; if (request.FormatName != null) { formatConfiguration = _exportJobConfiguration.Formats?.FirstOrDefault( (ExportJobFormatConfiguration formatConfig) => formatConfig.Name.Equals(request.FormatName, StringComparison.OrdinalIgnoreCase)); if (formatConfiguration == null) { throw new BadRequestException(Resources.ExportFormatNotFound); } } formatConfiguration ??= _exportJobConfiguration.Formats?.FirstOrDefault( (ExportJobFormatConfiguration formatConfig) => formatConfig.Default); formatConfiguration ??= new ExportJobFormatConfiguration() { Format = request.ContainerName == null ? ExportFormatTags.ResourceName : $"{ExportFormatTags.Timestamp}-{ExportFormatTags.Id}/{ExportFormatTags.ResourceName}", }; if (outcome == null) { var jobRecord = new ExportJobRecord( request.RequestUri, request.RequestType, formatConfiguration.Format, request.ResourceType, hash, requestorClaims, request.Since, request.GroupId, storageAccountConnectionHash, _exportJobConfiguration.StorageAccountUri, request.AnonymizationConfigurationLocation, request.AnonymizationConfigurationFileETag, _exportJobConfiguration.MaximumNumberOfResourcesPerQuery, _exportJobConfiguration.NumberOfPagesPerCommit, request.ContainerName); outcome = await _fhirOperationDataStore.CreateExportJobAsync(jobRecord, cancellationToken); } return(new CreateExportResponse(outcome.JobRecord.Id)); }