예제 #1
0
        /// <summary>
        /// Generate snapshots for all StructureDefinitions available to the preprocessor
        /// </summary>
        /// <returns></returns>
        public static OperationOutcome GenerateSnapshots(IEnumerable <StructureDefinition> sds, Action <StructureDefinition> snapshotGenerator, string path)
        {
            var outcome = new OperationOutcome();

            foreach (var sd in sds)
            {
                if (!sd.HasSnapshot)
                {
                    try
                    {
                        snapshotGenerator(sd);
                    }
                    catch (Exception e)
                    {
                        outcome.AddIssue($"Snapshot generation failed for '{sd.Url}'. Message: {e.Message}",
                                         Issue.UNAVAILABLE_SNAPSHOT_GENERATION_FAILED, path);
                    }
                }

                if (!sd.HasSnapshot)
                {
                    outcome.AddIssue($"Profile '{sd.Url}' does not include a snapshot.", Issue.UNAVAILABLE_NEED_SNAPSHOT, path);
                }
            }

            return(outcome);
        }
        public void Setup()
        {
            OperationOutcome level0 = new OperationOutcome();

            level0.AddIssue(Issue.CONTENT_ELEMENT_HAS_INCORRECT_TYPE.ToIssueComponent("A test error at level 0", "Patient"));

            OperationOutcome level1 = new OperationOutcome();

            Patient p = new Patient();

            p.Active  = true;
            _location = new PocoNavigator(p);
            _location.MoveToFirstChild();

            level1.AddIssue(Issue.PROFILE_ELEMENTDEF_CARDINALITY_MISSING.ToIssueComponent("A test warning at level 1", _location));

            OperationOutcome level2 = new OperationOutcome();

            level2.AddIssue(Issue.UNSUPPORTED_CONSTRAINT_WITHOUT_FHIRPATH.ToIssueComponent("A test warning at level 2", "Patient.active[0].id[0]"));
            level2.AddIssue(Issue.CONTENT_ELEMENT_MUST_MATCH_TYPE.ToIssueComponent("Another test error at level 2", "Patient.active[0].id[0]"));

            level1.Include(level2);

            level0.Include(level1);

            level0.AddIssue(Issue.PROFILE_ELEMENTDEF_IS_EMPTY.ToIssueComponent("A test warning at level 0", "Patient"));

            _report = level0;
        }
예제 #3
0
        private OperationOutcome processResult(string code, string system, string display, Coding coding, CodeableConcept codeableConcept, ValidateCodeResult result)
        {
            if (result?.Result?.Value == null)
            {
                throw Error.InvalidOperation($"Terminology service at {Endpoint.Endpoint.ToString()} did not return a result.");
            }

            var outcome = new OperationOutcome();

            if (result?.Result?.Value == false)
            {
                string message = result?.Message?.Value;

                if (message != null)
                {
                    outcome.AddIssue(message, Issue.TERMINOLOGY_CODE_NOT_IN_VALUESET);
                }
                else
                {
                    if (code != null && coding == null)
                    {
                        coding = new Coding(system, code, display);
                    }

                    var codeDisplay = codeableConcept != null?FhirSerializer.SerializeToJson(codeableConcept)
                                          : FhirSerializer.SerializeToJson(coding);

                    outcome.AddIssue($"Validation of '{codeDisplay}' failed, but" +
                                     $"the terminology service at {Endpoint.Endpoint.ToString()} did not provide further details.",
                                     Issue.TERMINOLOGY_CODE_NOT_IN_VALUESET);
                }
            }

            return(outcome);
        }
