Пример #1
0
        public static void ValidateRequestEntryMinimumRequirementForWithChange(
            FhirTransactionRequestMode expectedRequestMode,
            string path,
            Bundle.HTTPVerb?expectedMethod,
            FhirTransactionRequestEntry actualEntry)
        {
            // For request entry with no change, use the method below.
            Assert.NotEqual(FhirTransactionRequestMode.None, expectedRequestMode);

            Assert.NotNull(actualEntry);
            Assert.Equal(expectedRequestMode, actualEntry.RequestMode);

            if (expectedRequestMode == FhirTransactionRequestMode.Create)
            {
                // If the request mode is create, then it should be client generated resource id.
                Assert.IsType <ClientResourceId>(actualEntry.ResourceId);
            }
            else if (expectedRequestMode == FhirTransactionRequestMode.Update)
            {
                // Otherwise, it should be server generated resource id.
                ServerResourceId serverResourceId = Assert.IsType <ServerResourceId>(actualEntry.ResourceId);

                Assert.Equal(path, serverResourceId.ToString());
            }

            Assert.NotNull(actualEntry.Request);
            Assert.Equal(expectedMethod, actualEntry.Request.Method);
            Assert.Equal(path, actualEntry.Request.Url);

            if (expectedMethod != Bundle.HTTPVerb.DELETE)
            {
                Assert.NotNull(actualEntry.Resource);
            }
        }
        /// <inheritdoc/>
        public async Task PrepareRequestAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context, nameof(context));

            DicomDataset dataset = context.ChangeFeedEntry.Metadata;

            if (dataset == null)
            {
                return;
            }

            if (!dataset.TryGetSingleValue(DicomTag.PatientID, out string patientId))
            {
                throw new MissingRequiredDicomTagException(nameof(DicomTag.PatientID));
            }

            var patientIdentifier = new Identifier(string.Empty, patientId);

            FhirTransactionRequestMode requestMode = FhirTransactionRequestMode.None;

            Patient existingPatient = await _fhirService.RetrievePatientAsync(patientIdentifier, cancellationToken);

            Patient patient = (Patient)existingPatient?.DeepCopy();

            if (existingPatient == null)
            {
                patient = new Patient();

                patient.Identifier.Add(patientIdentifier);

                requestMode = FhirTransactionRequestMode.Create;
            }

            _patientSynchronizer.Synchronize(dataset, patient);

            if (requestMode == FhirTransactionRequestMode.None &&
                !existingPatient.IsExactly(patient))
            {
                requestMode = FhirTransactionRequestMode.Update;
            }

            Bundle.RequestComponent request = requestMode switch
            {
                FhirTransactionRequestMode.Create => GenerateCreateRequest(patientIdentifier),
                FhirTransactionRequestMode.Update => GenerateUpdateRequest(patient),
                _ => null
            };

            IResourceId resourceId = requestMode switch
            {
                FhirTransactionRequestMode.Create => new ClientResourceId(),
                _ => existingPatient.ToServerResourceId(),
            };

            context.Request.Patient = new FhirTransactionRequestEntry(
                requestMode,
                request,
                resourceId,
                patient);
        }
        /// <inheritdoc/>
        public async Task <FhirTransactionRequestEntry> BuildAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context, nameof(context));
            EnsureArg.IsNotNull(context.ChangeFeedEntry, nameof(context.ChangeFeedEntry));
            EnsureArg.IsNotNull(context.Request, nameof(context.Request));

            IResourceId patientId = context.Request.Patient.ResourceId;

            ChangeFeedEntry changeFeedEntry = context.ChangeFeedEntry;

            Identifier imagingStudyIdentifier = ImagingStudyIdentifierUtility.CreateIdentifier(changeFeedEntry.StudyInstanceUid);

            ImagingStudy existingImagingStudy = await _fhirService.RetrieveImagingStudyAsync(imagingStudyIdentifier, cancellationToken);

            ImagingStudy imagingStudy = (ImagingStudy)existingImagingStudy?.DeepCopy();

            FhirTransactionRequestMode requestMode = FhirTransactionRequestMode.None;

            if (existingImagingStudy == null)
            {
                imagingStudy = new ImagingStudy()
                {
                    Status  = ImagingStudy.ImagingStudyStatus.Available,
                    Subject = patientId.ToResourceReference(),
                };

                imagingStudy.Identifier.Add(imagingStudyIdentifier);
                requestMode = FhirTransactionRequestMode.Create;
            }

            SynchronizeImagingStudyProperties(context, imagingStudy);

            if (requestMode != FhirTransactionRequestMode.Create &&
                !existingImagingStudy.IsExactly(imagingStudy))
            {
                requestMode = FhirTransactionRequestMode.Update;
            }

            Bundle.RequestComponent request = requestMode switch
            {
                FhirTransactionRequestMode.Create => ImagingStudyPipelineHelper.GenerateCreateRequest(imagingStudyIdentifier),
                FhirTransactionRequestMode.Update => ImagingStudyPipelineHelper.GenerateUpdateRequest(imagingStudy),
                _ => null,
            };

            IResourceId resourceId = requestMode switch
            {
                FhirTransactionRequestMode.Create => new ClientResourceId(),
                _ => existingImagingStudy.ToServerResourceId(),
            };

            return(new FhirTransactionRequestEntry(
                       requestMode,
                       request,
                       resourceId,
                       imagingStudy));
        }
        public FhirTransactionRequestEntry(
            FhirTransactionRequestMode requestMode,
            Bundle.RequestComponent request,
            IResourceId resourceId,
            Resource resource)
        {
            EnsureArg.EnumIsDefined(requestMode, nameof(requestMode));

            RequestMode = requestMode;
            Request     = request;
            ResourceId  = resourceId;
            Resource    = resource;
        }
Пример #5
0
        public async Task GivenAResourceToProcess_WhenProcessed_ThenTransactionShouldBeExecuted(FhirTransactionRequestMode requestMode)
        {
            // Setup the pipeline step to simulate creating/updating patient.
            var patientRequest = new FhirTransactionRequestEntry(
                requestMode,
                new Bundle.RequestComponent(),
                new ClientResourceId(),
                new Patient());

            var pipelineStep = new MockFhirTransactionPipelineStep()
            {
                OnPrepareRequestAsyncCalled = (context, cancellationToken) =>
                {
                    context.Request.Patient = patientRequest;

                    Assert.Equal(DefaultCancellationToken, cancellationToken);
                },
            };

            _fhirTransactionPipelineSteps.Add(pipelineStep);

            // Setup the transaction executor to return response.
            var responseBundle = new Bundle();

            var responseEntry = new Bundle.EntryComponent()
            {
                Response = new Bundle.ResponseComponent(),
                Resource = new Patient(),
            };

            responseBundle.Entry.Add(responseEntry);

            _fhirTransactionExecutor.ExecuteTransactionAsync(
                Arg.Any <Bundle>(),
                DefaultCancellationToken)
            .Returns(call =>
            {
                // Make sure the request bundle is correct.
                Bundle requestBundle = call.ArgAt <Bundle>(0);

                Assert.NotNull(requestBundle);
                Assert.Equal(Bundle.BundleType.Transaction, requestBundle.Type);

                Assert.Collection(
                    requestBundle.Entry,
                    entry =>
                {
                    Assert.Equal(patientRequest.ResourceId.ToString(), entry.FullUrl);
                    Assert.Equal(patientRequest.Request, entry.Request);
                    Assert.Equal(patientRequest.Resource, entry.Resource);
                });

                return(responseBundle);
            });

            // Process
            await _fhirTransactionPipeline.ProcessAsync(ChangeFeedGenerator.Generate(), DefaultCancellationToken);

            // The response should have been processed.
            Assert.NotNull(_capturedFhirTransactionContext);

            FhirTransactionResponseEntry patientResponse = _capturedFhirTransactionContext.Response.Patient;

            Assert.NotNull(patientResponse);
            Assert.Equal(responseEntry.Response, patientResponse.Response);
            Assert.Equal(responseEntry.Resource, patientResponse.Resource);
        }
Пример #6
0
        public async Task PrepareRequestAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context, nameof(context));

            string queryParameter = $"name={FhirTransactionConstants.EndpointName}&connection-type={FhirTransactionConstants.EndpointConnectionTypeSystem}|{FhirTransactionConstants.EndpointConnectionTypeCode}";

            Endpoint endpoint = await _fhirService.RetrieveEndpointAsync(queryParameter, cancellationToken);

            FhirTransactionRequestMode requestMode = FhirTransactionRequestMode.None;

            if (endpoint == null)
            {
                endpoint = new Endpoint()
                {
                    Name           = FhirTransactionConstants.EndpointName,
                    Status         = Endpoint.EndpointStatus.Active,
                    ConnectionType = new Coding()
                    {
                        System = FhirTransactionConstants.EndpointConnectionTypeSystem,
                        Code   = FhirTransactionConstants.EndpointConnectionTypeCode,
                    },
                    Address     = _dicomWebEndpoint,
                    PayloadType = new List <CodeableConcept>
                    {
                        new CodeableConcept(string.Empty, string.Empty, FhirTransactionConstants.EndpointPayloadTypeText),
                    },
                    PayloadMimeType = new string[]
                    {
                        FhirTransactionConstants.DicomMimeType,
                    },
                };

                requestMode = FhirTransactionRequestMode.Create;
            }
            else
            {
                // Make sure the address matches.
                if (!string.Equals(endpoint.Address, _dicomWebEndpoint, StringComparison.Ordinal))
                {
                    // We have found an endpoint with matching name and connection-type but the address does not match.
                    throw new FhirResourceValidationException(DicomCastCoreResource.MismatchEndpointAddress);
                }
            }

            Bundle.RequestComponent request = requestMode switch
            {
                FhirTransactionRequestMode.Create => new Bundle.RequestComponent()
                {
                    Method      = Bundle.HTTPVerb.POST,
                    IfNoneExist = queryParameter,
                    Url         = ResourceType.Endpoint.GetLiteral(),
                },
                _ => null,
            };

            IResourceId resourceId = requestMode switch
            {
                FhirTransactionRequestMode.Create => new ClientResourceId(),
                _ => endpoint.ToServerResourceId(),
            };

            context.Request.Endpoint = new FhirTransactionRequestEntry(
                requestMode,
                request,
                resourceId,
                endpoint);
        }