From f4cf4bf54afe5d59b9e6151caaf01ec8aeef307d Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Jan 2021 17:09:31 -0500 Subject: [PATCH] Survivorship --- .../jpa/mdm/config/MdmConsumerConfig.java | 5 +++++ .../mdm/svc/GoldenResourceMergerSvcImpl.java | 2 +- .../fhir/jpa/mdm/svc/MdmEidUpdateService.java | 6 ++++-- .../jpa/mdm/svc/MdmSurvivorshipSvcImpl.java | 13 ++++++++++++ .../ca/uhn/fhir/mdm/api/IMdmSettings.java | 2 ++ .../fhir/mdm/api/IMdmSurvivorshipService.java | 20 +++++++++++++++++++ .../fhir/mdm/provider/BaseMdmProvider.java | 1 - .../mdm/provider/MdmControllerHelper.java | 1 + .../fhir/mdm/rules/config/MdmSettings.java | 10 ++++++++++ .../fhir/mdm/util/GoldenResourceHelper.java | 19 +++++------------- 10 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java create mode 100644 hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSurvivorshipService.java diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java index a80f2e5f1c5..204b27e69f1 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.mdm.config; */ import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.mdm.svc.MdmSurvivorshipSvcImpl; import ca.uhn.fhir.mdm.api.IMdmControllerSvc; import ca.uhn.fhir.mdm.api.IMdmExpungeSvc; import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc; @@ -29,6 +30,7 @@ import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc; import ca.uhn.fhir.mdm.api.IMdmMatchFinderSvc; import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.provider.MdmControllerHelper; import ca.uhn.fhir.mdm.provider.MdmProviderLoader; @@ -77,6 +79,9 @@ public class MdmConsumerConfig { return new MdmStorageInterceptor(); } + @Bean + IMdmSurvivorshipService mdmSurvivorshipService() { return new MdmSurvivorshipSvcImpl(); } + @Bean MdmQueueConsumerLoader mdmQueueConsumerLoader() { return new MdmQueueConsumerLoader(); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java index 09361f0cde2..f4e3c4e9eec 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java @@ -66,7 +66,7 @@ public class GoldenResourceMergerSvcImpl implements IGoldenResourceMergerSvc { String resourceType = theMdmTransactionContext.getResourceType(); //Merge attributes, to be determined when survivorship is solved. - myGoldenResourceHelper.mergeFields(theFromGoldenResource, theToGoldenResource); + myGoldenResourceHelper.mergeFields(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext); //Merge the links from the FROM to the TO resource. Clean up dangling links. mergeGoldenResourceLinks(theFromGoldenResource, theToGoldenResource, toGoldenResourcePid, theMdmTransactionContext); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index 05ba75fbf71..4c6c5de1426 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.mdm.svc; * #L% */ +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.api.IMdmLinkSvc; @@ -61,13 +62,14 @@ public class MdmEidUpdateService { private MdmLinkDaoSvc myMdmLinkDaoSvc; @Autowired private IMdmSettings myMdmSettings; + @Autowired + private IMdmSurvivorshipService myMdmSurvivorshipService; void handleMdmUpdate(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theResource); if (updateContext.isRemainsMatchedToSameGoldenResource()) { // Copy over any new external EIDs which don't already exist. - // TODO NG - Eventually this call will use terser to clone data in, once the surviorship rules for copying data will be confirmed - // myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext); + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext); if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) { //update to patient that uses internal EIDs only. myMdmLinkSvc.updateLink(updateContext.getMatchedGoldenResource(), theResource, theMatchedGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java new file mode 100644 index 00000000000..0768fcc2f4f --- /dev/null +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java @@ -0,0 +1,13 @@ +package ca.uhn.fhir.jpa.mdm.svc; + +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; +import ca.uhn.fhir.mdm.model.MdmTransactionContext; +import org.hl7.fhir.instance.model.api.IBase; + +public class MdmSurvivorshipSvcImpl implements IMdmSurvivorshipService { + + @Override + public void applySurvivorshipRulesToGoldenResource(T theTargetResource, T theGoldenResource, MdmTransactionContext theMdmTransactionContext) { + // survivorship logic placeholder + } +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java index 025e3a6cfad..c0e0100ae2f 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSettings.java @@ -44,6 +44,8 @@ public interface IMdmSettings { String getRuleVersion(); + String getSurvivorshipRules(); + default boolean isSupportedMdmType(String theResourceName) { return getMdmRules().getMdmTypes().contains(theResourceName); } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSurvivorshipService.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSurvivorshipService.java new file mode 100644 index 00000000000..f0b152f8421 --- /dev/null +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/api/IMdmSurvivorshipService.java @@ -0,0 +1,20 @@ +package ca.uhn.fhir.mdm.api; + +import ca.uhn.fhir.mdm.model.MdmTransactionContext; +import org.hl7.fhir.instance.model.api.IBase; + +/** + * Service that applies survivorship rules on target and golden resources. + */ +public interface IMdmSurvivorshipService { + + /** + * Applies survivorship rules to merge fields from the specified target resource to the golden resource + * + * @param theTargetResource Target resource to merge fields from + * @param theGoldenResource Golden resource to merge fields into + * @param theMdmTransactionContext Current transaction context + * @param Resource type to apply the survivorship rules to + */ + void applySurvivorshipRulesToGoldenResource(T theTargetResource, T theGoldenResource, MdmTransactionContext theMdmTransactionContext); +} diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/BaseMdmProvider.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/BaseMdmProvider.java index 1ce676be837..e9bdb713959 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/BaseMdmProvider.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/BaseMdmProvider.java @@ -58,7 +58,6 @@ public abstract class BaseMdmProvider { } protected void validateUpdateLinkParameters(IPrimitiveType theGoldenResourceId, IPrimitiveType theResourceId, IPrimitiveType theMatchResult) { - // TODO NG - Add validation to check that types are the same? - This is done deeper in the code, perhaps move here? validateNotNull(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId); validateNotNull(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theResourceId); validateNotNull(ProviderConstants.MDM_UPDATE_LINK_MATCH_RESULT, theMatchResult); diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmControllerHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmControllerHelper.java index 57fd1c74769..cf1c301dd7e 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmControllerHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/provider/MdmControllerHelper.java @@ -37,6 +37,7 @@ import org.springframework.stereotype.Service; @Service public class MdmControllerHelper { + private final FhirContext myFhirContext; private final IResourceLoader myResourceLoader; private final IMdmSettings myMdmSettings; diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmSettings.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmSettings.java index c81570a6855..5fe71b9abd6 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmSettings.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmSettings.java @@ -36,6 +36,7 @@ public class MdmSettings implements IMdmSettings { private boolean myEnabled; private int myConcurrentConsumers = MDM_DEFAULT_CONCURRENT_CONSUMERS; private String myScriptText; + private String mySurvivorshipRules; private MdmRulesJson myMdmRules; private boolean myPreventEidUpdates; @@ -116,4 +117,13 @@ public class MdmSettings implements IMdmSettings { myPreventMultipleEids = thePreventMultipleEids; return this; } + + @Override + public String getSurvivorshipRules() { + return mySurvivorshipRules; + } + + public void setSurvivorshipRules(String theSurvivorshipRules) { + mySurvivorshipRules = theSurvivorshipRules; + } } diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java index 59d76cdbdfc..07f9d93561b 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/GoldenResourceHelper.java @@ -27,6 +27,7 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.fhirpath.IFhirPath; import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.MdmTransactionContext; @@ -59,7 +60,8 @@ public class GoldenResourceHelper { private IMdmSettings myMdmSettings; @Autowired private EIDHelper myEIDHelper; - + @Autowired + private IMdmSurvivorshipService myMdmSurvivorshipService; private final FhirContext myFhirContext; @@ -237,20 +239,9 @@ public class GoldenResourceHelper { } } - public void mergeFields(IBaseResource theFromGoldenResource, IBaseResource theToGoldenResource) { - // TODO NG - Revisit when merge rules are defined + public void mergeFields(IBaseResource theFromGoldenResource, IBaseResource theToGoldenResource, MdmTransactionContext theMdmTransactionContext) { TerserUtil.cloneCompositeField(myFhirContext, theFromGoldenResource, theToGoldenResource, FIELD_NAME_IDENTIFIER); - -// switch (myFhirContext.getVersion().getVersion()) { -// case R4: -// mergeR4PersonFields(theFromGoldenResource, theToGoldenResource); -// break; -// case DSTU3: -// mergeDstu3PersonFields(theFromGoldenResource, theToGoldenResource); -// break; -// default: -// throw new UnsupportedOperationException("Version not supported: " + myFhirContext.getVersion().getVersion()); -// } + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext); } /**