예제 #4
0
        public OperationOutcome ValidateBinding(IElementNavigator instance, ElementDefinition definition)
        {
            var outcome = new OperationOutcome();

            if (definition.Binding != null)
            {
                var binding = definition.Binding;

                if (binding.ValueSet != null)
                {
                    var uri = (binding.ValueSet as FhirUri)?.Value;

                    // == null, so we check whether this could NOT be casted to a FhirUri, thus is a ValueSet reference
                    if (uri == null)
                    {
                        uri = (binding.ValueSet as ResourceReference).Reference;

                        var codedType = Validator.DetermineType(definition, instance);
                        if (codedType != null)
                        {
                            if (codedType.Value.IsBindeableFhirType())
                            {
                                var bindable = instance.ParseBindable(codedType.Value);

                                if (bindable is Coding)
                                {
                                    return(ValidateBinding(bindable as Coding, uri, binding.Strength));
                                }
                                else
                                {
                                    return(ValidateBinding(bindable as CodeableConcept, uri, binding.Strength));
                                }
                            }
                            else
                            {
                                outcome.AddIssue($"A binding is given ('{uri}'), but the instance data is of type '{codedType.Value}', which is not bindeable.", Issue.CONTENT_TYPE_NOT_BINDEABLE, instance);
                            }
                        }
                        else
                        {
                            outcome.AddIssue($"Cannot determine type of data in instance to extract code/system information", Issue.CONTENT_ELEMENT_CANNOT_DETERMINE_TYPE, instance);
                        }
                    }
                    else
                    {
                        outcome.AddIssue($"Binding element references a valueset by uri ({uri}), which cannot be used to validate a binding",
                                         Issue.UNSUPPORTED_URI_BINDING_NOT_SUPPORTED, instance);
                    }
                }
                else
                {
                    outcome.AddIssue($"Encountered a binding element without a ValueSet reference", Issue.PROFILE_BINDING_WITHOUT_VALUESET, instance);
                }
            }

            return(outcome);
        }
        public OperationOutcome ValidateCode(string uri, string code, string system, string display = null, bool abstractAllowed = false)
        {
            var result = new OperationOutcome();
            var vs     = _resolver.FindValueSet(uri);

            if (vs == null)
            {
                result.AddIssue($"Cannot retrieve valueset '{uri}'", Issue.UNAVAILABLE_VALUESET);
                return(result);
            }

            // We might have a cached or pre-expanded version brought to us by the _source
            if (!vs.HasExpansion)
            {
                // This will expand te vs - since we do not deepcopy() it, it will change the instance
                // as it was passed to us from the source
                try
                {
                    _expander.Expand(vs);
                }
                catch (Exception e)
                {
                    var tooComplex = e is NotSupportedException || e is ValueSetExpansionTooBigException;

                    result.AddIssue($"ValueSet cannot be expanded: {e.Message}",
                                    tooComplex ? Issue.TERMINOLOGY_VALUESET_TOO_COMPLEX : Issue.TERMINOLOGY_EXPANSION_FAILED);
                    return(result);
                }
            }

            // No fallback necessary, just do a direct check for now

            var component = vs.FindInExpansion(code, system);
            var codeLabel = $"Code '{code}' from system '{system}'";

            if (component == null)
            {
                result.AddIssue($"{codeLabel} does not exists in valueset '{uri}'", Issue.TERMINOLOGY_CODE_NOT_IN_VALUESET);
            }
            else
            {
                if (component.Abstract == true && !abstractAllowed)
                {
                    result.AddIssue($"{codeLabel} is abstract, which is not allowed here", Issue.TERMINOLOGY_ABSTRACT_CODE_NOT_ALLOWED);
                }

                if (display != null && component.Display != null && display != component.Display)
                {
                    result.AddIssue($"{codeLabel} has incorrect display '{display}', should be '{component.Display}'", Issue.TERMINOLOGY_INCORRECT_DISPLAY);
                }
            }

            return(result);
        }
예제 #6
0
        // This is the one and only main internal entry point for all validations, which in its term
        // will call step 1 in the validator, the function validateElement
        internal OperationOutcome Validate(ScopedNavigator instance, IEnumerable <ElementDefinitionNavigator> definitions)
        {
            var outcome = new OperationOutcome();

            try
            {
                List <ElementDefinitionNavigator> allDefinitions = new List <ElementDefinitionNavigator>(definitions);

                if (allDefinitions.Count() == 1)
                {
                    outcome.Add(validateElement(allDefinitions.Single(), instance));
                }
                else
                {
                    var validators = allDefinitions.Select(nav => createValidator(nav, instance));
                    outcome.Add(this.Combine(BatchValidationMode.All, instance, validators));
                }
            }
            catch (Exception e)
            {
                outcome.AddIssue($"Internal logic failure: {e.Message}", Issue.PROCESSING_CATASTROPHIC_FAILURE, instance);
            }

            return(outcome);
        }
예제 #7
0
 internal void Trace(OperationOutcome outcome, string message, Issue issue, IElementNavigator location)
 {
     if (Settings.Trace || issue.Severity != OperationOutcome.IssueSeverity.Information)
     {
         outcome.AddIssue(message, issue, location);
     }
 }
예제 #8
0
        public static OperationOutcome.IssueComponent AddIssue(this OperationOutcome outcome, string message, Issue infoIssue, string location = null)
        {
            var issue = infoIssue.ToIssueComponent(message, location);

            outcome.AddIssue(issue);
            return(issue);
        }
예제 #9
0
        public static OperationOutcome NewOutcomeWithIssue(this Issue infoIssue, string message, string location = null)
        {
            var outcome = new OperationOutcome();
            var issue   = infoIssue.ToIssueComponent(message, location);

            outcome.AddIssue(issue);
            return(outcome);
        }
예제 #10
0
        internal OperationOutcome.IssueComponent Trace(OperationOutcome outcome, string message, Issue issue, string location)
        {
            if (Settings.Trace || issue.Severity != OperationOutcome.IssueSeverity.Information)
            {
                return(outcome.AddIssue(message, issue, location));
            }

            return(null);
        }
 public static void Add(this OperationOutcome outcome, OperationOutcome other)
 {
     outcome.AddIssue(other.Issue);
     //foreach (var issue in other.Issue)
     //{
     //    //var myIssue = (OperationOutcome.IssueComponent)issue.DeepCopy();
     //    var myIssue = issue;
     //    outcome.AddIssue(myIssue);
     //}
 }
        internal static OperationOutcome ValidateXml(this Validator me, XDocument instance)
        {
            var result = new OperationOutcome();

            ValidationEventHandler veh = (o, args) => result.AddIssue(ToIssueComponent(args));

            instance.Validate(SchemaCollection.ValidationSchemaSet, veh);

            return(result);
        }
 public static void Include(this OperationOutcome outcome, OperationOutcome other)
 {
     foreach (var issue in other.Issue)
     {
         // var myIssue = (OperationOutcome.IssueComponent)issue.DeepCopy();
         var myIssue = issue;
         myIssue.SetHierarchyLevel(myIssue.GetHierarchyLevel() + 1);
         outcome.AddIssue(myIssue);
     }
 }
        private static OperationOutcome validateMinMaxValue(Validator me, Element definition, ITypedElement instance,
                                                            int comparisonOutcome, string elementName)
        {
            var outcome = new OperationOutcome();

            if (definition != null)
            {
                // Min/max are only defined for ordered types
                if (definition.GetType().IsOrderedFhirType())
                {
                    try
                    {
                        var instanceValue = instance.GetComparableValue(definition.GetType());

                        if (instanceValue != null)
                        {
                            if (Compare(instanceValue, definition) == comparisonOutcome)
                            {
                                var label = comparisonOutcome == -1 ? "smaller than" :
                                            comparisonOutcome == 0 ? "equal to" :
                                            "larger than";
                                var issue = comparisonOutcome == -1 ? Issue.CONTENT_ELEMENT_PRIMITIVE_VALUE_TOO_SMALL :
                                            Issue.CONTENT_ELEMENT_PRIMITIVE_VALUE_TOO_LARGE;

                                outcome.AddIssue($"Instance value '{instanceValue}' is {label} {elementName} '{definition}'", issue, instance);
                            }
                        }
                    }
                    catch (NotSupportedException ns)
                    {
                        outcome.AddIssue($"Comparing the instance against the {elementName} failed: {ns.Message}", Issue.UNSUPPORTED_MIN_MAX_QUANTITY, instance);
                    }
                }
                else
                {
                    me.Trace(outcome, $"{elementName} was given in ElementDefinition, but type '{definition.TypeName}' is not an ordered type", Issue.PROFILE_ELEMENTDEF_MIN_MAX_USES_UNORDERED_TYPE, instance);
                }
            }

            return(outcome);
        }
예제 #15
0
        private OperationOutcome validateCodeVS(ValueSet vs, string code, string system, string display, bool?abstractAllowed)
        {
            if (code == null)
            {
                return(Issue.TERMINOLOGY_NO_CODE_IN_INSTANCE.NewOutcomeWithIssue($"No code supplied."));
            }

            lock (vs.SyncLock)
            {
                // We might have a cached or pre-expanded version brought to us by the _source
                if (!vs.HasExpansion)
                {
                    // This will expand te vs - since we do not deepcopy() it, it will change the instance
                    // as it was passed to us from the source
                    _expander.Expand(vs);
                }
            }

            var component = vs.FindInExpansion(code, system);
            var codeLabel = $"Code '{code}' from system '{system}'";
            var result    = new OperationOutcome();

            if (component == null)
            {
                result.AddIssue($"{codeLabel} does not exist in valueset '{vs.Url}'", Issue.TERMINOLOGY_CODE_NOT_IN_VALUESET);
            }
            else
            {
                if (component.Abstract == true && abstractAllowed == false)  // will be ignored if abstractAllowed == null
                {
                    result.AddIssue($"{codeLabel} is abstract, which is not allowed here", Issue.TERMINOLOGY_ABSTRACT_CODE_NOT_ALLOWED);
                }

                if (display != null && component.Display != null && display != component.Display)
                {
                    result.AddIssue($"{codeLabel} has incorrect display '{display}', should be '{component.Display}'", Issue.TERMINOLOGY_INCORRECT_DISPLAY);
                }
            }

            return(result);
        }
예제 #16
0
        private OperationOutcome callService(string code, string system, string display, string uri, BindingStrength?strength, string path)
        {
            var outcome = new OperationOutcome();

            OperationOutcome validateResult = _service.ValidateCode(uri, code, system, display, abstractAllowed: false);
            var codeLabel = $"Code '{code}' from system '{system}'";

            if (display != null)
            {
                codeLabel += $" with display '{display}'";
            }

            if (validateResult.Where(type: OperationOutcome.IssueType.NotSupported).Any())
            {
                if (strength != BindingStrength.Example)
                {
                    outcome.AddIssue($"The terminology service is incapable of validating {codeLabel} (valueset '{uri}').", Issue.UNSUPPORTED_BINDING_NOT_SUPPORTED_BY_SERVICE, path);
                    validateResult.MakeInformational();
                    outcome.Include(validateResult);
                }
                return(outcome);
            }

            if (!validateResult.Success)
            {
                if (strength == BindingStrength.Required)
                {
                    outcome.AddIssue($"{codeLabel} is not valid for required binding to valueset '{uri}'", Issue.CONTENT_INVALID_FOR_REQUIRED_BINDING, path);
                }
                else if (strength != BindingStrength.Example)
                {
                    outcome.AddIssue($"{codeLabel} is not valid for non-required binding to valueset '{uri}'", Issue.CONTENT_INVALID_FOR_NON_REQUIRED_BINDING, path);
                }

                validateResult.MakeInformational();
            }

            outcome.Include(validateResult);
            return(outcome);
        }
예제 #17
0
        /// <summary>
        /// Resolves the StructureDefinitions referred to by the given canonicals, and adds them
        /// to the list of StructureDefinitions available to the preprocessor
        /// </summary>
        /// <returns></returns>
        public OperationOutcome Resolve()
        {
            if (_lastResolutionOutcome != null)
            {
                return(_lastResolutionOutcome);
            }

            var outcome = new OperationOutcome();

            // Go through all entries to find those that don't yet have a StructureDefinition
            foreach (var entry in _allEntries.Where(e => e.Unresolved))
            {
                StructureDefinition structureDefinition = null;

                try
                {
                    // Once FindStructureDefinition() gets an overload to resolve multiple at the same time,
                    // use that one
                    structureDefinition = _resolver(entry.Reference);

                    if (structureDefinition == null)
                    {
                        outcome.AddIssue($"Unable to resolve reference to profile '{entry.Reference}'", Issue.UNAVAILABLE_REFERENCED_PROFILE, _path);
                    }
                    else
                    {
                        entry.StructureDefinition = structureDefinition;
                    }
                }
                catch (Exception e)
                {
                    outcome.AddIssue($"Resolution of profile at '{entry.Reference}' failed: {e.Message}", Issue.UNAVAILABLE_REFERENCED_PROFILE, _path);
                    continue;
                }
            }

            _lastResolutionOutcome = outcome;
            return(outcome);
        }
예제 #18
0
        /// <summary>
        /// Generate snapshots for all StructureDefinitions available to the preprocessor
        /// </summary>
        /// <returns></returns>
        public static OperationOutcome GenerateSnapshots(IEnumerable <StructureDefinition> sds, Func <StructureDefinition, OperationOutcome> snapshotGenerator, string path)
        {
            var outcome = new OperationOutcome();

            foreach (var sd in sds)
            {
                lock (sd.SyncLock)
                {
                    if (!sd.HasSnapshot)
                    {
                        try
                        {
                            var snapshotOutcome = snapshotGenerator(sd);
                            // [WMR 20180725] Null outcome also indicates success
                            if (snapshotOutcome != null && !snapshotOutcome.Success)
                            {
                                outcome.AddIssue($"Snapshot generation failed for '{sd.Url}'. Details follow below.",
                                                 Issue.UNAVAILABLE_SNAPSHOT_GENERATION_FAILED, path);
                                outcome.Add(snapshotOutcome);
                            }
                        }
                        catch (Exception e)
                        {
                            outcome.AddIssue($"Snapshot generation failed for '{sd.Url}'. Message: {e.Message}",
                                             Issue.UNAVAILABLE_SNAPSHOT_GENERATION_FAILED, path);
                        }
                    }
                }

                if (!sd.HasSnapshot)
                {
                    outcome.AddIssue($"Profile '{sd.Url}' does not include a snapshot.", Issue.UNAVAILABLE_NEED_SNAPSHOT, path);
                }
            }

            return(outcome);
        }
예제 #19
0
 OperationOutcome.IssueComponent addIssue(OperationOutcome.IssueComponent component, string profileUrl = null)
 {
     if (component == null)
     {
         throw Error.ArgumentNull(nameof(component));
     }
     if (_outcome == null)
     {
         _outcome = new OperationOutcome();
     }
     // Return current profile url in Diagnostics field
     component.Diagnostics = profileUrl ?? CurrentProfileUri;
     _outcome.AddIssue(component);
     return(component);
 }
예제 #20
0
        private OperationOutcome callService(string canonical, string code = null, string system = null, string display       = null,
                                             Coding coding = null, CodeableConcept cc            = null, bool?abstractAllowed = null)
        {
            var outcome = new OperationOutcome();

            try
            {
                outcome = _service.ValidateCode(canonical: canonical, code: code, system: system, display: display,
                                                coding: coding, codeableConcept: cc, @abstract: abstractAllowed);
                foreach (var issue in outcome.Issue)
                {
                    issue.Location = new string[] { _path }
                }
                ;
            }
            catch (TerminologyServiceException tse)
            {
                outcome.AddIssue($"Terminology service failed while validating code '{code}' (system '{system}'): {tse.Message}", Issue.TERMINOLOGY_SERVICE_FAILED, _path);
            }

            return(outcome);
        }
예제 #21
0
        public OperationOutcome Process()
        {
            var outcome = new OperationOutcome();

            // Start preprocessing by resolving the references to the profiles (if any)
            var resolveOutcome = _profiles.Resolve();

            outcome.Add(resolveOutcome);

            if (resolveOutcome.Success)
            {
                // Then, validate consistency of the profile assertions
                var validationOutcome = _profiles.Validate();
                outcome.Add(validationOutcome);

                if (validationOutcome.Success)
                {
                    if (_profiles.MinimalProfiles.Any())
                    {
                        // Then, generate snapshots for all sds that we have found
                        var genSnapshotOutcome = GenerateSnapshots(_profiles.MinimalProfiles, _snapshotGenerator, _path);
                        outcome.Add(genSnapshotOutcome);

                        if (genSnapshotOutcome.Success)
                        {
                            // Finally, return navigators to the definitions
                            Result = CreateNavigators(_profiles.MinimalProfiles);
                        }
                    }
                    else
                    {
                        outcome.AddIssue("There are no profile and type assertions at this point in the instance, so validation cannot succeed",
                                         Issue.PROFILE_NO_PROFILE_TO_VALIDATE_AGAINST, _path);
                    }
                }
            }

            return(outcome);
        }
        internal static OperationOutcome ValidatedParseXml(this Validator me, XmlReader instance, out Resource poco)
        {
            var result = new OperationOutcome();

            try
            {
                if (me.Settings.EnableXsdValidation)
                {
                    var doc = XDocument.Load(instance, LoadOptions.SetLineInfo);
                    result.Add(me.ValidateXml(doc));
                    instance = doc.CreateReader();
                }

                poco = (Resource)(new FhirXmlParser()).Parse(instance, typeof(Resource));
            }
            catch (Exception e)
            {
                result.AddIssue($"Parsing of Xml into a FHIR Poco failed: {e.Message}", Issue.XSD_CONTENT_POCO_PARSING_FAILED, (string)null);
                poco = null;
            }

            return(result);
        }
