Ejemplo n.º 1
0
        /// <summary>
        /// Searches a resource from the client registry datastore
        /// </summary>
        public Bundle SearchResource(string resourceType)
        {
            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>();
            FhirQueryResult      result  = null;

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

                // Setup outgoing content
                WebOperationContext.Current.OutgoingRequest.Headers.Add("Last-Modified", DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz"));

                if (resourceProcessor == null) // Unsupported resource
                {
                    throw new FileNotFoundException();
                }

                // TODO: Appropriately format response
                // Process incoming request
                result = resourceProcessor.Query(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters);

                if (result == null || result.Outcome == ResultCode.Rejected)
                {
                    throw new InvalidDataException("Message was rejected");
                }
                else if (result.Outcome != ResultCode.Accepted)
                {
                    throw new DataException("Query failed");
                }

                audit = AuditUtil.CreateAuditData(result.Results);
                // Create the Atom feed
                return(MessageUtil.CreateBundle(result));
            }
            catch (Exception e)
            {
                audit         = AuditUtil.CreateAuditData(null);
                audit.Outcome = OutcomeIndicator.EpicFail;
                return(this.ErrorHelper(e, result, true) as Bundle);
            }
            finally
            {
                if (auditService != null)
                {
                    auditService.SendAudit(audit);
                }
            }
        }
Ejemplo n.º 2
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);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads the complete history of the specified identifier
        /// </summary>
        public Bundle History(string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                this.m_traceSource.TraceError($"Argument {nameof(id)} null or empty");
                throw new ArgumentNullException(this.m_localizationService.GetString("error.type.ArgumentNullException"));
            }

            Guid guidId = Guid.Empty;

            if (!Guid.TryParse(id, out guidId))
            {
                throw new ArgumentException(this.m_localizationService.FormatString("error.type.ArgumentException", new
                {
                    param = "id"
                }));
            }

            var result = this.Read(guidId, Guid.Empty);

            if (result == null)
            {
                throw new KeyNotFoundException(this.m_localizationService.GetString("error.type.KeyNotFoundException"));
            }

            // Results
            List <TModel> results = new List <TModel>()
            {
                result
            };

            while ((result as IVersionedEntity)?.PreviousVersionKey.HasValue == true)
            {
                result = this.Read(guidId, (result as IVersionedEntity).PreviousVersionKey.Value);
                results.Add(result);
            }

            // FHIR Operation result
            var retVal = new FhirQueryResult(typeof(TFhirResource).Name)
            {
                Results = results.Select(this.MapToFhir).Select(o => new Bundle.EntryComponent()
                {
                    Resource = o,
                    Response = new Bundle.ResponseComponent()
                    {
                        Status = "200"
                    }
                }).ToList()
            };

            return(ExtensionUtil.ExecuteBeforeSendResponseBehavior(TypeRestfulInteraction.HistoryInstance, this.ResourceType, MessageUtil.CreateBundle(retVal, Bundle.BundleType.History)) as Bundle);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Queries for a specified resource.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Returns the FHIR query result containing the results of the query.</returns>
        /// <exception cref="System.ArgumentNullException">parameters</exception>
        public virtual Bundle Query(System.Collections.Specialized.NameValueCollection parameters)
        {
            if (parameters == null)
            {
                this.m_traceSource.TraceError($"Argument {nameof(parameters)} null or empty");
                throw new ArgumentNullException(this.m_localizationService.GetString("error.type.ArgumentNullException"));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            FhirQuery query = QueryRewriter.RewriteFhirQuery(typeof(TFhirResource), typeof(TModel), parameters, out hdsiQuery);

            // Do the query
            int totalResults = 0;
            var predicate    = QueryExpressionParser.BuildLinqExpression <TModel>(hdsiQuery);
            var hdsiResults  = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);

            var auth = AuthenticationContext.Current;

            // Return FHIR query result
            if (Environment.ProcessorCount > 4)
            {
                hdsiResults = hdsiResults.AsParallel().AsOrdered();
            }

            var retVal = new FhirQueryResult(typeof(TFhirResource).Name)
            {
                Results = hdsiResults.Select(o =>
                {
                    using (AuthenticationContext.EnterContext(auth.Principal))
                    {
                        return(new Bundle.EntryComponent()
                        {
                            Resource = this.MapToFhir(o),
                            Search = new Bundle.SearchComponent()
                            {
                                Mode = Bundle.SearchEntryMode.Match
                            }
                        });
                    }
                }).ToList(),
                Query        = query,
                TotalResults = totalResults
            };

            this.ProcessIncludes(hdsiResults, parameters, retVal);

            return(ExtensionUtil.ExecuteBeforeSendResponseBehavior(TypeRestfulInteraction.SearchType, this.ResourceType, MessageUtil.CreateBundle(retVal, Bundle.BundleType.Searchset)) as Bundle);
        }
Ejemplo n.º 5
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);
        }
        /// <summary>
        /// Parameters
        /// </summary>
        public override Bundle Query(NameValueCollection parameters)
        {
            if (parameters == null)
            {
                this.m_tracer.TraceError(nameof(parameters));
                throw new ArgumentNullException(nameof(parameters), this.m_localizationService.GetString("error.type.ArgumentNullException"));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            var query = QueryRewriter.RewriteFhirQuery(typeof(Observation), typeof(Core.Model.Acts.Observation), parameters, out hdsiQuery);

            // Do the query
            var totalResults = 0;

            IEnumerable <Core.Model.Acts.Observation> hdsiResults = null;

            if (parameters["value-concept"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <CodedObservation>(hdsiQuery);
                hdsiResults = this.QueryEx(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else if (parameters["value-quantity"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <QuantityObservation>(hdsiQuery);
                hdsiResults = this.QueryEx(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <Core.Model.Acts.Observation>(hdsiQuery);
                hdsiResults = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);
            }

            // Return FHIR query result
            var retVal = new FhirQueryResult("Observation")
            {
                Results = hdsiResults.Select(this.MapToFhir).Select(o => new Bundle.EntryComponent
                {
                    Resource = o,
                    Search   = new Bundle.SearchComponent
                    {
                        Mode = Bundle.SearchEntryMode.Match
                    }
                }).ToList(),
                Query        = query,
                TotalResults = totalResults
            };

            base.ProcessIncludes(hdsiResults, parameters, retVal);

            return(ExtensionUtil.ExecuteBeforeSendResponseBehavior(TypeRestfulInteraction.SearchType, this.ResourceType, MessageUtil.CreateBundle(retVal, Bundle.BundleType.Searchset)) as Bundle);
        }