4934 validation doesn't consider loaded ig immediately (#4935)

* Unit tests for validation after install and uninstall IG

* Fix validation result cached after install and uninstall IG

* Fix validation result cached after install and uninstall IG - updated changelog

* Fix validation result cached after uninstalling IG - updated changelog

* Fix validation result cached after uninstalling IG - fixed unit tests

* Fix validation result cached after uninstalling IG - fixed changelog

* Fix validation result cached after uninstalling IG - test fixes
This commit is contained in:
volodymyr-korzh 2023-05-30 12:02:14 -06:00 committed by GitHub
parent 34f4c90eb9
commit 31ae8d8f27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 3 deletions

View File

@ -0,0 +1,4 @@
---
type: fix
issue: 4934
title: "Previously, installing or uninstalling an implementation guide does not refresh the validation cache. This problem has been fixed."

View File

@ -129,7 +129,9 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
@Override @Override
public PackageDeleteOutcomeJson uninstall(PackageInstallationSpec theInstallationSpec) { public PackageDeleteOutcomeJson uninstall(PackageInstallationSpec theInstallationSpec) {
return myPackageCacheManager.uninstallPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion()); PackageDeleteOutcomeJson outcome = myPackageCacheManager.uninstallPackage(theInstallationSpec.getName(), theInstallationSpec.getVersion());
validationSupport.invalidateCaches();
return outcome;
} }
/** /**
@ -178,6 +180,8 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
mySearchParamRegistryController.refreshCacheIfNecessary(); mySearchParamRegistryController.refreshCacheIfNecessary();
} }
validationSupport.invalidateCaches();
} catch (IOException e) { } catch (IOException e) {
throw new ImplementationGuideInstallationException(Msg.code(1285) + "Could not load NPM package " + theInstallationSpec.getName() + "#" + theInstallationSpec.getVersion(), e); throw new ImplementationGuideInstallationException(Msg.code(1285) + "Could not load NPM package " + theInstallationSpec.getName() + "#" + theInstallationSpec.getVersion(), e);
} }

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.packages;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
@ -63,6 +64,8 @@ public class PackageInstallerSvcImplTest {
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Mock @Mock
private IFhirResourceDao<CodeSystem> myCodeSystemDao; private IFhirResourceDao<CodeSystem> myCodeSystemDao;
@Mock
private IValidationSupport myIValidationSupport;
@Spy @Spy
private FhirContext myCtx = FhirContext.forR4Cached(); private FhirContext myCtx = FhirContext.forR4Cached();
@Spy @Spy

View File

@ -28,6 +28,7 @@ import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.test.utilities.ProxyUtil; import ca.uhn.fhir.test.utilities.ProxyUtil;
import ca.uhn.fhir.util.ClasspathUtil; import ca.uhn.fhir.util.ClasspathUtil;
import ca.uhn.fhir.util.JsonUtil; import ca.uhn.fhir.util.JsonUtil;
import ca.uhn.fhir.validation.ValidationResult;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
@ -35,7 +36,9 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.ImplementationGuide; import org.hl7.fhir.r4.model.ImplementationGuide;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.PractitionerRole; import org.hl7.fhir.r4.model.PractitionerRole;
import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.SearchParameter;
@ -165,6 +168,47 @@ public class NpmR4Test extends BaseJpaR4Test {
myPackageInstallerSvc.install(spec); myPackageInstallerSvc.install(spec);
} }
@Test
public void testValidationCache_whenInstallingIG_isRefreshed() {
Patient patient = new Patient();
patient.setMeta(new Meta().addProfile("https://fhir.nhs.uk/R4/StructureDefinition/UKCore-Patient"));
ValidationResult validationResultBefore = validateWithResult(patient);
assertFalse(validationResultBefore.isSuccessful());
byte[] bytes = ClasspathUtil.loadResourceAsByteArray("/packages/UK.Core.r4-1.1.0.tgz");
myFakeNpmServlet.responses.put("/UK.Core.r4/1.1.0", bytes);
PackageInstallationSpec spec = new PackageInstallationSpec().setName("UK.Core.r4").setVersion("1.1.0")
.setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);
myPackageInstallerSvc.install(spec);
ValidationResult validationResultAfter = validateWithResult(patient);
assertTrue(validationResultAfter.isSuccessful());
}
@Test
public void testValidationCache_whenUnInstallingIG_isRefreshed() {
byte[] bytes = ClasspathUtil.loadResourceAsByteArray("/packages/UK.Core.r4-1.1.0.tgz");
myFakeNpmServlet.responses.put("/UK.Core.r4/1.1.0", bytes);
PackageInstallationSpec spec = new PackageInstallationSpec().setName("UK.Core.r4").setVersion("1.1.0")
.setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);
myPackageInstallerSvc.install(spec);
Patient patient = new Patient();
patient.setMeta(new Meta().addProfile("https://fhir.nhs.uk/R4/StructureDefinition/UKCore-Patient"));
ValidationResult validationResultBefore = validateWithResult(patient);
assertTrue(validationResultBefore.isSuccessful());
myPackageInstallerSvc.uninstall(spec);
ValidationResult validationResultAfter = validateWithResult(patient);
assertFalse(validationResultAfter.isSuccessful());
}
@Test @Test
public void testCacheDstu3Package() throws Exception { public void testCacheDstu3Package() throws Exception {

View File

@ -625,13 +625,16 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
return myTxManager; return myTxManager;
} }
protected void validate(IBaseResource theResource) { protected ValidationResult validateWithResult(IBaseResource theResource) {
FhirValidator validatorModule = myFhirContext.newValidator(); FhirValidator validatorModule = myFhirContext.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport); FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore); instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
instanceValidator.setValidatorPolicyAdvisor(new ValidationPolicyAdvisor()); instanceValidator.setValidatorPolicyAdvisor(new ValidationPolicyAdvisor());
validatorModule.registerValidatorModule(instanceValidator); validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource); return validatorModule.validateWithResult(theResource);
}
protected void validate(IBaseResource theResource) {
ValidationResult result = validateWithResult(theResource);
if (!result.isSuccessful()) { if (!result.isSuccessful()) {
fail(myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome())); fail(myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
} }