Survivorship

This commit is contained in:
Nick 2021-01-04 17:09:31 -05:00
parent 86f254cd66
commit f4cf4bf54a
10 changed files with 61 additions and 18 deletions

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.mdm.config;
*/ */
import ca.uhn.fhir.context.FhirContext; 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.IMdmControllerSvc;
import ca.uhn.fhir.mdm.api.IMdmExpungeSvc; import ca.uhn.fhir.mdm.api.IMdmExpungeSvc;
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc; 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.IMdmMatchFinderSvc;
import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc;
import ca.uhn.fhir.mdm.api.IMdmSettings; 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.log.Logs;
import ca.uhn.fhir.mdm.provider.MdmControllerHelper; import ca.uhn.fhir.mdm.provider.MdmControllerHelper;
import ca.uhn.fhir.mdm.provider.MdmProviderLoader; import ca.uhn.fhir.mdm.provider.MdmProviderLoader;
@ -77,6 +79,9 @@ public class MdmConsumerConfig {
return new MdmStorageInterceptor(); return new MdmStorageInterceptor();
} }
@Bean
IMdmSurvivorshipService mdmSurvivorshipService() { return new MdmSurvivorshipSvcImpl(); }
@Bean @Bean
MdmQueueConsumerLoader mdmQueueConsumerLoader() { MdmQueueConsumerLoader mdmQueueConsumerLoader() {
return new MdmQueueConsumerLoader(); return new MdmQueueConsumerLoader();

View File

@ -66,7 +66,7 @@ public class GoldenResourceMergerSvcImpl implements IGoldenResourceMergerSvc {
String resourceType = theMdmTransactionContext.getResourceType(); String resourceType = theMdmTransactionContext.getResourceType();
//Merge attributes, to be determined when survivorship is solved. //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. //Merge the links from the FROM to the TO resource. Clean up dangling links.
mergeGoldenResourceLinks(theFromGoldenResource, theToGoldenResource, toGoldenResourcePid, theMdmTransactionContext); mergeGoldenResourceLinks(theFromGoldenResource, theToGoldenResource, toGoldenResourcePid, theMdmTransactionContext);

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.mdm.svc;
* #L% * #L%
*/ */
import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
import ca.uhn.fhir.mdm.api.IMdmLinkSvc; import ca.uhn.fhir.mdm.api.IMdmLinkSvc;
@ -61,13 +62,14 @@ public class MdmEidUpdateService {
private MdmLinkDaoSvc myMdmLinkDaoSvc; private MdmLinkDaoSvc myMdmLinkDaoSvc;
@Autowired @Autowired
private IMdmSettings myMdmSettings; private IMdmSettings myMdmSettings;
@Autowired
private IMdmSurvivorshipService myMdmSurvivorshipService;
void handleMdmUpdate(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { void handleMdmUpdate(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) {
MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theResource); MdmUpdateContext updateContext = new MdmUpdateContext(theMatchedGoldenResourceCandidate, theResource);
if (updateContext.isRemainsMatchedToSameGoldenResource()) { if (updateContext.isRemainsMatchedToSameGoldenResource()) {
// Copy over any new external EIDs which don't already exist. // 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 myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
// myPersonHelper.updatePersonFromUpdatedEmpiTarget(updateContext.getMatchedPerson(), theResource, theEmpiTransactionContext);
if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) { if (!updateContext.isIncomingResourceHasAnEid() || updateContext.isHasEidsInCommon()) {
//update to patient that uses internal EIDs only. //update to patient that uses internal EIDs only.
myMdmLinkSvc.updateLink(updateContext.getMatchedGoldenResource(), theResource, theMatchedGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); myMdmLinkSvc.updateLink(updateContext.getMatchedGoldenResource(), theResource, theMatchedGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext);

View File

@ -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 <T extends IBase> void applySurvivorshipRulesToGoldenResource(T theTargetResource, T theGoldenResource, MdmTransactionContext theMdmTransactionContext) {
// survivorship logic placeholder
}
}

View File

@ -44,6 +44,8 @@ public interface IMdmSettings {
String getRuleVersion(); String getRuleVersion();
String getSurvivorshipRules();
default boolean isSupportedMdmType(String theResourceName) { default boolean isSupportedMdmType(String theResourceName) {
return getMdmRules().getMdmTypes().contains(theResourceName); return getMdmRules().getMdmTypes().contains(theResourceName);
} }

View File

@ -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 <T> Resource type to apply the survivorship rules to
*/
<T extends IBase> void applySurvivorshipRulesToGoldenResource(T theTargetResource, T theGoldenResource, MdmTransactionContext theMdmTransactionContext);
}

View File

@ -58,7 +58,6 @@ public abstract class BaseMdmProvider {
} }
protected void validateUpdateLinkParameters(IPrimitiveType<String> theGoldenResourceId, IPrimitiveType<String> theResourceId, IPrimitiveType<String> theMatchResult) { protected void validateUpdateLinkParameters(IPrimitiveType<String> theGoldenResourceId, IPrimitiveType<String> theResourceId, IPrimitiveType<String> 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_GOLDEN_RESOURCE_ID, theGoldenResourceId);
validateNotNull(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theResourceId); validateNotNull(ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theResourceId);
validateNotNull(ProviderConstants.MDM_UPDATE_LINK_MATCH_RESULT, theMatchResult); validateNotNull(ProviderConstants.MDM_UPDATE_LINK_MATCH_RESULT, theMatchResult);

View File

@ -37,6 +37,7 @@ import org.springframework.stereotype.Service;
@Service @Service
public class MdmControllerHelper { public class MdmControllerHelper {
private final FhirContext myFhirContext; private final FhirContext myFhirContext;
private final IResourceLoader myResourceLoader; private final IResourceLoader myResourceLoader;
private final IMdmSettings myMdmSettings; private final IMdmSettings myMdmSettings;

View File

@ -36,6 +36,7 @@ public class MdmSettings implements IMdmSettings {
private boolean myEnabled; private boolean myEnabled;
private int myConcurrentConsumers = MDM_DEFAULT_CONCURRENT_CONSUMERS; private int myConcurrentConsumers = MDM_DEFAULT_CONCURRENT_CONSUMERS;
private String myScriptText; private String myScriptText;
private String mySurvivorshipRules;
private MdmRulesJson myMdmRules; private MdmRulesJson myMdmRules;
private boolean myPreventEidUpdates; private boolean myPreventEidUpdates;
@ -116,4 +117,13 @@ public class MdmSettings implements IMdmSettings {
myPreventMultipleEids = thePreventMultipleEids; myPreventMultipleEids = thePreventMultipleEids;
return this; return this;
} }
@Override
public String getSurvivorshipRules() {
return mySurvivorshipRules;
}
public void setSurvivorshipRules(String theSurvivorshipRules) {
mySurvivorshipRules = theSurvivorshipRules;
}
} }

View File

@ -27,6 +27,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.fhirpath.IFhirPath; import ca.uhn.fhir.fhirpath.IFhirPath;
import ca.uhn.fhir.mdm.api.IMdmSettings; 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.log.Logs;
import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.CanonicalEID;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
@ -59,7 +60,8 @@ public class GoldenResourceHelper {
private IMdmSettings myMdmSettings; private IMdmSettings myMdmSettings;
@Autowired @Autowired
private EIDHelper myEIDHelper; private EIDHelper myEIDHelper;
@Autowired
private IMdmSurvivorshipService myMdmSurvivorshipService;
private final FhirContext myFhirContext; private final FhirContext myFhirContext;
@ -237,20 +239,9 @@ public class GoldenResourceHelper {
} }
} }
public void mergeFields(IBaseResource theFromGoldenResource, IBaseResource theToGoldenResource) { public void mergeFields(IBaseResource theFromGoldenResource, IBaseResource theToGoldenResource, MdmTransactionContext theMdmTransactionContext) {
// TODO NG - Revisit when merge rules are defined
TerserUtil.cloneCompositeField(myFhirContext, theFromGoldenResource, theToGoldenResource, FIELD_NAME_IDENTIFIER); TerserUtil.cloneCompositeField(myFhirContext, theFromGoldenResource, theToGoldenResource, FIELD_NAME_IDENTIFIER);
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theFromGoldenResource, theToGoldenResource, theMdmTransactionContext);
// 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());
// }
} }
/** /**