Beispiel #1
0
        /// <summary>
        /// Create an operation outcome resource
        /// </summary>
        public static OperationOutcome CreateOutcomeResource(FhirOperationResult result)
        {
            var retVal = new OperationOutcome();

            Uri fhirIssue = new Uri("http://hl7.org/fhir/issue-type");

            // Add issues for each of the details
            foreach (var dtl in result.Details)
            {
                Issue issue = new Issue()
                {
                    Diagnostics = new DataTypes.FhirString(dtl.Message),
                    Severity    = (IssueSeverity)Enum.Parse(typeof(IssueSeverity), dtl.Type.ToString())
                };

                if (!String.IsNullOrEmpty(dtl.Location))
                {
                    issue.Location.Add(new DataTypes.FhirString(dtl.Location));
                }

                // Type
                if (dtl.Exception is TimeoutException)
                {
                    issue.Code = new DataTypes.FhirCoding(fhirIssue, "timeout");
                }
                else if (dtl is FixedValueMisMatchedResultDetail)
                {
                    issue.Code = new DataTypes.FhirCoding(fhirIssue, "value");
                }
                else if (dtl is PersistenceResultDetail)
                {
                    issue.Code = new DataTypes.FhirCoding(fhirIssue, "no-store");
                }
                else
                {
                    issue.Code = new DataTypes.FhirCoding(fhirIssue, "exception");
                }

                retVal.Issue.Add(issue);
            }

            // Add detected issues
            if (result.Issues != null)
            {
                foreach (var iss in result.Issues)
                {
                    retVal.Issue.Add(new Issue()
                    {
                        Diagnostics = new DataTypes.FhirString(iss.Text),
                        Severity    = (IssueSeverity)Enum.Parse(typeof(IssueSeverity), iss.Severity.ToString()),
                        Code        = new DataTypes.FhirCoding(fhirIssue, "business-rule")
                    });
                }
            }

            return(retVal);
        }
Beispiel #2
0
        /// <summary>
        /// Delete a resource
        /// </summary>
        public DomainResourceBase DeleteResource(string resourceType, string id, string mimeType)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result       = null;
            AuditData           audit        = null;
            IAuditorService     auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService;

            try
            {
                // Setup outgoing content/
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NoContent;

                // Create or update?
                var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType);
                if (handler == null)
                {
                    throw new FileNotFoundException(); // endpoint not found!
                }
                result = handler.Delete(id, TransactionMode.Commit);

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new NotSupportedException();
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Delete failed");
                }

                audit = AuditUtil.CreateAuditData(result.Results);

                return(null);
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Not implemented
        /// </summary>
        public Bundle GetHistory(string mimeType)
        {
            this.ThrowIfNotReady();

            var result = new FhirOperationResult()
            {
                Outcome = ResultCode.Rejected,
                Details = new List <IResultDetail>()
                {
                    new ResultDetail(ResultDetailType.Error, "For security reasons system history is not supported", null, null)
                }
            };

            return(this.ErrorHelper(new NotImplementedException(), result, true) as Bundle);
        }
Beispiel #4
0
        /// <summary>
        /// Validate a resource (really an update with debugging / non comit)
        /// </summary>
        public OperationOutcome ValidateResource(string resourceType, string id, DomainResourceBase target)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result = null;

            try
            {
                // Setup outgoing content

                // Create or update?
                var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType);
                if (handler == null)
                {
                    throw new FileNotFoundException(); // endpoint not found!
                }
                result = handler.Update(id, target, TransactionMode.Rollback);
                if (result == null || result.Results.Count == 0) // Create
                {
                    result = handler.Create(target, TransactionMode.Rollback);
                    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created;
                }

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new InvalidDataException("Resource structure is not valid");
                }
                else if (result.Outcome == ResultCode.AcceptedNonConformant)
                {
                    throw new ConstraintException("Resource not conformant");
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Validate failed");
                }

                // Return constraint
                return(MessageUtil.CreateOutcomeResource(result));
            }
            catch (Exception e)
            {
                return(this.ErrorHelper(e, result, false) as OperationOutcome);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Update a patient
        /// </summary>
        public SVC.Messaging.FHIR.FhirOperationResult Update(string id, SVC.Messaging.FHIR.Resources.ResourceBase target, SVC.Core.Services.DataPersistenceMode mode)
        {
            // Create a registration event ... subject
            FhirOperationResult retVal = new FhirOperationResult();

            retVal.Details = new List <IResultDetail>();

            // Get query parameters
            var resourceProcessor = FhirMessageProcessorUtil.GetMessageProcessor(this.ResourceName);

            // Parse the incoming request
            if (target != null)
            {
                target.Id = id;
            }
            var storeContainer = resourceProcessor.ProcessResource(target, retVal.Details);

            if (storeContainer == null)
            {
                retVal.Outcome = ResultCode.AcceptedNonConformant;
            }
            else
            {
                // Now store the container
                try
                {
                    // HACK: Store the container
                    storeContainer = DataUtil.Update(storeContainer, id, mode, retVal.Details);

                    retVal.Outcome = ResultCode.Accepted;
                    retVal.Results = new List <ResourceBase>();
                    retVal.Results.Add(resourceProcessor.ProcessComponent(storeContainer, retVal.Details));
                }
                catch (MissingPrimaryKeyException e)
                {
                    retVal.Details.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
                    retVal.Outcome = ResultCode.TypeNotAvailable;
                    throw e;
                }
                catch (Exception e)
                {
                    retVal.Details.Add(new ResultDetail(ResultDetailType.Error, ApplicationContext.LocalizationService.GetString("DTPE001"), e));
                    retVal.Outcome = ResultCode.Error;
                }
            }
            return(retVal);
        }
Beispiel #6
0
        /// <summary>
        /// Get a resource's history
        /// </summary>
        public Bundle GetResourceInstanceHistory(string resourceType, string id, string mimeType)
        {
            this.ThrowIfNotReady();

            FhirOperationResult readResult = null;

            try
            {
                readResult = this.PerformRead(resourceType, id, String.Empty);
                WebOperationContext.Current.OutgoingResponse.Headers.Remove("Content-Disposition");
                return(MessageUtil.CreateBundle(readResult));
            }
            catch (Exception e)
            {
                return(this.ErrorHelper(e, readResult, true) as Bundle);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Read resource with version
        /// </summary>
        public DomainResourceBase VReadResource(string resourceType, string id, string vid, string mimeType)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result = null;

            try
            {
                // Setup outgoing content
                result = this.PerformRead(resourceType, id, vid);
                return(result.Results[0]);
            }
            catch (Exception e)
            {
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Read a reasource
        /// </summary>
        public DomainResourceBase ReadResource(string resourceType, string id, string mimeType)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result = null;

            try
            {
                // Setup outgoing content
                result = this.PerformRead(resourceType, id, null);
                String baseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.AbsoluteUri;
                WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Location", String.Format("{0}/_history/{1}", baseUri, result.Results[0].VersionId));
                return(result.Results[0]);
            }
            catch (Exception e)
            {
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Create a feed
        /// </summary>
        internal static Bundle CreateBundle(FhirOperationResult result)
        {
            Bundle          retVal      = new Bundle();
            FhirQueryResult queryResult = result as FhirQueryResult;

            int pageNo = queryResult == null || queryResult.Query.Quantity == 0 ? 0 : queryResult.Query.Start / queryResult.Query.Quantity,
                nPages = queryResult == null || queryResult.Query.Quantity == 0 ? 1 : (queryResult.TotalResults / queryResult.Query.Quantity);

            retVal.Type = BundleType.SearchResults;

            retVal.Id = String.Format("urn:uuid:{0}", Guid.NewGuid());

            // Make the Self uri
            String baseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.AbsoluteUri;

            if (baseUri.Contains("?"))
            {
                baseUri = baseUri.Substring(0, baseUri.IndexOf("?") + 1);
            }
            else
            {
                baseUri += "?";
            }

            // Self uri
            if (queryResult != null)
            {
                for (int i = 0; i < queryResult.Query.ActualParameters.Count; i++)
                {
                    foreach (var itm in queryResult.Query.ActualParameters.GetValues(i))
                    {
                        switch (queryResult.Query.ActualParameters.GetKey(i))
                        {
                        case "_stateid":
                        case "_page":
                            break;

                        default:
                            baseUri += string.Format("{0}={1}&", queryResult.Query.ActualParameters.GetKey(i), itm);
                            break;
                        }
                    }
                }

                if (!baseUri.Contains("_stateid=") && queryResult.Query.QueryId != Guid.Empty)
                {
                    baseUri += String.Format("_stateid={0}&", queryResult.Query.QueryId);
                }
            }

            // Format
            string format = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["_format"];

            if (String.IsNullOrEmpty(format))
            {
                format = "xml";
            }
            else if (format == "application/xml+fhir")
            {
                format = "xml";
            }
            else if (format == "application/json+fhir")
            {
                format = "json";
            }

            if (!baseUri.Contains("_format"))
            {
                baseUri += String.Format("_format={0}&", format);
            }

            var localizationService = ApplicationContext.Current.GetService <ILocalizationService>();

            // Self URI
            if (queryResult != null && queryResult.TotalResults > queryResult.Results.Count)
            {
                retVal.Link.Add(new BundleLink(new Uri(String.Format("{0}_page={1}", baseUri, pageNo)), "self"));
                if (pageNo > 0)
                {
                    retVal.Link.Add(new BundleLink(new Uri(String.Format("{0}_page=0", baseUri)), "first"));
                    retVal.Link.Add(new BundleLink(new Uri(String.Format("{0}_page={1}", baseUri, pageNo - 1)), "previous"));
                }
                if (pageNo <= nPages)
                {
                    retVal.Link.Add(new BundleLink(new Uri(String.Format("{0}_page={1}", baseUri, pageNo + 1)), "next"));
                    retVal.Link.Add(new BundleLink(new Uri(String.Format("{0}_page={1}", baseUri, nPages + 1)), "last"));
                }
            }
            else
            {
                retVal.Link.Add(new BundleLink(new Uri(baseUri), "self"));
            }

            // Updated
            retVal.Timestamp = DateTime.Now;
            //retVal.Generator = "MARC-HI Service Core Framework";

            // HACK: Remove me
            if (queryResult != null)
            {
                retVal.Total = queryResult.TotalResults;
            }

            //retVal.
            // Results
            if (result.Results != null)
            {
                var feedItems = new List <BundleEntry>();
                foreach (DomainResourceBase itm in result.Results)
                {
                    Uri         resourceUrl = new Uri(String.Format("{0}/{1}?_format={2}", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri, String.Format("{0}/{1}/_history/{2}", itm.GetType().Name, itm.Id, itm.VersionId), format));
                    BundleEntry feedResult  = new BundleEntry(); //new Bundleentry(String.Format("{0} id {1} version {2}", itm.GetType().Name, itm.Id, itm.VersionId), null ,resourceUrl);

                    feedResult.FullUrl = resourceUrl;

                    string summary = "<div xmlns=\"http://www.w3.org/1999/xhtml\">" + itm.Text.ToString() + "</div>";

                    // Add confidence if the attribute permits
                    ConfidenceAttribute confidence = itm.Attributes.Find(a => a is ConfidenceAttribute) as ConfidenceAttribute;
                    if (confidence != null)
                    {
                        feedResult.Search = new BundleSearch()
                        {
                            Score = confidence.Confidence
                        }
                    }
                    ;

                    feedResult.Resource = new BundleResrouce(itm);
                    feedItems.Add(feedResult);
                }
                retVal.Entry = feedItems;
            }

            // Outcome
            //if (result.Details.Count > 0 || result.Issues != null && result.Issues.Count > 0)
            //{
            //    var outcome = CreateOutcomeResource(result);
            //    retVal.ElementExtensions.Add(outcome, new XmlSerializer(typeof(OperationOutcome)));
            //    retVal.Description = new TextSyndicationContent(outcome.Text.ToString(), TextSyndicationContentKind.Html);
            //}
            return(retVal);
        }
Beispiel #10
0
        /// <summary>
        /// Read a patint resource
        /// </summary>
        public SVC.Messaging.FHIR.FhirOperationResult Read(string id, string versionId)
        {
            FhirOperationResult result = new FhirOperationResult();

            result.Details = new List <IResultDetail>();
            result.Results = new List <ResourceBase>();

            // Data persistence service
            IDataPersistenceService dataPersistence = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
            var container = dataPersistence.GetContainer(new VersionedDomainIdentifier()
            {
                Domain     = this.DataDomain,
                Identifier = id,
                Version    = String.IsNullOrEmpty(versionId) ? null : versionId
            }, String.IsNullOrEmpty(versionId));


            // Container was not found
            if (container == null)
            {
                result.Outcome = ResultCode.NotAvailable;
            }
            else
            {
                var processor = FhirMessageProcessorUtil.GetComponentProcessor(container.GetType());

                // Was there a history?
                if (versionId == null)
                {
                    result.Results.Add(processor.ProcessComponent(container as IComponent, result.Details));
                }
                else if (versionId == String.Empty) // Get all versions
                {
                    while (container != null)
                    {
                        var hsrc     = container as HealthServiceRecordContainer;
                        var resource = processor.ProcessComponent(container as IComponent, result.Details);

                        if (hsrc.IsMasked) // record is masked so add a detected issue
                        {
                            result.Issues.Add(new SVC.Core.Issues.DetectedIssue()
                            {
                                MitigatedBy = ManagementType.OtherActionTaken,
                                Severity    = IssueSeverityType.Moderate,
                                Text        = String.Format("{0}/_history/{1} will not be returned as it has been masked", resource.Id, resource.VersionId),
                                Type        = IssueType.DetectedIssue
                            });
                        }
                        else
                        {
                            result.Results.Add(resource);
                        }
                        container = hsrc.FindComponent(HealthServiceRecordSiteRoleType.OlderVersionOf) as IContainer;
                    }
                }
                else // Some version
                {
                    while (container != null)
                    {
                        var hsrc     = container as HealthServiceRecordContainer;
                        var resource = processor.ProcessComponent(container as IComponent, result.Details);
                        container = hsrc.FindComponent(HealthServiceRecordSiteRoleType.ReplacementOf) as IContainer;


                        if (resource != null && resource.VersionId.ToString() != versionId)
                        {
                            continue;
                        }

                        if (hsrc.IsMasked) // record is masked so add a detected issue
                        {
                            result.Issues.Add(new SVC.Core.Issues.DetectedIssue()
                            {
                                MitigatedBy = ManagementType.OtherActionTaken,
                                Severity    = IssueSeverityType.Moderate,
                                Text        = String.Format("{0}/_history/{1} will not be returned as it has been masked", resource.Id, resource.VersionId),
                                Type        = IssueType.DetectedIssue
                            });
                        }
                        else
                        {
                            result.Results.Add(resource);
                        }
                    }
                }
                result.Outcome = ResultCode.Accepted;
            }

            result.Results.RemoveAll(o => o == null);
            return(result);
        }
Beispiel #11
0
        /// <summary>
        /// Perform a read against the underlying IFhirResourceHandler
        /// </summary>
        private FhirOperationResult PerformRead(string resourceType, string id, string vid)
        {
            this.ThrowIfNotReady();
            // Get the services from the service registry
            var auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService;

            // Stuff for auditing and exception handling
            AuditData            audit   = null;
            List <IResultDetail> details = new List <IResultDetail>();
            FhirOperationResult  result  = null;

            try
            {
                // Get query parameters
                var queryParameters   = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
                var resourceProcessor = FhirResourceHandlerUtil.GetResourceHandler(resourceType);

                if (resourceProcessor == null) // Unsupported resource
                {
                    throw new FileNotFoundException("Specified resource type is not found");
                }

                // TODO: Appropriately format response
                // Process incoming request
                result = resourceProcessor.Read(id, vid);

                if (result.Outcome == ResultCode.Rejected)
                {
                    throw new InvalidDataException("Message was rejected");
                }
                else if (result.Outcome == (ResultCode.NotAvailable | ResultCode.Rejected))
                {
                    throw new FileLoadException(String.Format("Resource {0} is no longer available", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable ||
                         result.Results == null || result.Results.Count == 0)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Read failed");
                }
                audit = AuditUtil.CreateAuditData(result.Results);

                // Create the result
                if (result.Results != null && result.Results.Count > 0)
                {
                    WebOperationContext.Current.OutgoingResponse.LastModified = result.Results[0].Timestamp;
                    WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", String.Format("filename=\"{0}-{1}-{2}.xml\"", resourceType, result.Results[0].Id, result.Results[0].VersionId));
                    WebOperationContext.Current.OutgoingResponse.ETag = result.Results[0].VersionId;
                }
                return(result);
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                throw;
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Throw an appropriate exception based on the caught exception
        /// </summary>
        private object ErrorHelper(Exception e, FhirOperationResult result, bool returnBundle)
        {
            if (result == null && returnBundle)
            {
                result = new FhirQueryResult()
                {
                    Details = new List <IResultDetail>(), Query = new FhirQuery()
                    {
                        Start = 0, Quantity = 0
                    }
                }
            }
            ;
            else if (result == null)
            {
                result = new FhirOperationResult()
                {
                    Details = new List <IResultDetail>()
                    {
                        new ResultDetail(ResultDetailType.Error, "No information available", e)
                    }
                }
            }
            ;


            this.m_tracer.TraceEvent(TraceEventType.Error, 0, e.ToString());
            result.Details.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));

            HttpStatusCode retCode = HttpStatusCode.OK;

            if (e is NotSupportedException)
            {
                retCode = System.Net.HttpStatusCode.MethodNotAllowed;
            }
            else if (e is NotImplementedException)
            {
                retCode = System.Net.HttpStatusCode.NotImplemented;
            }
            else if (e is InvalidDataException)
            {
                retCode = HttpStatusCode.BadRequest;
            }
            else if (e is FileLoadException)
            {
                retCode = System.Net.HttpStatusCode.Gone;
            }
            else if (e is FileNotFoundException || e is ArgumentException)
            {
                retCode = System.Net.HttpStatusCode.NotFound;
            }
            else if (e is ConstraintException)
            {
                retCode = (HttpStatusCode)422;
            }
            else
            {
                retCode = System.Net.HttpStatusCode.InternalServerError;
            }

            WebOperationContext.Current.OutgoingResponse.StatusCode = retCode;
            WebOperationContext.Current.OutgoingResponse.Format     = WebMessageFormat.Xml;

            if (returnBundle)
            {
                throw new WebFaultException <Bundle>(MessageUtil.CreateBundle(result), retCode);
            }
            else
            {
                WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "filename=\"error.xml\"");
                throw e;
            }
            //return MessageUtil.CreateOutcomeResource(result);
        }
Beispiel #13
0
        /// <summary>
        /// Create a resource
        /// </summary>
        public DomainResourceBase CreateResource(string resourceType, string mimeType, DomainResourceBase target)
        {
            this.ThrowIfNotReady();

            FhirOperationResult result = null;

            AuditData       audit        = null;
            IAuditorService auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService;

            try
            {
                // Setup outgoing content

                // Create or update?
                var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType);
                if (handler == null)
                {
                    throw new FileNotFoundException(); // endpoint not found!
                }
                result = handler.Create(target, TransactionMode.Commit);
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created;

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new InvalidDataException("Resource structure is not valid");
                }
                else if (result.Outcome == ResultCode.AcceptedNonConformant)
                {
                    throw new ConstraintException("Resource not conformant");
                }
                else if (result.Outcome == ResultCode.TypeNotAvailable)
                {
                    throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri));
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Create failed");
                }

                audit = AuditUtil.CreateAuditData(result.Results);

                String baseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.AbsoluteUri;
                WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Location", String.Format("{0}{1}/{2}/_history/{3}", baseUri, resourceType, result.Results[0].Id, result.Results[0].VersionId));
                WebOperationContext.Current.OutgoingResponse.LastModified = result.Results[0].Timestamp;
                WebOperationContext.Current.OutgoingResponse.ETag         = result.Results[0].VersionId;


                return(result.Results[0]);
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                return(this.ErrorHelper(e, result, false) as DomainResourceBase);
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Read a value set
        /// </summary>
        public SVC.Messaging.FHIR.FhirOperationResult Read(string id, string versionId)
        {
            // Determine where to fetch the code system from
            List <Type> codeSystemType = new List <Type>();

            if (id != null && id.StartsWith("v3-")) // Everest
            {
                id = id.Substring(3);
                foreach (var asm in new Assembly[] { typeof(MARC.Everest.DataTypes.II).Assembly, typeof(MARC.Everest.RMIM.UV.NE2008.Vocabulary.AdministrativeGender).Assembly, typeof(MARC.Everest.RMIM.CA.R020402.Vocabulary.AdministrativeGender).Assembly })
                {
                    if (!String.IsNullOrEmpty(versionId))
                    {
                        var version = asm.GetCustomAttribute <AssemblyInformationalVersionAttribute>();
                        if (version != null && version.InformationalVersion != versionId)
                        {
                            continue;
                        }
                    }

                    var tcodesys = Array.Find(asm.GetTypes(), t => t.IsEnum && t.GetCustomAttribute <StructureAttribute>() != null && t.GetCustomAttribute <StructureAttribute>().Name == id);

                    if (tcodesys != null)
                    {
                        codeSystemType.Add(tcodesys);
                    }
                }
            }
            else
            {
                foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (!String.IsNullOrEmpty(versionId) && asm.GetName().Version.ToString() != versionId)
                    {
                        continue;
                    }

                    var tcodesys = Array.Find(asm.GetTypes(), t => t.Name.Equals(id));
                    if (tcodesys != null)
                    {
                        codeSystemType.Add(tcodesys);
                    }
                }
            }

            // Code system type
            if (codeSystemType == null || codeSystemType.Count == 0)
            {
                return new FhirOperationResult()
                       {
                           Outcome = ResultCode.TypeNotAvailable,
                       }
            }
            ;
            else
            {
                var retVal = new FhirOperationResult()
                {
                    Outcome = ResultCode.Accepted,
                    Results = new List <ResourceBase>()
                };

                foreach (var cs in codeSystemType)
                {
                    retVal.Results.Add(this.CreateValueSetFromEnum(cs));
                }
                return(retVal);
            }
        }