Updated link processing for MDM events
This commit is contained in:
parent
1bd1b36668
commit
c63a503841
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.entity;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
|
@ -47,7 +48,7 @@ import java.util.Date;
|
||||||
@Table(name = "MPI_LINK", uniqueConstraints = {
|
@Table(name = "MPI_LINK", uniqueConstraints = {
|
||||||
@UniqueConstraint(name = "IDX_EMPI_PERSON_TGT", columnNames = {"PERSON_PID", "TARGET_PID"}),
|
@UniqueConstraint(name = "IDX_EMPI_PERSON_TGT", columnNames = {"PERSON_PID", "TARGET_PID"}),
|
||||||
})
|
})
|
||||||
public class MdmLink {
|
public class MdmLink implements IMdmLink {
|
||||||
public static final int VERSION_LENGTH = 16;
|
public static final int VERSION_LENGTH = 16;
|
||||||
private static final int MATCH_RESULT_LENGTH = 16;
|
private static final int MATCH_RESULT_LENGTH = 16;
|
||||||
private static final int LINK_SOURCE_LENGTH = 16;
|
private static final int LINK_SOURCE_LENGTH = 16;
|
||||||
|
|
|
@ -119,17 +119,17 @@ public class MdmMessageHandler implements MessageHandler {
|
||||||
ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType());
|
ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType());
|
||||||
outgoingMsg.setTransactionId(theMsg.getTransactionId());
|
outgoingMsg.setTransactionId(theMsg.getTransactionId());
|
||||||
|
|
||||||
MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkEvent();
|
MdmLinkEvent linkChangeEvent = new MdmLinkEvent();
|
||||||
Optional<MdmLink> mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource);
|
mdmContext.getMdmLinks()
|
||||||
if (!mdmLinkBySource.isPresent()) {
|
.stream()
|
||||||
ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement());
|
.forEach(l -> {
|
||||||
}
|
linkChangeEvent.addMdmLink(myModelConverter.toJson((MdmLink) l));
|
||||||
|
});
|
||||||
|
|
||||||
mdmLinkBySource.ifPresent(link -> linkChangeEvent.setFromLink(myModelConverter.toJson(link)));
|
|
||||||
HookParams params = new HookParams()
|
HookParams params = new HookParams()
|
||||||
.add(ResourceOperationMessage.class, outgoingMsg)
|
.add(ResourceOperationMessage.class, outgoingMsg)
|
||||||
.add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages())
|
.add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages())
|
||||||
.add(MdmLinkEvent.class, mdmContext.getMdmLinkEvent());
|
.add(MdmLinkEvent.class, linkChangeEvent);
|
||||||
|
|
||||||
myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params);
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,6 @@ public class MdmEidUpdateService {
|
||||||
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, updateContext.getMatchedGoldenResource(), theMdmTransactionContext);
|
||||||
myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType());
|
myMdmResourceDaoSvc.upsertGoldenResource(updateContext.getMatchedGoldenResource(), theMdmTransactionContext.getResourceType());
|
||||||
}
|
}
|
||||||
|
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(updateContext.getExistingGoldenResource());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNoEidsInCommon(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext, MdmUpdateContext theUpdateContext) {
|
private void handleNoEidsInCommon(IAnyResource theResource, MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext, MdmUpdateContext theUpdateContext) {
|
||||||
|
|
|
@ -53,6 +53,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
||||||
private MdmLinkDaoSvc myMdmLinkDaoSvc;
|
private MdmLinkDaoSvc myMdmLinkDaoSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IdHelperService myIdHelperService;
|
private IdHelperService myIdHelperService;
|
||||||
|
@Autowired
|
||||||
|
private IMdmModelConverterSvc myMdmModelConverterSvc;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
@ -69,7 +71,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
||||||
validateRequestIsLegal(theGoldenResource, theSourceResource, matchResultEnum, theLinkSource);
|
validateRequestIsLegal(theGoldenResource, theSourceResource, matchResultEnum, theLinkSource);
|
||||||
|
|
||||||
myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmTransactionContext.getResourceType());
|
myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmTransactionContext.getResourceType());
|
||||||
createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext);
|
MdmLink link = createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext);
|
||||||
|
theMdmTransactionContext.addMdmLink(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean goldenResourceLinkedAsNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) {
|
private boolean goldenResourceLinkedAsNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) {
|
||||||
|
@ -87,6 +90,7 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
||||||
MdmLink mdmLink = optionalMdmLink.get();
|
MdmLink mdmLink = optionalMdmLink.get();
|
||||||
log(theMdmTransactionContext, "Deleting MdmLink [" + theGoldenResource.getIdElement().toVersionless() + " -> " + theSourceResource.getIdElement().toVersionless() + "] with result: " + mdmLink.getMatchResult());
|
log(theMdmTransactionContext, "Deleting MdmLink [" + theGoldenResource.getIdElement().toVersionless() + " -> " + theSourceResource.getIdElement().toVersionless() + "] with result: " + mdmLink.getMatchResult());
|
||||||
myMdmLinkDaoSvc.deleteLink(mdmLink);
|
myMdmLinkDaoSvc.deleteLink(mdmLink);
|
||||||
|
theMdmTransactionContext.addMdmLink(mdmLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +133,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrUpdateLinkEntity(IBaseResource theGoldenResource, IBaseResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmTransactionContext) {
|
private MdmLink createOrUpdateLinkEntity(IBaseResource theGoldenResource, IBaseResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmTransactionContext) {
|
||||||
myMdmLinkDaoSvc.createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext);
|
return myMdmLinkDaoSvc.createOrUpdateLinkEntity(theGoldenResource, theSourceResource, theMatchOutcome, theLinkSource, theMdmTransactionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(MdmTransactionContext theMdmTransactionContext, String theMessage) {
|
private void log(MdmTransactionContext theMdmTransactionContext, String theMessage) {
|
||||||
|
|
|
@ -78,8 +78,6 @@ public class MdmMatchLinkSvc {
|
||||||
private MdmTransactionContext doMdmUpdate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) {
|
private MdmTransactionContext doMdmUpdate(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) {
|
||||||
CandidateList candidateList = myMdmGoldenResourceFindingSvc.findGoldenResourceCandidates(theResource);
|
CandidateList candidateList = myMdmGoldenResourceFindingSvc.findGoldenResourceCandidates(theResource);
|
||||||
|
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setTargetResourceId(theResource);
|
|
||||||
|
|
||||||
if (candidateList.isEmpty()) {
|
if (candidateList.isEmpty()) {
|
||||||
handleMdmWithNoCandidates(theResource, theMdmTransactionContext);
|
handleMdmWithNoCandidates(theResource, theMdmTransactionContext);
|
||||||
} else if (candidateList.exactlyOneMatch()) {
|
} else if (candidateList.exactlyOneMatch()) {
|
||||||
|
@ -115,14 +113,12 @@ public class MdmMatchLinkSvc {
|
||||||
|
|
||||||
//Set all GoldenResources as POSSIBLE_DUPLICATE of the last GoldenResource.
|
//Set all GoldenResources as POSSIBLE_DUPLICATE of the last GoldenResource.
|
||||||
IAnyResource firstGoldenResource = goldenResources.get(0);
|
IAnyResource firstGoldenResource = goldenResources.get(0);
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(firstGoldenResource);
|
|
||||||
|
|
||||||
goldenResources.subList(1, goldenResources.size())
|
goldenResources.subList(1, goldenResources.size())
|
||||||
.forEach(possibleDuplicateGoldenResource -> {
|
.forEach(possibleDuplicateGoldenResource -> {
|
||||||
MdmMatchOutcome outcome = MdmMatchOutcome.POSSIBLE_DUPLICATE;
|
MdmMatchOutcome outcome = MdmMatchOutcome.POSSIBLE_DUPLICATE;
|
||||||
outcome.setEidMatch(theCandidateList.isEidMatch());
|
outcome.setEidMatch(theCandidateList.isEidMatch());
|
||||||
myMdmLinkSvc.updateLink(firstGoldenResource, possibleDuplicateGoldenResource, outcome, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(firstGoldenResource, possibleDuplicateGoldenResource, outcome, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
theMdmTransactionContext.getMdmLinkEvent().addDuplicateGoldenResourceId(possibleDuplicateGoldenResource);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,8 +131,6 @@ public class MdmMatchLinkSvc {
|
||||||
// 2. Create source resource for the MDM source
|
// 2. Create source resource for the MDM source
|
||||||
// 3. UPDATE MDM LINK TABLE
|
// 3. UPDATE MDM LINK TABLE
|
||||||
myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
|
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) {
|
private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) {
|
||||||
|
@ -146,7 +140,6 @@ public class MdmMatchLinkSvc {
|
||||||
if (myGoldenResourceHelper.isPotentialDuplicate(goldenResource, theTargetResource)) {
|
if (myGoldenResourceHelper.isPotentialDuplicate(goldenResource, theTargetResource)) {
|
||||||
log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs.");
|
log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs.");
|
||||||
IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theTargetResource, theMdmTransactionContext);
|
IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theTargetResource, theMdmTransactionContext);
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(newGoldenResource);
|
|
||||||
|
|
||||||
myMdmLinkSvc.updateLink(newGoldenResource, theTargetResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(newGoldenResource, theTargetResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
myMdmLinkSvc.updateLink(newGoldenResource, goldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(newGoldenResource, goldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
|
@ -156,7 +149,6 @@ public class MdmMatchLinkSvc {
|
||||||
myEidUpdateService.applySurvivorshipRulesAndSaveGoldenResource(theTargetResource, goldenResource, theMdmTransactionContext);
|
myEidUpdateService.applySurvivorshipRulesAndSaveGoldenResource(theTargetResource, goldenResource, theMdmTransactionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
theMdmTransactionContext.getMdmLinkEvent().setGoldenResourceId(goldenResource);
|
|
||||||
myMdmLinkSvc.updateLink(goldenResource, theTargetResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
myMdmLinkSvc.updateLink(goldenResource, theTargetResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,22 +31,22 @@ public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc {
|
||||||
IdHelperService myIdHelperService;
|
IdHelperService myIdHelperService;
|
||||||
|
|
||||||
public MdmLinkJson toJson(MdmLink theLink) {
|
public MdmLinkJson toJson(MdmLink theLink) {
|
||||||
MdmLinkJson retval = new MdmLinkJson();
|
MdmLinkJson retVal = new MdmLinkJson();
|
||||||
String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue();
|
String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue();
|
||||||
retval.setSourceId(sourceId);
|
retVal.setSourceId(sourceId);
|
||||||
String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue();
|
String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue();
|
||||||
retval.setGoldenResourceId(goldenResourceId);
|
retVal.setGoldenResourceId(goldenResourceId);
|
||||||
retval.setCreated(theLink.getCreated());
|
retVal.setCreated(theLink.getCreated());
|
||||||
retval.setEidMatch(theLink.getEidMatch());
|
retVal.setEidMatch(theLink.getEidMatch());
|
||||||
retval.setLinkSource(theLink.getLinkSource());
|
retVal.setLinkSource(theLink.getLinkSource());
|
||||||
retval.setMatchResult(theLink.getMatchResult());
|
retVal.setMatchResult(theLink.getMatchResult());
|
||||||
retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource());
|
retVal.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource());
|
||||||
retval.setScore(theLink.getScore());
|
retVal.setScore(theLink.getScore());
|
||||||
retval.setUpdated(theLink.getUpdated());
|
retVal.setUpdated(theLink.getUpdated());
|
||||||
retval.setVector(theLink.getVector());
|
retVal.setVector(theLink.getVector());
|
||||||
retval.setVersion(theLink.getVersion());
|
retVal.setVersion(theLink.getVersion());
|
||||||
retval.setRuleCount(theLink.getRuleCount());
|
retVal.setRuleCount(theLink.getRuleCount());
|
||||||
return retval;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,10 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
||||||
import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer;
|
import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer;
|
||||||
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
||||||
|
@ -29,6 +32,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
@ -51,53 +55,38 @@ public class MdmEventIT extends BaseMdmR4Test {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IdHelperService myIdHelperService;
|
private IdHelperService myIdHelperService;
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Primary
|
|
||||||
public Properties jpaProperties() {
|
|
||||||
Properties extraProperties = new Properties();
|
|
||||||
extraProperties.put("hibernate.format_sql", "true");
|
|
||||||
extraProperties.put("hibernate.show_sql", "true");
|
|
||||||
extraProperties.put("hibernate.hbm2ddl.auto", "update");
|
|
||||||
extraProperties.put("hibernate.dialect", H2Dialect.class.getName());
|
|
||||||
|
|
||||||
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
|
|
||||||
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), HapiLuceneAnalysisConfigurer.class.getName());
|
|
||||||
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-heap");
|
|
||||||
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
|
|
||||||
extraProperties.put(HibernateOrmMapperSettings.ENABLED, "true");
|
|
||||||
|
|
||||||
return extraProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateLinkChangeEvent() throws InterruptedException {
|
public void testDuplicateLinkChangeEvent() throws InterruptedException {
|
||||||
Patient patient1 = buildJanePatient();
|
Patient patient1 = buildJanePatient();
|
||||||
addExternalEID(patient1, "eid-1");
|
addExternalEID(patient1, "eid-1");
|
||||||
addExternalEID(patient1, "eid-11");
|
addExternalEID(patient1, "eid-11");
|
||||||
patient1 = createPatientAndUpdateLinks(patient1);
|
myMdmHelper.createWithLatch(patient1);
|
||||||
|
|
||||||
Patient patient2 = buildPaulPatient();
|
Patient patient2 = buildPaulPatient();
|
||||||
addExternalEID(patient2, "eid-2");
|
addExternalEID(patient2, "eid-2");
|
||||||
addExternalEID(patient2, "eid-22");
|
addExternalEID(patient2, "eid-22");
|
||||||
patient2 = createPatientAndUpdateLinks(patient2);
|
myMdmHelper.createWithLatch(patient2);
|
||||||
|
|
||||||
Patient patient3 = buildPaulPatient();
|
Patient patient3 = buildPaulPatient();
|
||||||
addExternalEID(patient3, "eid-22");
|
addExternalEID(patient3, "eid-22");
|
||||||
patient3 = createPatientAndUpdateLinks(patient3);
|
myMdmHelper.createWithLatch(patient3);
|
||||||
|
|
||||||
patient2.getIdentifier().clear();
|
patient2.getIdentifier().clear();
|
||||||
addExternalEID(patient2, "eid-11");
|
addExternalEID(patient2, "eid-11");
|
||||||
addExternalEID(patient2, "eid-22");
|
addExternalEID(patient2, "eid-22");
|
||||||
|
|
||||||
patient2 = (Patient) myPatientDao.update(patient2).getResource();
|
myMdmHelper.updateWithLatch(patient2);
|
||||||
MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType()));
|
|
||||||
|
|
||||||
MdmLinkEvent mdmLinkEvent = ctx.getMdmLinkEvent();
|
MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class);
|
||||||
assertFalse(mdmLinkEvent.getDuplicateGoldenResourceIds().isEmpty());
|
assertNotNull(linkChangeEvent);
|
||||||
|
|
||||||
|
// MdmTransactionContext ctx = myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, createContextForUpdate(patient2.getIdElement().getResourceType()));
|
||||||
|
|
||||||
|
List<MdmLinkJson> mdmLinkEvent = linkChangeEvent.getMdmLinks();
|
||||||
|
assertEquals(3, mdmLinkEvent.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
public void testCreateLinkChangeEvent() throws InterruptedException {
|
public void testCreateLinkChangeEvent() throws InterruptedException {
|
||||||
Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC");
|
Practitioner pr = buildPractitionerWithNameAndId("Young", "AC-DC");
|
||||||
myMdmHelper.createWithLatch(pr);
|
myMdmHelper.createWithLatch(pr);
|
||||||
|
@ -110,56 +99,13 @@ public class MdmEventIT extends BaseMdmR4Test {
|
||||||
|
|
||||||
MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class);
|
MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class);
|
||||||
assertNotNull(linkChangeEvent);
|
assertNotNull(linkChangeEvent);
|
||||||
assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong());
|
|
||||||
assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong());
|
assertEquals(1, linkChangeEvent.getMdmLinks().size());
|
||||||
|
MdmLinkJson l = linkChangeEvent.getMdmLinks().get(0);
|
||||||
|
assertEquals(link.getGoldenResourcePid(), new IdDt(l.getGoldenResourceId()).getIdPartAsLong());
|
||||||
|
assertEquals(link.getSourcePid(), new IdDt(l.getSourceId()).getIdPartAsLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@Test
|
|
||||||
public void testDuplicateLinkChangeEvent() throws InterruptedException {
|
|
||||||
logAllLinks();
|
|
||||||
for (IBaseResource r : myPatientDao.search(new SearchParameterMap()).getAllResources()) {
|
|
||||||
ourLog.info("Found {}", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
Patient myPatient = createPatientAndUpdateLinks(buildPaulPatient());
|
|
||||||
StringType myPatientId = new StringType(myPatient.getIdElement().getValue());
|
|
||||||
|
|
||||||
Patient mySourcePatient = getGoldenResourceFromTargetResource(myPatient);
|
|
||||||
StringType mySourcePatientId = new StringType(mySourcePatient.getIdElement().getValue());
|
|
||||||
StringType myVersionlessGodlenResourceId = new StringType(mySourcePatient.getIdElement().toVersionless().getValue());
|
|
||||||
|
|
||||||
MdmLink myLink = myMdmLinkDaoSvc.findMdmLinkBySource(myPatient).get();
|
|
||||||
// Tests require our initial link to be a POSSIBLE_MATCH
|
|
||||||
myLink.setMatchResult(MdmMatchResultEnum.POSSIBLE_MATCH);
|
|
||||||
saveLink(myLink);
|
|
||||||
assertEquals(MdmLinkSourceEnum.AUTO, myLink.getLinkSource());
|
|
||||||
// myDaoConfig.setExpungeEnabled(true);
|
|
||||||
|
|
||||||
// Add a second patient
|
|
||||||
createPatientAndUpdateLinks(buildJanePatient());
|
|
||||||
|
|
||||||
// Add a possible duplicate
|
|
||||||
StringType myLinkSource = new StringType(MdmLinkSourceEnum.AUTO.name());
|
|
||||||
Patient sourcePatient1 = createGoldenPatient();
|
|
||||||
StringType myGoldenResource1Id = new StringType(sourcePatient1.getIdElement().toVersionless().getValue());
|
|
||||||
Long sourcePatient1Pid = myIdHelperService.getPidOrNull(sourcePatient1);
|
|
||||||
Patient sourcePatient2 = createGoldenPatient();
|
|
||||||
StringType myGoldenResource2Id = new StringType(sourcePatient2.getIdElement().toVersionless().getValue());
|
|
||||||
Long sourcePatient2Pid = myIdHelperService.getPidOrNull(sourcePatient2);
|
|
||||||
|
|
||||||
|
|
||||||
MdmLink possibleDuplicateMdmLink = myMdmLinkDaoSvc.newMdmLink().setGoldenResourcePid(sourcePatient1Pid).setSourcePid(sourcePatient2Pid).setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE).setLinkSource(MdmLinkSourceEnum.AUTO);
|
|
||||||
saveLink(possibleDuplicateMdmLink);
|
|
||||||
|
|
||||||
logAllLinks();
|
|
||||||
|
|
||||||
ResourceOperationMessage resourceOperationMessage = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(ResourceOperationMessage.class);
|
|
||||||
assertNotNull(resourceOperationMessage);
|
|
||||||
assertEquals(sourcePatient2.getId(), resourceOperationMessage.getId());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private MdmLink getLinkByTargetId(IBaseResource theResource) {
|
private MdmLink getLinkByTargetId(IBaseResource theResource) {
|
||||||
MdmLink example = new MdmLink();
|
MdmLink example = new MdmLink();
|
||||||
example.setSourcePid(theResource.getIdElement().getIdPartAsLong());
|
example.setSourcePid(theResource.getIdElement().getIdPartAsLong());
|
||||||
|
@ -171,19 +117,14 @@ public class MdmEventIT extends BaseMdmR4Test {
|
||||||
Patient patient1 = addExternalEID(buildJanePatient(), "eid-1");
|
Patient patient1 = addExternalEID(buildJanePatient(), "eid-1");
|
||||||
myMdmHelper.createWithLatch(patient1);
|
myMdmHelper.createWithLatch(patient1);
|
||||||
|
|
||||||
MdmTransactionContext ctx = createContextForCreate("Patient");
|
MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class);
|
||||||
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx);
|
assertNotNull(linkChangeEvent);
|
||||||
ourLog.info(ctx.getMdmLinkEvent().toString());
|
assertEquals(1, linkChangeEvent.getMdmLinks().size());
|
||||||
assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId());
|
|
||||||
assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong());
|
|
||||||
|
|
||||||
Patient patient2 = addExternalEID(buildJanePatient(), "eid-2");
|
MdmLinkJson link = linkChangeEvent.getMdmLinks().get(0);
|
||||||
myMdmHelper.createWithLatch(patient2);
|
assertEquals(patient1.getResourceType() + "/" + patient1.getIdElement().getIdPart(), link.getSourceId());
|
||||||
ctx = createContextForCreate("Patient");
|
assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(link.getGoldenResourceId()).getIdPartAsLong());
|
||||||
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx);
|
assertEquals(MdmMatchResultEnum.MATCH, link.getMatchResult());
|
||||||
ourLog.info(ctx.getMdmLinkEvent().toString());
|
|
||||||
assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId());
|
|
||||||
assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,26 +76,6 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test {
|
||||||
return myMdmLinkDao.findAll(Example.of(example)).get(0);
|
return myMdmLinkDao.findAll(Example.of(example)).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateLinkChangeEvent() throws InterruptedException {
|
|
||||||
Patient patient1 = addExternalEID(buildJanePatient(), "eid-1");
|
|
||||||
myMdmHelper.createWithLatch(patient1);
|
|
||||||
|
|
||||||
MdmTransactionContext ctx = createContextForCreate("Patient");
|
|
||||||
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient1, ctx);
|
|
||||||
ourLog.info(ctx.getMdmLinkEvent().toString());
|
|
||||||
assertEquals(patient1.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId());
|
|
||||||
assertEquals(getLinkByTargetId(patient1).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong());
|
|
||||||
|
|
||||||
Patient patient2 = addExternalEID(buildJanePatient(), "eid-2");
|
|
||||||
myMdmHelper.createWithLatch(patient2);
|
|
||||||
ctx = createContextForCreate("Patient");
|
|
||||||
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(patient2, ctx);
|
|
||||||
ourLog.info(ctx.getMdmLinkEvent().toString());
|
|
||||||
assertEquals(patient2.getIdElement().getValue(), ctx.getMdmLinkEvent().getTargetResourceId());
|
|
||||||
assertEquals(getLinkByTargetId(patient2).getGoldenResourcePid(), new IdDt(ctx.getMdmLinkEvent().getGoldenResourceId()).getIdPartAsLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchExpandingInterceptorWorks() {
|
public void testSearchExpandingInterceptorWorks() {
|
||||||
SearchParameterMap subject = new SearchParameterMap("subject", new ReferenceParam("Patient/123").setMdmExpand(true)).setLoadSynchronous(true);
|
SearchParameterMap subject = new SearchParameterMap("subject", new ReferenceParam("Patient/123").setMdmExpand(true)).setLoadSynchronous(true);
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Master Data Management
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IMdmLink {
|
||||||
|
}
|
|
@ -25,158 +25,32 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
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 java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class MdmLinkEvent implements IModelJson {
|
public class MdmLinkEvent implements IModelJson {
|
||||||
|
|
||||||
@JsonProperty(value = "matchResult")
|
private List<MdmLinkJson> myMdmLinks = new ArrayList<>();
|
||||||
private MdmMatchResultEnum myMdmMatchResult;
|
|
||||||
@JsonProperty(value = "linkSource")
|
|
||||||
private MdmLinkSourceEnum myMdmLinkSource;
|
|
||||||
@JsonProperty(value = "eidMatch")
|
|
||||||
private Boolean myEidMatch;
|
|
||||||
@JsonProperty(value = "newGoldenResource")
|
|
||||||
private Boolean myNewGoldenResource;
|
|
||||||
@JsonProperty(value = "score")
|
|
||||||
private Double myScore;
|
|
||||||
@JsonProperty(value = "ruleCount")
|
|
||||||
private Long myRuleCount;
|
|
||||||
@JsonProperty(value = "targetResourceId", required = true)
|
|
||||||
private String myTargetResourceId;
|
|
||||||
@JsonProperty(value = "goldenResourceId", required = true)
|
|
||||||
private String myGoldenResourceId;
|
|
||||||
@JsonProperty(value = "duplicateResourceIds")
|
|
||||||
private Set<String> myDuplicateGoldenResourceIds = new HashSet<>();
|
|
||||||
|
|
||||||
public String getGoldenResourceId() {
|
public List<MdmLinkJson> getMdmLinks() {
|
||||||
return myGoldenResourceId;
|
return myMdmLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGoldenResourceId(IBaseResource theGoldenResourceId) {
|
public void setMdmLinks(List<MdmLinkJson> theMdmLinks) {
|
||||||
setGoldenResourceId(getIdAsString(theGoldenResourceId));
|
myMdmLinks = theMdmLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGoldenResourceId(String theGoldenResourceId) {
|
public MdmLinkEvent addMdmLink(MdmLinkJson theMdmLink) {
|
||||||
myGoldenResourceId = theGoldenResourceId;
|
getMdmLinks().add(theMdmLink);
|
||||||
}
|
|
||||||
|
|
||||||
private String getIdAsString(IBaseResource theResource) {
|
|
||||||
if (theResource == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
IIdType idElement = theResource.getIdElement();
|
|
||||||
if (idElement == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return idElement.getValueAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTargetResourceId() {
|
|
||||||
return myTargetResourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTargetResourceId(IBaseResource theTargetResource) {
|
|
||||||
setTargetResourceId(getIdAsString(theTargetResource));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTargetResourceId(String theTargetResourceId) {
|
|
||||||
myTargetResourceId = theTargetResourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getDuplicateGoldenResourceIds() {
|
|
||||||
return myDuplicateGoldenResourceIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuplicateGoldenResourceIds(Set<String> theDuplicateGoldenResourceIds) {
|
|
||||||
myDuplicateGoldenResourceIds = theDuplicateGoldenResourceIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MdmLinkEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) {
|
|
||||||
String id = getIdAsString(theDuplicateGoldenResourceId);
|
|
||||||
if (id != null) {
|
|
||||||
getDuplicateGoldenResourceIds().add(id);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MdmMatchResultEnum getMdmMatchResult() {
|
|
||||||
return myMdmMatchResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMdmMatchResult(MdmMatchResultEnum theMdmMatchResult) {
|
|
||||||
myMdmMatchResult = theMdmMatchResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MdmLinkSourceEnum getMdmLinkSource() {
|
|
||||||
return myMdmLinkSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMdmLinkSource(MdmLinkSourceEnum theMdmLinkSource) {
|
|
||||||
myMdmLinkSource = theMdmLinkSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getEidMatch() {
|
|
||||||
return myEidMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEidMatch(Boolean theEidMatch) {
|
|
||||||
if (theEidMatch == null) {
|
|
||||||
myEidMatch = Boolean.FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
myEidMatch = theEidMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getNewGoldenResource() {
|
|
||||||
return myNewGoldenResource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNewGoldenResource(Boolean theNewGoldenResource) {
|
|
||||||
if (theNewGoldenResource == null) {
|
|
||||||
myNewGoldenResource = Boolean.FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
myNewGoldenResource = theNewGoldenResource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double getScore() {
|
|
||||||
return myScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScore(Double theScore) {
|
|
||||||
myScore = theScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getRuleCount() {
|
|
||||||
return myRuleCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRuleCount(Long theRuleCount) {
|
|
||||||
myRuleCount = theRuleCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFromLink(MdmLinkJson theMdmLinkJson) {
|
|
||||||
setMdmMatchResult(theMdmLinkJson.getMatchResult());
|
|
||||||
setMdmLinkSource(theMdmLinkJson.getLinkSource());
|
|
||||||
setEidMatch(theMdmLinkJson.getEidMatch());
|
|
||||||
setNewGoldenResource(theMdmLinkJson.getLinkCreatedNewResource());
|
|
||||||
setScore(theMdmLinkJson.getScore());
|
|
||||||
setRuleCount(theMdmLinkJson.getRuleCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MdmLinkChangeEvent{" +
|
return "MdmLinkEvent{" +
|
||||||
"myMdmMatchResult=" + myMdmMatchResult +
|
"myMdmLinks=" + myMdmLinks +
|
||||||
", myMdmLinkSource=" + myMdmLinkSource +
|
|
||||||
", myEidMatch=" + myEidMatch +
|
|
||||||
", myNewGoldenResource=" + myNewGoldenResource +
|
|
||||||
", myScore=" + myScore +
|
|
||||||
", myRuleCount=" + myRuleCount +
|
|
||||||
", myTargetResourceId='" + myTargetResourceId + '\'' +
|
|
||||||
", myGoldenResourceId='" + myGoldenResourceId + '\'' +
|
|
||||||
", myDuplicateGoldenResourceIds=" + myDuplicateGoldenResourceIds +
|
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,13 @@ package ca.uhn.fhir.mdm.model;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MdmTransactionContext {
|
public class MdmTransactionContext {
|
||||||
|
|
||||||
public enum OperationType {
|
public enum OperationType {
|
||||||
|
@ -46,7 +50,7 @@ public class MdmTransactionContext {
|
||||||
|
|
||||||
private String myResourceType;
|
private String myResourceType;
|
||||||
|
|
||||||
private MdmLinkEvent myMdmLinkEvent = new MdmLinkEvent();
|
private List<IMdmLink> myMdmLinkEvents = new ArrayList<>();
|
||||||
|
|
||||||
public TransactionLogMessages getTransactionLogMessages() {
|
public TransactionLogMessages getTransactionLogMessages() {
|
||||||
return myTransactionLogMessages;
|
return myTransactionLogMessages;
|
||||||
|
@ -96,12 +100,16 @@ public class MdmTransactionContext {
|
||||||
this.myResourceType = myResourceType;
|
this.myResourceType = myResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MdmLinkEvent getMdmLinkEvent() {
|
public List<IMdmLink> getMdmLinks() {
|
||||||
return myMdmLinkEvent;
|
return myMdmLinkEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMdmLinkChangeEvent(MdmLinkEvent theMdmLinkEvent) {
|
public MdmTransactionContext addMdmLink(IMdmLink theMdmLinkEvent) {
|
||||||
myMdmLinkEvent = theMdmLinkEvent;
|
getMdmLinks().add(theMdmLinkEvent);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMdmLinks(List<IMdmLink> theMdmLinkEvents) {
|
||||||
|
myMdmLinkEvents = theMdmLinkEvents;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue