From 47454554e39427a63e0208be57d9c118bcd31d63 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Sun, 7 Nov 2021 15:04:33 -0500 Subject: [PATCH] Moved concurrent details from ValidationOptions to FhirValidator --- .../java/ca/uhn/fhir/context/FhirContext.java | 18 +- .../fhir/context/IFhirValidatorFactory.java | 7 + .../ca/uhn/fhir/validation/FhirValidator.java | 50 +++++- .../fhir/validation/ValidationOptions.java | 41 +---- .../fhir/jpa/dao/BaseHapiFhirResourceDao.java | 2 - .../FhirResourceDaoDstu3TerminologyTest.java | 1 - .../ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java | 3 - .../r4/FhirResourceDaoR4TerminologyTest.java | 1 - .../ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java | 3 - .../BaseValidatingInterceptor.java | 23 +-- .../RequestValidatingInterceptor.java | 5 +- .../ResponseValidatingInterceptor.java | 5 +- .../ca/uhn/fhir/jpa/api/config/DaoConfig.java | 16 +- .../FhirInstanceValidatorR4Test.java | 158 +++++++++--------- .../QuestionnaireResponseValidatorR5Test.java | 1 - 15 files changed, 165 insertions(+), 169 deletions(-) create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IFhirValidatorFactory.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java index 2c3a93ff048..152ef94d2dc 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java @@ -127,6 +127,7 @@ public class FhirContext { private volatile Boolean myFormatJsonSupported; private volatile Boolean myFormatNDJsonSupported; private volatile Boolean myFormatRdfSupported; + private IFhirValidatorFactory myFhirValidatorFactory = fhirContext -> new FhirValidator(fhirContext); /** * @deprecated It is recommended that you use one of the static initializer methods instead @@ -908,7 +909,7 @@ public class FhirContext { *

*/ public FhirValidator newValidator() { - return new FhirValidator(this); + return myFhirValidatorFactory.newFhirValidator(this); } public ViewGenerator newViewGenerator() { @@ -1072,9 +1073,22 @@ public class FhirContext { * * @param theParserErrorHandler The error handler */ - public void setParserErrorHandler(final IParserErrorHandler theParserErrorHandler) { + public FhirContext setParserErrorHandler(final IParserErrorHandler theParserErrorHandler) { Validate.notNull(theParserErrorHandler, "theParserErrorHandler must not be null"); myParserErrorHandler = theParserErrorHandler; + return this; + } + + /** + * Set the factory method used to create FhirValidator instances + * + * @param theFhirValidatorFactory + * @return this + * @since 5.6.0 + */ + public FhirContext setFhirValidatorFactory(IFhirValidatorFactory theFhirValidatorFactory) { + myFhirValidatorFactory = theFhirValidatorFactory; + return this; } @SuppressWarnings({"cast"}) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IFhirValidatorFactory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IFhirValidatorFactory.java new file mode 100644 index 00000000000..0252d252dd4 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IFhirValidatorFactory.java @@ -0,0 +1,7 @@ +package ca.uhn.fhir.context; + +import ca.uhn.fhir.validation.FhirValidator; + +public interface IFhirValidatorFactory { + FhirValidator newFhirValidator(FhirContext theFhirContext); +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java index cf6cb013a53..b8a3de99f9b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java @@ -58,11 +58,16 @@ public class FhirValidator { private static final Logger ourLog = LoggerFactory.getLogger(FhirValidator.class); private static final String I18N_KEY_NO_PH_ERROR = FhirValidator.class.getName() + ".noPhError"; + public static final int DEFAULT_BUNDLE_VALIDATION_THREADCOUNT = 1; private static volatile Boolean ourPhPresentOnClasspath; private final FhirContext myContext; private List myValidators = new ArrayList<>(); private IInterceptorBroadcaster myInterceptorBraodcaster; + // FIXME KHS make it clear in the docs that bundle structure is not validated when this is true + private boolean myConcurrentBundleValidation; + private int myBundleValidationThreadCount = DEFAULT_BUNDLE_VALIDATION_THREADCOUNT; + private ExecutorService myExecutor; /** @@ -226,7 +231,7 @@ public class FhirValidator { applyDefaultValidators(); - if (theResource instanceof IBaseBundle && theOptions.isConcurrentBundleValidation()) { + if (theResource instanceof IBaseBundle && myConcurrentBundleValidation) { return validateBundleEntriesConcurrently((IBaseBundle) theResource, theOptions); } @@ -236,7 +241,7 @@ public class FhirValidator { private ValidationResult validateBundleEntriesConcurrently(IBaseBundle theBundle, ValidationOptions theOptions) { List entries = BundleUtil.toListOfResources(myContext, theBundle); - ExecutorService executorService = getExecutorService(theOptions); + ExecutorService executorService = getExecutorService(); List> futures = new ArrayList<>(); for (IBaseResource entry : entries) { futures.add(executorService.submit(() -> validateResource(entry, theOptions))); @@ -255,9 +260,9 @@ public class FhirValidator { return new ValidationResult(myContext, validationMessages.stream().collect(Collectors.toList())); } - private ExecutorService getExecutorService(ValidationOptions theOptions) { + private ExecutorService getExecutorService() { if (myExecutor == null) { - int size = theOptions.getBundleValidationThreadCount(); + int size = myBundleValidationThreadCount; ourLog.info("Creating FhirValidation thread pool with size {}", size); myExecutor = Executors.newFixedThreadPool(size); } @@ -308,7 +313,7 @@ public class FhirValidator { IValidationContext ctx = ValidationContext.forText(myContext, theResource, theOptions); - if (ctx.getResource() instanceof IBaseBundle && theOptions.isConcurrentBundleValidation()) { + if (ctx.getResource() instanceof IBaseBundle && myConcurrentBundleValidation) { return validateBundleEntriesConcurrently((IBaseBundle) ctx.getResource(), theOptions); } @@ -335,4 +340,39 @@ public class FhirValidator { myExecutor = theExecutor; return this; } + + /** + * If this is true, bundles will be validated in parallel threads. The bundle structure itself will not be validated, + * only the resources in its entries. + */ + + public boolean isConcurrentBundleValidation() { + return myConcurrentBundleValidation; + } + + /** + * If this is true, bundles will be validated in parallel threads. The bundle structure itself will not be validated, + * only the resources in its entries. + */ + public FhirValidator setConcurrentBundleValidation(boolean theConcurrentBundleValidation) { + myConcurrentBundleValidation = theConcurrentBundleValidation; + return this; + } + + /** + * The number of threads bundle entries will be validated within. This is only used when + * {@link #isConcurrentBundleValidation} is true. + */ + public int getBundleValidationThreadCount() { + return myBundleValidationThreadCount; + } + + /** + * The number of threads bundle entries will be validated within. This is only used when + * {@link #isConcurrentBundleValidation} is true. + */ + public FhirValidator setBundleValidationThreadCount(int theBundleValidationThreadCount) { + myBundleValidationThreadCount = theBundleValidationThreadCount; + return this; + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/ValidationOptions.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/ValidationOptions.java index 08c3ddb90c6..50c032596b6 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/ValidationOptions.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/ValidationOptions.java @@ -30,13 +30,11 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; public class ValidationOptions { - public static final int DEFAULT_BUNDLE_VALIDATION_THREADCOUNT = 1; private static ValidationOptions ourEmpty; private Set myProfiles; - // FIXME KHS make it clear in the docs that bundle structure is not validated when this is true - private boolean myConcurrentBundleValidation; - private int myBundleValidationThreadCount = DEFAULT_BUNDLE_VALIDATION_THREADCOUNT; + public ValidationOptions() { + } public Set getProfiles() { return myProfiles != null ? Collections.unmodifiableSet(myProfiles) : Collections.emptySet(); @@ -59,41 +57,6 @@ public class ValidationOptions { return this; } - /** - * If this is true, bundles will be validated in parallel threads. The bundle structure itself will not be validated, - * only the resources in its entries. - */ - - public boolean isConcurrentBundleValidation() { - return myConcurrentBundleValidation; - } - - /** - * If this is true, bundles will be validated in parallel threads. The bundle structure itself will not be validated, - * only the resources in its entries. - */ - public ValidationOptions setConcurrentBundleValidation(boolean theConcurrentBundleValidation) { - myConcurrentBundleValidation = theConcurrentBundleValidation; - return this; - } - - /** - * The number of threads bundle entries will be validated within. This is only used when - * {@link #isConcurrentBundleValidation} is true. - */ - public int getBundleValidationThreadCount() { - return myBundleValidationThreadCount; - } - - /** - * The number of threads bundle entries will be validated within. This is only used when - * {@link #isConcurrentBundleValidation} is true. - */ - public ValidationOptions setBundleValidationThreadCount(int theBundleValidationThreadCount) { - myBundleValidationThreadCount = theBundleValidationThreadCount; - return this; - } - public static ValidationOptions empty() { ValidationOptions retVal = ourEmpty; if (retVal == null) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 2dc92b860b5..dd63aeb98a2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -86,7 +86,6 @@ import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.RestfulServerUtils; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; -import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; @@ -1776,7 +1775,6 @@ public abstract class BaseHapiFhirResourceDao extends B } FhirValidator validator = getContext().newValidator(); - validator.setInterceptorBroadcaster(CompositeInterceptorBroadcaster.newCompositeBroadcaster(myInterceptorBroadcaster, theRequest)); validator.registerValidatorModule(getInstanceValidator()); validator.registerValidatorModule(new IdChecker(theMode)); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java index d733b4bce80..fba4248a897 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java @@ -16,7 +16,6 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParamModifier; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.validation.FhirValidator; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java index 33cbefd436f..0baa12f73d1 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java @@ -60,7 +60,6 @@ import ca.uhn.fhir.jpa.entity.TermValueSetConcept; import ca.uhn.fhir.jpa.interceptor.PerformanceTracingLoggingInterceptor; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc; import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc; import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4; @@ -93,8 +92,6 @@ import ca.uhn.fhir.util.ClasspathUtil; import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; -import org.hibernate.search.mapper.orm.Search; -import org.hibernate.search.mapper.orm.session.SearchSession; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.instance.model.api.IBaseResource; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java index d3a992782a7..ea39397a73a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyTest.java @@ -15,7 +15,6 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParamModifier; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.validation.FhirValidator; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java index 8164fd79a9a..6ac60fb6b98 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java @@ -49,7 +49,6 @@ import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSetConcept; import ca.uhn.fhir.jpa.interceptor.PerformanceTracingLoggingInterceptor; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; @@ -76,8 +75,6 @@ import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ValidationResult; import org.apache.commons.io.IOUtils; -import org.hibernate.search.mapper.orm.Search; -import org.hibernate.search.mapper.orm.session.SearchSession; import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/BaseValidatingInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/BaseValidatingInterceptor.java index e97b5854339..0c23ee9487d 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/BaseValidatingInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/BaseValidatingInterceptor.java @@ -32,7 +32,6 @@ import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.SingleValidationMessage; -import ca.uhn.fhir.validation.ValidationOptions; import ca.uhn.fhir.validation.ValidationResult; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.text.StrLookup; @@ -76,7 +75,6 @@ public abstract class BaseValidatingInterceptor extends ValidationResultEnric private List myValidatorModules; private FhirValidator myValidator; - private final ValidationOptions myValidationOptions = new ValidationOptions(); private void addResponseIssueHeader(RequestDetails theRequestDetails, SingleValidationMessage theNext) { // Perform any string substitutions from the message format @@ -117,7 +115,7 @@ public abstract class BaseValidatingInterceptor extends ValidationResultEnric } - abstract ValidationResult doValidate(FhirValidator theValidator, T theRequest, ValidationOptions theValidationOptions); + abstract ValidationResult doValidate(FhirValidator theValidator, T theRequest); /** * Fail the request by throwing an {@link UnprocessableEntityException} as a result of a validation failure. @@ -312,21 +310,22 @@ public abstract class BaseValidatingInterceptor extends ValidationResultEnric return null; } - FhirValidator validator; + FhirValidator fhirValidator; if (myValidator != null) { - validator = myValidator; + fhirValidator = myValidator; } else { - validator = theRequestDetails.getServer().getFhirContext().newValidator(); + // FIXME KHS this is our validator + fhirValidator = theRequestDetails.getServer().getFhirContext().newValidator(); if (myValidatorModules != null) { for (IValidatorModule next : myValidatorModules) { - validator.registerValidatorModule(next); + fhirValidator.registerValidatorModule(next); } } } ValidationResult validationResult; try { - validationResult = doValidate(validator, theRequest, myValidationOptions); + validationResult = doValidate(fhirValidator, theRequest); } catch (Exception e) { if (myIgnoreValidatorExceptions) { ourLog.warn("Validator threw an exception during validation", e); @@ -392,14 +391,6 @@ public abstract class BaseValidatingInterceptor extends ValidationResultEnric return validationResult; } - protected void setConcurrentBundleValidation(boolean theConcurrentBundleValidation) { - myValidationOptions.setConcurrentBundleValidation(theConcurrentBundleValidation); - } - - protected void setBundleValidationThreadCount(int theBundleValidationThreadCount) { - myValidationOptions.setBundleValidationThreadCount(theBundleValidationThreadCount); - } - private static class MyLookup extends StrLookup { private SingleValidationMessage myMessage; diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/RequestValidatingInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/RequestValidatingInterceptor.java index bdb17bc3362..25c035c8692 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/RequestValidatingInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/RequestValidatingInterceptor.java @@ -30,7 +30,6 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.method.ResourceParameter; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ResultSeverityEnum; -import ca.uhn.fhir.validation.ValidationOptions; import ca.uhn.fhir.validation.ValidationResult; import javax.servlet.http.HttpServletRequest; @@ -54,8 +53,8 @@ public class RequestValidatingInterceptor extends BaseValidatingInterceptor mySupportedCodeSystemsForExpansion; - private FhirValidator myVal; + private FhirValidator myFhirValidator; private ArrayList myValidConcepts; private Set myValidSystems = new HashSet<>(); private Map myStructureDefinitionMap = new HashMap<>(); @@ -136,7 +134,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { resource.setSubject(new Reference("#invalid-ref")); - ValidationResult output = myVal.validateWithResult(resource); + ValidationResult output = myFhirValidator.validateWithResult(resource); List nonInfo = logResultsAndReturnNonInformationalOnes(output); assertThat(nonInfo, hasSize(2)); } @@ -144,21 +142,20 @@ public class FhirInstanceValidatorR4Test extends BaseTest { @SuppressWarnings("unchecked") @BeforeEach public void before() { - myVal = ourCtx.newValidator(); - myVal.setValidateAgainstStandardSchema(false); - myVal.setValidateAgainstStandardSchematron(false); + myFhirValidator = ourCtx.newValidator(); + myFhirValidator.setValidateAgainstStandardSchema(false); + myFhirValidator.setValidateAgainstStandardSchematron(false); // This is only used if the validation is performed with validationOptions.isConcurrentBundleValidation = true - myVal.setExecutor(Executors.newFixedThreadPool(4)); + myFhirValidator.setExecutor(Executors.newFixedThreadPool(4)); IValidationSupport mockSupport = mock(IValidationSupport.class); when(mockSupport.getFhirContext()).thenReturn(ourCtx); ValidationSupportChain chain = new ValidationSupportChain(myDefaultValidationSupport, mockSupport, new InMemoryTerminologyServerValidationSupport(ourCtx), new CommonCodeSystemsTerminologyService(ourCtx), new SnapshotGeneratingValidationSupport(ourCtx)); myValidationSupport = new CachingValidationSupport(chain); - ourCtx.setValidationSupport(myValidationSupport); myInstanceVal = new FhirInstanceValidator(myValidationSupport); - myVal.registerValidatorModule(myInstanceVal); + myFhirValidator.registerValidatorModule(myInstanceVal); mySupportedCodeSystemsForExpansion = new HashMap<>(); @@ -530,7 +527,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { ourLog.info("Encoded: {}", encoded); - ValidationResult output = myVal.validateWithResult(encoded); + ValidationResult output = myFhirValidator.validateWithResult(encoded); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, errors.size()); assertEquals("The value '%%%2@()()' is not a valid Base64 value", errors.get(0).getMessage()); @@ -541,7 +538,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateBundleWithNoFullUrl() throws IOException { String encoded = loadResource("/r4/r4-caredove-bundle.json"); - ValidationResult output = myVal.validateWithResult(encoded); + ValidationResult output = myFhirValidator.validateWithResult(encoded); List errors = logResultsAndReturnNonInformationalOnes(output); errors = errors .stream() @@ -563,7 +560,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { ourLog.info("Encoded: {}", encoded); - ValidationResult output = myVal.validateWithResult(encoded); + ValidationResult output = myFhirValidator.validateWithResult(encoded); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size()); @@ -607,7 +604,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { t.setSystem(org.hl7.fhir.r4.model.ContactPoint.ContactPointSystem.URL); t.setValue("http://infoway-inforoute.ca"); - ValidationResult results = myVal.validateWithResult(p); + ValidationResult results = myFhirValidator.validateWithResult(p); List outcome = logResultsAndReturnNonInformationalOnes(results); assertThat(outcome, empty()); @@ -619,7 +616,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { @Test public void testExtensionUrlWithHl7Url() throws IOException { String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/bug872-ext-with-hl7-url.json"), Charsets.UTF_8); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List nonInfo = logResultsAndReturnNonInformationalOnes(output); assertThat(nonInfo, empty()); } @@ -634,7 +631,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { @Test public void testLargeBase64() throws IOException { String input = IOUtils.toString(FhirInstanceValidatorR4Test.class.getResourceAsStream("/r4/diagnosticreport-example-gingival-mass.json"), Constants.CHARSET_UTF8); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnAll(output); assertEquals(1, errors.size()); assertEquals("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/report-codes (http://hl7.org/fhir/ValueSet/report-codes), and a coding is recommended to come from this value set) (codes = http://loinc.org#1-8)", errors.get(0).getMessage()); @@ -650,7 +647,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { int passes = 1; for (int i = 0; i < passes; i++) { ourLog.info("Pass {}", i + 1); - output = myVal.validateWithResult(input); + output = myFhirValidator.validateWithResult(input); } long delay = System.currentTimeMillis() - start; @@ -687,7 +684,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { ourLog.info("Validating {}", next.getId()); ourLog.trace(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(next)); - ValidationResult output = myVal.validateWithResult(next); + ValidationResult output = myFhirValidator.validateWithResult(next); List results = logResultsAndReturnAll(output); // This isn't a validator problem but a definition problem.. it should get fixed at some point and @@ -715,7 +712,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateBundleWithNoType() throws Exception { String vsContents = loadResource("/r4/bundle-with-no-type.json"); - ValidationResult output = myVal.validateWithResult(vsContents); + ValidationResult output = myFhirValidator.validateWithResult(vsContents); logResultsAndReturnNonInformationalOnes(output); assertThat(output.getMessages().toString(), containsString("Bundle.type: minimum required = 1, but only found 0")); } @@ -732,7 +729,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { "\"name\":[ {\"family\":\"bar\"} ]" + "}"; - ValidationResult output = myVal.validateWithResult(patient); + ValidationResult output = myFhirValidator.validateWithResult(patient); logResultsAndReturnNonInformationalOnes(output); assertThat(output.getMessages().toString(), containsString("Error parsing JSON source: Duplicated property name")); } @@ -760,7 +757,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { // bool = (BooleanType) fpOutput.get(0); // assertTrue(bool.getValue()); - ValidationResult output = myVal.validateWithResult(inputString); + ValidationResult output = myFhirValidator.validateWithResult(inputString); List errors = logResultsAndReturnNonInformationalOnes(output); assertThat(errors, empty()); @@ -771,7 +768,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateDocument() throws Exception { String vsContents = loadResource("/sample-document.xml"); - ValidationResult output = myVal.validateWithResult(vsContents); + ValidationResult output = myFhirValidator.validateWithResult(vsContents); logResultsAndReturnNonInformationalOnes(output); assertTrue(output.isSuccessful()); } @@ -823,7 +820,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateQuestionnaireResponse() throws IOException { String input = loadResource("/qr_jon.xml"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); logResultsAndReturnAll(output); assertThat(output.getMessages().toString(), containsString("Items not of type group should not have items - Item with linkId 5.1 of type BOOLEAN has 1 item(s)")); @@ -840,7 +837,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " \"id\":\"123\"" + "}"; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertEquals(0, output.getMessages().size(), output.toString()); } @@ -857,7 +854,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { "\"foo\":\"123\"" + "}"; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertEquals(1, output.getMessages().size(), output.toString()); ourLog.info(output.getMessages().get(0).getLocationString()); ourLog.info(output.getMessages().get(0).getMessage()); @@ -876,7 +873,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateRawJsonResourceFromExamples() throws Exception { String input = loadResource("/testscript-search.json"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); logResultsAndReturnNonInformationalOnes(output); // assertEquals(output.toString(), 1, output.getMessages().size()); // ourLog.info(output.getMessages().get(0).getLocationString()); @@ -912,7 +909,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { * } */ - ValidationResult output = myVal.validateWithResult(encoded); + ValidationResult output = myFhirValidator.validateWithResult(encoded); assertEquals(1, output.getMessages().size(), output.toString()); assertEquals("Unknown extension http://hl7.org/fhir/v3/ethnicity", output.getMessages().get(0).getMessage()); @@ -947,7 +944,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { */ myInstanceVal.setAnyExtensionsAllowed(false); - ValidationResult output = myVal.validateWithResult(encoded); + ValidationResult output = myFhirValidator.validateWithResult(encoded); assertEquals(1, output.getMessages().size(), output.toString()); assertEquals("The extension http://hl7.org/fhir/v3/ethnicity is unknown, and not allowed here", output.getMessages().get(0).getMessage()); @@ -964,7 +961,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " " + ""; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertEquals(0, output.getMessages().size(), output.toString()); } @@ -980,7 +977,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { "" + ""; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertEquals(1, output.getMessages().size(), output.toString()); ourLog.info(output.getMessages().get(0).getLocationString()); ourLog.info(output.getMessages().get(0).getMessage()); @@ -1000,7 +997,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { "" + ""; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List messages = logResultsAndReturnNonInformationalOnes(output); assertEquals(3, messages.size(), output.toString()); assertThat(messages.get(0).getMessage(), containsString("Element must have some content")); @@ -1035,7 +1032,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " \n" + " "; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List res = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, res.size(), output.toString()); assertEquals("A code with no system has no defined meaning. A system should be provided", output.getMessages().get(0).getMessage()); @@ -1050,7 +1047,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { p.getText().setDiv(new XhtmlNode().setValue("
AA
")).setStatus(Narrative.NarrativeStatus.GENERATED); p.getManagingOrganization().setDisplay("HELLO"); - ValidationResult output = myVal.validateWithResult(p); + ValidationResult output = myFhirValidator.validateWithResult(p); List nonInfo = logResultsAndReturnNonInformationalOnes(output); assertThat(nonInfo, empty()); } @@ -1065,7 +1062,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { p.getManagingOrganization().getIdentifier().setSystem("http://acme.org"); p.getManagingOrganization().getIdentifier().setValue("foo"); - ValidationResult output = myVal.validateWithResult(p); + ValidationResult output = myFhirValidator.validateWithResult(p); List nonInfo = logResultsAndReturnNonInformationalOnes(output); assertThat(nonInfo, empty()); } @@ -1085,7 +1082,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { rp.getPatient().setReference("Patient/1"); rp.addRelationship().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/v2-0131").setCode("C"); - ValidationResult results = myVal.validateWithResult(rp); + ValidationResult results = myFhirValidator.validateWithResult(rp); List outcome = logResultsAndReturnNonInformationalOnes(results); assertThat(outcome, empty()); @@ -1096,7 +1093,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { rp.getPatient().setReference("Patient/1"); rp.addRelationship().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/v2-0131").setCode("GAGAGAGA"); - results = myVal.validateWithResult(rp); + results = myFhirValidator.validateWithResult(rp); outcome = logResultsAndReturnNonInformationalOnes(results); assertThat(outcome, not(empty())); @@ -1115,7 +1112,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345"); myInstanceVal.setValidationSupport(myValidationSupport); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnAll(output); assertEquals(ResultSeverityEnum.ERROR, errors.get(0).getSeverity()); @@ -1136,7 +1133,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345"); myInstanceVal.setValidationSupport(myValidationSupport); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertThat(errors.toString(), containsString("Observation.subject: minimum required = 1, but only found 0")); @@ -1156,7 +1153,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); myInstanceVal.setValidationSupport(myValidationSupport); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, errors.size()); @@ -1173,7 +1170,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345"); input.setValue(new StringType("AAA")); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertThat(output.getMessages().size(), greaterThan(0)); assertEquals("Observation.status: minimum required = 1, but only found 0 (from http://hl7.org/fhir/StructureDefinition/Observation)", output.getMessages().get(0).getMessage()); @@ -1189,7 +1186,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(input)); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); assertEquals(output.getMessages().size(), 0); } @@ -1206,7 +1203,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " \n" + " \n" + ""; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); logResultsAndReturnAll(output); assertEquals( "The value provided ('notvalidcode') is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.0.1 (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')", @@ -1236,7 +1233,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " ]" + "}"; ourLog.info(input); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); logResultsAndReturnAll(output); assertEquals( "", @@ -1253,7 +1250,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size(), errors.toString()); @@ -1270,7 +1267,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); input.getCode().addCoding().setSystem("http://acme.org").setCode("9988877"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnAll(output); assertThat(errors.toString(), errors.size(), greaterThan(0)); assertEquals("Unknown code for 'http://acme.org#9988877'", errors.get(0).getMessage()); @@ -1288,7 +1285,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size(), errors.toString()); } @@ -1308,7 +1305,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); input.getCode().addCoding().setSystem("http://loinc.org").setCode("1234"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, errors.size()); assertEquals("Unknown code for 'http://loinc.org#1234'", errors.get(0).getMessage()); @@ -1325,7 +1322,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { input.setStatus(ObservationStatus.FINAL); input.getCode().addCoding().setSystem("http://acme.org").setCode("12345"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnAll(output); assertEquals(0, errors.size(), errors.toString()); } @@ -1337,7 +1334,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { p.getText().setDiv(new XhtmlNode().setValue("
AA
")).setStatus(Narrative.NarrativeStatus.GENERATED); p.addIdentifier().setSystem("http://example.com/").setValue("12345").getType().addCoding().setSystem("http://example.com/foo/bar").setCode("bar"); - ValidationResult output = myVal.validateWithResult(p); + ValidationResult output = myFhirValidator.validateWithResult(p); List all = logResultsAndReturnAll(output); assertEquals(1, all.size()); assertEquals("Patient.identifier[0].type", all.get(0).getLocationString()); @@ -1352,13 +1349,13 @@ public class FhirInstanceValidatorR4Test extends BaseTest { addValidConcept("http://loinc.org", "8310-5"); Observation input = loadResource(ourCtx, Observation.class, "/r4/observation-with-body-temp-ucum.json"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List all = logResultsAndReturnNonInformationalOnes(output); assertThat(all, empty()); // Change the unit to something not supported input.getValueQuantity().setCode("Heck"); - output = myVal.validateWithResult(input); + output = myFhirValidator.validateWithResult(input); all = logResultsAndReturnNonInformationalOnes(output); assertEquals(2, all.size()); assertThat(all.get(0).getMessage(), containsString("Validation failed for 'http://unitsofmeasure.org#Heck'")); @@ -1375,7 +1372,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { o.addPerformer(new Reference(p1)); o.addPerformer(new Reference(p2)); - ValidationResult output = myVal.validateWithResult(o); + ValidationResult output = myFhirValidator.validateWithResult(o); List valMessages = logResultsAndReturnAll(output); for (SingleValidationMessage msg : valMessages) { assertThat(msg.getMessage(), not(containsString("have a performer"))); @@ -1395,7 +1392,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { .setSystem("http://terminology.hl7.org/CodeSystem/v2-0203") .setCode("MR"); - ValidationResult output = myVal.validateWithResult(patient); + ValidationResult output = myFhirValidator.validateWithResult(patient); List all = logResultsAndReturnAll(output); assertEquals(0, all.size()); } @@ -1408,7 +1405,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class); when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); myInstanceVal.setValidatorResourceFetcher(resourceFetcher); - myVal.validateWithResult(encoded); + myFhirValidator.validateWithResult(encoded); verify(resourceFetcher, times(15)).resolveURL(any(), any(), anyString(), anyString(), anyString()); verify(resourceFetcher, times(12)).validationPolicy(any(), any(), anyString(), anyString()); @@ -1420,7 +1417,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { public void testValidateStructureDefinition() throws IOException { String input = loadResource("/sdc-questionnaire.profile.xml"); - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); logResultsAndReturnAll(output); assertEquals(3, output.getMessages().size(), output.toString()); @@ -1439,7 +1436,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " \"currency\": \"USD\"\n" + " }\n" + "}"; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size(), errors.toString()); @@ -1457,7 +1454,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { " \"currency\": \"BLAH\"\n" + " }\n" + "}"; - ValidationResult output = myVal.validateWithResult(input); + ValidationResult output = myFhirValidator.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, errors.size(), errors.toString()); assertThat(errors.get(0).getMessage(), containsString("The value provided ('BLAH') is not in the value set http://hl7.org/fhir/ValueSet/currencies")); @@ -1477,7 +1474,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { .setText("This is text") .setAuthor(new Reference("Patient/123")); - ValidationResult output = myVal.validateWithResult(allergy); + ValidationResult output = myFhirValidator.validateWithResult(allergy); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size(), errors.toString()); @@ -1496,7 +1493,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { .setText("This is text") .setAuthor(new Reference("CodeSystems/123")); - ValidationResult output = myVal.validateWithResult(allergy); + ValidationResult output = myFhirValidator.validateWithResult(allergy); List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(0, errors.size(), errors.toString()); assertThat(errors.get(0).getMessage(), containsString("The value provided ('BLAH') is not in the value set http://hl7.org/fhir/ValueSet/currencies")); @@ -1516,30 +1513,27 @@ public class FhirInstanceValidatorR4Test extends BaseTest { Bundle bundle = buildBundle(entriesCount, false); assertThat(bundle.getEntry(), hasSize(entriesCount)); - ValidationOptions validationOptions = buildValidationOptions(); - // Run once to exclude initialization from time - myVal.validateWithResult(bundle, validationOptions); + try { + myFhirValidator.setConcurrentBundleValidation(true); + myFhirValidator.setBundleValidationThreadCount(4); + // Run once to exclude initialization from time + myFhirValidator.validateWithResult(bundle); - // execute - StopWatch stopwatch = new StopWatch(); - ValidationResult output = myVal.validateWithResult(bundle, validationOptions); - ourLog.info("Validation time: {}", stopwatch); - - // validate - List all = logResultsAndReturnErrorOnes(output); - assertThat(output.getMessages(), hasSize(entriesCount * 2)); - // This assert proves that we did a multi-threaded validation since the outer bundle fails validation - // due to lack of unique fullUrl values on the entries. If you setConcurrentBundleValidation(false) - // above this test will fail. - assertEquals(0, all.size(), all.toString()); - } - - @NotNull - private ValidationOptions buildValidationOptions() { - ValidationOptions validationOptions = new ValidationOptions(); - validationOptions.setConcurrentBundleValidation(true); - validationOptions.setBundleValidationThreadCount(4); - return validationOptions; + // execute + StopWatch stopwatch = new StopWatch(); + ValidationResult output = myFhirValidator.validateWithResult(bundle); + ourLog.info("Validation time: {}", stopwatch); + // validate + List all = logResultsAndReturnErrorOnes(output); + assertThat(output.getMessages(), hasSize(entriesCount * 2)); + // This assert proves that we did a multi-threaded validation since the outer bundle fails validation + // due to lack of unique fullUrl values on the entries. If you setConcurrentBundleValidation(false) + // above this test will fail. + assertEquals(0, all.size(), all.toString()); + } finally { + myFhirValidator.setConcurrentBundleValidation(false); + myFhirValidator.setBundleValidationThreadCount(FhirValidator.DEFAULT_BUNDLE_VALIDATION_THREADCOUNT); + } } private Bundle buildBundle(int theSize, boolean theValidBundle) throws IOException { diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/QuestionnaireResponseValidatorR5Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/QuestionnaireResponseValidatorR5Test.java index 9540e9fe168..5564e86d538 100644 --- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/QuestionnaireResponseValidatorR5Test.java +++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/QuestionnaireResponseValidatorR5Test.java @@ -4,7 +4,6 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.DefaultProfileValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.parser.IParser; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.SingleValidationMessage;