예제 #23
0
        private OperationOutcome validateCodeVS(ValueSet vs, CodeableConcept cc, bool?abstractAllowed)
        {
            var outcome = new OperationOutcome();

            // Maybe just a text, but if there are no codings, that's a positive result
            if (!cc.Coding.Any())
            {
                return(outcome);
            }

            // If we have just 1 coding, we better handle this using the simpler version of ValidateBinding
            if (cc.Coding.Count == 1)
            {
                return(validateCodeVS(vs, cc.Coding.Single(), abstractAllowed));
            }

            // Else, look for one succesful match in any of the codes in the CodeableConcept
            var callResults    = cc.Coding.Select(coding => validateCodeVS(vs, coding, abstractAllowed));
            var successOutcome = callResults.Where(r => r.Success).OrderBy(oo => oo.Warnings).FirstOrDefault();

            if (successOutcome == null)
            {
                outcome.AddIssue("None of the Codings in the CodeableConcept were valid for the binding. Details follow.", Issue.CONTENT_INVALID_FOR_REQUIRED_BINDING);
                foreach (var cr in callResults)
                {
                    cr.MakeInformational();
                    outcome.Include(cr);
                }
            }
            else
            {
                outcome.Add(successOutcome);
            }

            return(outcome);
        }
 public static void AddIssue(this OperationOutcome outcome, params OperationOutcome.IssueComponent[] issue)
 {
     outcome.AddIssue((IEnumerable <OperationOutcome.IssueComponent>)issue);
 }
예제 #25
0
 public static OperationOutcome AddError(this OperationOutcome outcome, string message)
 {
     return(outcome.AddIssue(OperationOutcome.IssueSeverity.Error, message));
 }
예제 #26
0
 public static OperationOutcome AddMessage(this OperationOutcome outcome, HttpStatusCode code, string message)
 {
     return(outcome.AddIssue(IssueSeverityOf(code), message));
 }
예제 #27
0
 public static OperationOutcome AddMessage(this OperationOutcome outcome, string message)
 {
     return(outcome.AddIssue(OperationOutcome.IssueSeverity.Information, message));
 }
        public static OperationOutcome Combine(this Validator validator, BatchValidationMode mode, ITypedElement instance, IEnumerable <Func <OperationOutcome> > validations)
        {
            if (validations.Count() == 0)
            {
                return(new OperationOutcome());
            }

            if (validations.Count() == 1)
            {
                // To not pollute the output if there's just a single input, just add it to the output
                return(validations.First()());
            }

            OperationOutcome combinedResult = new OperationOutcome();

            var modeLabel = mode == BatchValidationMode.All ? "ALL" : "ANY";

            validator.Trace(combinedResult, $"Combination of {validations.Count()} child validation runs, {modeLabel} must succeed", Issue.PROCESSING_PROGRESS, instance);

            int failures  = 0;
            int successes = 0;

            List <OperationOutcome> results = new List <OperationOutcome>();

            // Run the given validations one by one, short circuiting when ANY success is enough
            foreach (var validation in validations)
            {
                var result = validation();
                results.Add(result);

                if (result.Success)
                {
                    successes += 1;
                }
                else
                {
                    failures += 1;
                }

                if (mode == BatchValidationMode.Any && successes > 0)
                {
                    break;                                                         // shortcut evaluation
                }
            }

            // Did we have success overall?
            bool success = mode == BatchValidationMode.Any && successes > 0 ||
                           mode == BatchValidationMode.All && failures == 0 ||
                           mode == BatchValidationMode.Once && successes == 1;


            // Now, build final report

            for (var index = 0; index < results.Count; index++)
            {
                var result = results[index];
                validator.Trace(combinedResult, $"Report {index}: {(result.Success ? "SUCCESS" : "FAILURE")}", Issue.PROCESSING_PROGRESS, instance);

                if (success)
                {
                    // We'd like to include all results of the combined reports, but if the total result is a success,
                    // any errors in failing runs should just be informational
                    if (!result.Success)
                    {
                        result.MakeInformational();
                    }
                }

                combinedResult.Include(result);
            }

            if (success)
            {
                validator.Trace(combinedResult, "Combined validation succeeded", Issue.PROCESSING_PROGRESS, instance);
            }
            else
            {
                combinedResult.AddIssue($"Combined {modeLabel} validation failed, {failures} child validation runs failed, {successes} succeeded", Issue.PROCESSING_PROGRESS, instance);
            }


            return(combinedResult);
        }
예제 #29
0
 public static void AddIssue(this OperationOutcome outcome, string message, Issue infoIssue, string location = null)
 {
     outcome.AddIssue(infoIssue.ToIssueComponent(message, location));
 }
예제 #30
0
 public static void AddIssue(this OperationOutcome outcome, string message, Issue infoIssue, IElementNavigator location)
 {
     outcome.AddIssue(infoIssue.ToIssueComponent(message, location));
 }