/// <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;
        }
예제 #4
0
        public async Task <IEnumerable <FhirTransactionRequestEntry> > BuildAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context?.ChangeFeedEntry, nameof(context.ChangeFeedEntry));
            EnsureArg.IsNotNull(context.Request, nameof(context.Request));

            IResourceId     patientId       = context.Request.Patient.ResourceId;
            IResourceId     imagingStudyId  = context.Request.ImagingStudy.ResourceId;
            ChangeFeedEntry changeFeedEntry = context.ChangeFeedEntry;

            Identifier identifier = IdentifierUtility.CreateIdentifier(changeFeedEntry.StudyInstanceUid);

            IReadOnlyCollection <Observation> observations = _observationParser.Parse(changeFeedEntry.Metadata, patientId.ToResourceReference(), imagingStudyId.ToResourceReference(), identifier);

            if (observations.Count == 0)
            {
                return(Enumerable.Empty <FhirTransactionRequestEntry>());
            }

            Identifier imagingStudyIdentifier = imagingStudyId.ToResourceReference().Identifier;
            IEnumerable <Observation> existingDoseSummariesAsync = imagingStudyIdentifier != null
                ? await _fhirService
                                                                   .RetrieveObservationsAsync(
                imagingStudyId.ToResourceReference().Identifier,
                cancellationToken)
                : new List <Observation>();

            // TODO: Figure out a way to match existing observations with newly created ones.

            List <FhirTransactionRequestEntry> fhirRequests = new List <FhirTransactionRequestEntry>();

            foreach (var observation in observations)
            {
                fhirRequests.Add(new FhirTransactionRequestEntry(
                                     FhirTransactionRequestMode.Create,
                                     new Bundle.RequestComponent()
                {
                    Method = Bundle.HTTPVerb.POST,
                    Url    = ResourceType.Observation.GetLiteral()
                },
                                     new ClientResourceId(),
                                     observation));
            }

            return(fhirRequests);
        }
예제 #5
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);
        }