Issue 3648 fix mdm log messages (#3649)
* fix log messages * fix log messages * fix log messages * fix log messages * fix log messages * fix log messages * review feedback and fix log messages * improved logging * improved logging
This commit is contained in:
parent
ad3294f8e8
commit
4f4032d892
|
@ -98,7 +98,7 @@ public class MdmLinkDaoSvc {
|
||||||
mdmLink.setPartitionId(new PartitionablePartitionId(partitionId.getFirstPartitionIdOrNull(), partitionId.getPartitionDate()));
|
mdmLink.setPartitionId(new PartitionablePartitionId(partitionId.getFirstPartitionIdOrNull(), partitionId.getPartitionDate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
String message = String.format("Creating MdmLink from %s to %s.", theGoldenResource.getIdElement().toUnqualifiedVersionless(), theSourceResource.getIdElement().toUnqualifiedVersionless());
|
String message = String.format("Creating %s link from %s to Golden Resource %s.", mdmLink.getMatchResult(), theSourceResource.getIdElement().toUnqualifiedVersionless(), theGoldenResource.getIdElement().toUnqualifiedVersionless());
|
||||||
theMdmTransactionContext.addTransactionLogMessage(message);
|
theMdmTransactionContext.addTransactionLogMessage(message);
|
||||||
ourLog.debug(message);
|
ourLog.debug(message);
|
||||||
save(mdmLink);
|
save(mdmLink);
|
||||||
|
|
|
@ -21,11 +21,11 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
|
import ca.uhn.fhir.jpa.mdm.svc.candidate.MdmCandidateSearchSvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmMatchFinderSvc;
|
import ca.uhn.fhir.mdm.api.IMdmMatchFinderSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MatchedTarget;
|
import ca.uhn.fhir.mdm.api.MatchedTarget;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
import ca.uhn.fhir.mdm.rules.svc.MdmResourceMatcherSvc;
|
import ca.uhn.fhir.mdm.rules.svc.MdmResourceMatcherSvc;
|
||||||
import ca.uhn.fhir.jpa.mdm.svc.candidate.MdmCandidateSearchSvc;
|
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -37,6 +37,8 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.mdm.svc.candidate.CandidateSearcher.idOrType;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MdmMatchFinderSvcImpl implements IMdmMatchFinderSvc {
|
public class MdmMatchFinderSvcImpl implements IMdmMatchFinderSvc {
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ public class MdmMatchFinderSvcImpl implements IMdmMatchFinderSvc {
|
||||||
.map(candidate -> new MatchedTarget(candidate, myMdmResourceMatcherSvc.getMatchResult(theResource, candidate)))
|
.map(candidate -> new MatchedTarget(candidate, myMdmResourceMatcherSvc.getMatchResult(theResource, candidate)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
ourLog.info("Found {} matched targets for {}.", matches.size(), theResourceType);
|
ourLog.trace("Found {} matched targets for {}.", matches.size(), idOrType(theResource, theResourceType));
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class MdmMatchLinkSvc {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMdmWithNoCandidates(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) {
|
private void handleMdmWithNoCandidates(IAnyResource theResource, MdmTransactionContext theMdmTransactionContext) {
|
||||||
log(theMdmTransactionContext, String.format("There were no matched candidates for MDM, creating a new %s.", theResource.getIdElement().getResourceType()));
|
log(theMdmTransactionContext, String.format("There were no matched candidates for MDM, creating a new %s Golden Resource.", theResource.getIdElement().getResourceType()));
|
||||||
IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource, theMdmTransactionContext);
|
IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theResource, theMdmTransactionContext);
|
||||||
// TODO GGG :)
|
// TODO GGG :)
|
||||||
// 1. Get the right helper
|
// 1. Get the right helper
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class MdmResourceFilteringSvc {
|
||||||
*/
|
*/
|
||||||
public boolean shouldBeProcessed(IAnyResource theResource) {
|
public boolean shouldBeProcessed(IAnyResource theResource) {
|
||||||
if (MdmResourceUtil.isMdmManaged(theResource)) {
|
if (MdmResourceUtil.isMdmManaged(theResource)) {
|
||||||
ourLog.debug("MDM Message handler is dropping [{}] as it is MDM-managed.", theResource.getId());
|
ourLog.trace("MDM Message handler is dropping [{}] as it is MDM-managed.", theResource.getId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -83,4 +84,11 @@ public class CandidateSearcher {
|
||||||
public Optional<IBundleProvider> search(String theResourceType, String theResourceCriteria) {
|
public Optional<IBundleProvider> search(String theResourceType, String theResourceCriteria) {
|
||||||
return this.search(theResourceType, theResourceCriteria, RequestPartitionId.allPartitions());
|
return this.search(theResourceType, theResourceCriteria, RequestPartitionId.allPartitions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String idOrType(IAnyResource theResource, String theResourceType) {
|
||||||
|
if (theResource.getIdElement() == null) {
|
||||||
|
return theResourceType;
|
||||||
|
}
|
||||||
|
return theResource.getIdElement().toUnqualifiedVersionless().toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,22 +52,22 @@ public class FindCandidateByEidSvc extends BaseCandidateFinder {
|
||||||
private MdmLinkDaoSvc myMdmLinkDaoSvc;
|
private MdmLinkDaoSvc myMdmLinkDaoSvc;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theBaseResource) {
|
protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theIncomingResource) {
|
||||||
List<MatchedGoldenResourceCandidate> retval = new ArrayList<>();
|
List<MatchedGoldenResourceCandidate> retval = new ArrayList<>();
|
||||||
|
|
||||||
List<CanonicalEID> eidFromResource = myEIDHelper.getExternalEid(theBaseResource);
|
List<CanonicalEID> eidFromResource = myEIDHelper.getExternalEid(theIncomingResource);
|
||||||
if (!eidFromResource.isEmpty()) {
|
if (!eidFromResource.isEmpty()) {
|
||||||
for (CanonicalEID eid : eidFromResource) {
|
for (CanonicalEID eid : eidFromResource) {
|
||||||
Optional<IAnyResource> oFoundGoldenResource = myMdmResourceDaoSvc.searchGoldenResourceByEID(eid.getValue(), theBaseResource.getIdElement().getResourceType(), (RequestPartitionId) theBaseResource.getUserData(Constants.RESOURCE_PARTITION_ID));
|
Optional<IAnyResource> oFoundGoldenResource = myMdmResourceDaoSvc.searchGoldenResourceByEID(eid.getValue(), theIncomingResource.getIdElement().getResourceType(), (RequestPartitionId) theIncomingResource.getUserData(Constants.RESOURCE_PARTITION_ID));
|
||||||
if (oFoundGoldenResource.isPresent()) {
|
if (oFoundGoldenResource.isPresent()) {
|
||||||
IAnyResource foundGoldenResource = oFoundGoldenResource.get();
|
IAnyResource foundGoldenResource = oFoundGoldenResource.get();
|
||||||
// Exclude manually declared NO_MATCH links from candidates
|
// Exclude manually declared NO_MATCH links from candidates
|
||||||
if (isNoMatch(foundGoldenResource, theBaseResource)) {
|
if (isNoMatch(foundGoldenResource, theIncomingResource)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Long pidOrNull = myIdHelperService.getPidOrNull(foundGoldenResource);
|
Long pidOrNull = myIdHelperService.getPidOrNull(foundGoldenResource);
|
||||||
MatchedGoldenResourceCandidate mpc = new MatchedGoldenResourceCandidate(new ResourcePersistentId(pidOrNull), MdmMatchOutcome.EID_MATCH);
|
MatchedGoldenResourceCandidate mpc = new MatchedGoldenResourceCandidate(new ResourcePersistentId(pidOrNull), MdmMatchOutcome.EID_MATCH);
|
||||||
ourLog.debug("Matched {} by EID {}", foundGoldenResource.getIdElement(), eid);
|
ourLog.debug("Incoming Resource {} matched Golden Resource {} by EID {}", theIncomingResource.getIdElement().toUnqualifiedVersionless(), foundGoldenResource.getIdElement().toUnqualifiedVersionless(), eid);
|
||||||
retval.add(mpc);
|
retval.add(mpc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
|
||||||
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
|
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.entity.MdmLink;
|
import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
|
@ -76,21 +75,39 @@ public class FindCandidateByExampleSvc extends BaseCandidateFinder {
|
||||||
// The data flow is as follows ->
|
// The data flow is as follows ->
|
||||||
// MatchedTargetCandidate -> Golden Resource -> MdmLink -> MatchedGoldenResourceCandidate
|
// MatchedTargetCandidate -> Golden Resource -> MdmLink -> MatchedGoldenResourceCandidate
|
||||||
matchedCandidates = matchedCandidates.stream().filter(mc -> mc.isMatch() || mc.isPossibleMatch()).collect(Collectors.toList());
|
matchedCandidates = matchedCandidates.stream().filter(mc -> mc.isMatch() || mc.isPossibleMatch()).collect(Collectors.toList());
|
||||||
|
List<String> skippedLogMessages = new ArrayList<>();
|
||||||
|
List<String> matchedLogMessages = new ArrayList<>();
|
||||||
for (MatchedTarget match : matchedCandidates) {
|
for (MatchedTarget match : matchedCandidates) {
|
||||||
|
|
||||||
Optional<MdmLink> optionalMdmLink = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(match.getTarget()));
|
Optional<MdmLink> optionalMdmLink = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(myIdHelperService.getPidOrNull(match.getTarget()));
|
||||||
if (!optionalMdmLink.isPresent()) {
|
if (!optionalMdmLink.isPresent()) {
|
||||||
|
if (ourLog.isDebugEnabled()) {
|
||||||
|
skippedLogMessages.add(String.format("%s does not link to a Golden Resource (it may be a Golden Resource itself). Removing candidate.", match.getTarget().getIdElement().toUnqualifiedVersionless()));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MdmLink matchMdmLink = optionalMdmLink.get();
|
MdmLink matchMdmLink = optionalMdmLink.get();
|
||||||
if (goldenResourcePidsToExclude.contains(matchMdmLink.getGoldenResourcePid())) {
|
if (goldenResourcePidsToExclude.contains(matchMdmLink.getGoldenResourcePid())) {
|
||||||
ourLog.info("Skipping MDM on candidate Golden Resource with PID {} due to manual NO_MATCH", matchMdmLink.getGoldenResourcePid());
|
skippedLogMessages.add(String.format("Skipping MDM on candidate Golden Resource with PID %s due to manual NO_MATCH", matchMdmLink.getGoldenResourcePid()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchedGoldenResourceCandidate candidate = new MatchedGoldenResourceCandidate(getResourcePersistentId(matchMdmLink.getGoldenResourcePid()), match.getMatchResult());
|
MatchedGoldenResourceCandidate candidate = new MatchedGoldenResourceCandidate(getResourcePersistentId(matchMdmLink.getGoldenResourcePid()), match.getMatchResult());
|
||||||
|
if (ourLog.isDebugEnabled()) {
|
||||||
|
matchedLogMessages.add(String.format("Navigating from matched resource %s to its Golden Resource %s", match.getTarget().getIdElement().toUnqualifiedVersionless(), matchMdmLink.getGoldenResource().getIdDt().toUnqualifiedVersionless()));
|
||||||
|
}
|
||||||
retval.add(candidate);
|
retval.add(candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ourLog.isDebugEnabled()) {
|
||||||
|
for (String logMessage: skippedLogMessages) {
|
||||||
|
ourLog.debug(logMessage);
|
||||||
|
}
|
||||||
|
for (String logMessage: matchedLogMessages) {
|
||||||
|
ourLog.debug(logMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,8 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
|
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
|
@ -44,6 +43,7 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.mdm.svc.candidate.CandidateSearcher.idOrType;
|
||||||
import static ca.uhn.fhir.mdm.api.MdmConstants.ALL_RESOURCE_SEARCH_PARAM_TYPE;
|
import static ca.uhn.fhir.mdm.api.MdmConstants.ALL_RESOURCE_SEARCH_PARAM_TYPE;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -93,14 +93,16 @@ public class MdmCandidateSearchSvc {
|
||||||
searchForIdsAndAddToMap(theResourceType, theResource, matchedPidsToResources, filterCriteria, resourceSearchParam, theRequestPartitionId);
|
searchForIdsAndAddToMap(theResourceType, theResource, matchedPidsToResources, filterCriteria, resourceSearchParam, theRequestPartitionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Obviously we don't want to consider the freshly added resource as a potential candidate.
|
// Obviously we don't want to consider the incoming resource as a potential candidate.
|
||||||
//Sometimes, we are running this function on a resource that has not yet been persisted,
|
// Sometimes, we are running this function on a resource that has not yet been persisted,
|
||||||
//so it may not have an ID yet, precluding the need to remove it.
|
// so it may not have an ID yet, precluding the need to remove it.
|
||||||
if (theResource.getIdElement().getIdPart() != null) {
|
if (theResource.getIdElement().getIdPart() != null) {
|
||||||
matchedPidsToResources.remove(myJpaIdHelperService.getPidOrNull(theResource));
|
if (matchedPidsToResources.remove(myJpaIdHelperService.getPidOrNull(theResource)) != null) {
|
||||||
|
ourLog.debug("Removing incoming resource {} from list of candidates.", theResource.getIdElement().toUnqualifiedVersionless());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Found {} resources for {}", matchedPidsToResources.size(), theResourceType);
|
ourLog.info("Candidate search found {} matching resources for {}", matchedPidsToResources.size(), idOrType(theResource, theResourceType));
|
||||||
return matchedPidsToResources.values();
|
return matchedPidsToResources.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,15 +76,15 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
|
||||||
JobInstanceStartRequest request = buildRequest(jobId);
|
JobInstanceStartRequest request = buildRequest(jobId);
|
||||||
|
|
||||||
myFirstStepLatch.setExpectedCount(1);
|
myFirstStepLatch.setExpectedCount(1);
|
||||||
|
myLastStepLatch.setExpectedCount(1);
|
||||||
String instanceId = myJobCoordinator.startInstance(request);
|
String instanceId = myJobCoordinator.startInstance(request);
|
||||||
myFirstStepLatch.awaitExpected();
|
myFirstStepLatch.awaitExpected();
|
||||||
|
|
||||||
myBatch2JobHelper.assertNoGatedStep(instanceId);
|
myBatch2JobHelper.assertNoGatedStep(instanceId);
|
||||||
|
|
||||||
myLastStepLatch.setExpectedCount(1);
|
|
||||||
// Since there was only one chunk, the job should proceed without requiring a maintenance pass
|
// Since there was only one chunk, the job should proceed without requiring a maintenance pass
|
||||||
myLastStepLatch.awaitExpected();
|
|
||||||
myBatch2JobHelper.awaitSingleChunkJobCompletion(instanceId);
|
myBatch2JobHelper.awaitSingleChunkJobCompletion(instanceId);
|
||||||
|
myLastStepLatch.awaitExpected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -111,11 +111,7 @@ public class CanonicalEID {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CanonicalEID{" +
|
return mySystem + '|' + myValue;
|
||||||
"mySystem='" + mySystem + '\'' +
|
|
||||||
", myUse='" + myUse + '\'' +
|
|
||||||
", myValue='" + myValue + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,14 @@ package ca.uhn.fhir.mdm.rules.svc;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.api.MdmConstants;
|
import ca.uhn.fhir.mdm.api.MdmConstants;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchEvaluation;
|
import ca.uhn.fhir.mdm.api.MdmMatchEvaluation;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
|
import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
|
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
|
||||||
|
@ -130,7 +130,7 @@ public class MdmResourceMatcherSvc {
|
||||||
ourLog.debug("Matcher {} is not valid for resource type: {}. Skipping it.", fieldComparator.getName(), resourceType);
|
ourLog.debug("Matcher {} is not valid for resource type: {}. Skipping it.", fieldComparator.getName(), resourceType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ourLog.debug("Matcher {} is valid for resource type: {}. Evaluating match.", fieldComparator.getName(), resourceType);
|
ourLog.trace("Matcher {} is valid for resource type: {}. Evaluating match.", fieldComparator.getName(), resourceType);
|
||||||
MdmMatchEvaluation matchEvaluation = fieldComparator.match(theLeftResource, theRightResource);
|
MdmMatchEvaluation matchEvaluation = fieldComparator.match(theLeftResource, theRightResource);
|
||||||
if (matchEvaluation.match) {
|
if (matchEvaluation.match) {
|
||||||
vector |= (1 << i);
|
vector |= (1 << i);
|
||||||
|
|
|
@ -20,13 +20,13 @@ package ca.uhn.fhir.mdm.util;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
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.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.fhirpath.IFhirPath;
|
import ca.uhn.fhir.fhirpath.IFhirPath;
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
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.api.IMdmSurvivorshipService;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
|
@ -94,7 +94,7 @@ public class GoldenResourceHelper {
|
||||||
// hapi has 2 metamodels: for children and types
|
// hapi has 2 metamodels: for children and types
|
||||||
BaseRuntimeChildDefinition goldenResourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
|
BaseRuntimeChildDefinition goldenResourceIdentifier = resourceDefinition.getChildByName(FIELD_NAME_IDENTIFIER);
|
||||||
|
|
||||||
cloneAllExternalEidsIntoNewGoldenResource(goldenResourceIdentifier, theIncomingResource, newGoldenResource);
|
cloneMDMEidsIntoNewGoldenResource(goldenResourceIdentifier, theIncomingResource, newGoldenResource);
|
||||||
|
|
||||||
addHapiEidIfNoExternalEidIsPresent(newGoldenResource, goldenResourceIdentifier, theIncomingResource);
|
addHapiEidIfNoExternalEidIsPresent(newGoldenResource, goldenResourceIdentifier, theIncomingResource);
|
||||||
|
|
||||||
|
@ -126,24 +126,30 @@ public class GoldenResourceHelper {
|
||||||
cloneEidIntoResource(myFhirContext, theSourceResource, hapiEid);
|
cloneEidIntoResource(myFhirContext, theSourceResource, hapiEid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cloneAllExternalEidsIntoNewGoldenResource(BaseRuntimeChildDefinition theGoldenResourceIdentifier,
|
private void cloneMDMEidsIntoNewGoldenResource(BaseRuntimeChildDefinition theGoldenResourceIdentifier,
|
||||||
IAnyResource theGoldenResource, IBase theNewGoldenResource) {
|
IAnyResource theIncomingResource, IBase theNewGoldenResource) {
|
||||||
|
String incomingResourceType = myFhirContext.getResourceType(theIncomingResource);
|
||||||
|
String mdmEIDSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(incomingResourceType);
|
||||||
|
if (mdmEIDSystem == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// FHIR choice types - fields within fhir where we have a choice of ids
|
// FHIR choice types - fields within fhir where we have a choice of ids
|
||||||
IFhirPath fhirPath = myFhirContext.newFhirPath();
|
IFhirPath fhirPath = myFhirContext.newFhirPath();
|
||||||
List<IBase> goldenResourceIdentifiers = theGoldenResourceIdentifier.getAccessor().getValues(theGoldenResource);
|
List<IBase> incomingResourceIdentifiers = theGoldenResourceIdentifier.getAccessor().getValues(theIncomingResource);
|
||||||
|
|
||||||
for (IBase base : goldenResourceIdentifiers) {
|
for (IBase incomingResourceIdentifier : incomingResourceIdentifiers) {
|
||||||
Optional<IPrimitiveType> system = fhirPath.evaluateFirst(base, "system", IPrimitiveType.class);
|
Optional<IPrimitiveType> incomingIdentifierSystem = fhirPath.evaluateFirst(incomingResourceIdentifier, "system", IPrimitiveType.class);
|
||||||
if (system.isPresent()) {
|
if (incomingIdentifierSystem.isPresent()) {
|
||||||
String resourceType = myFhirContext.getResourceType(theGoldenResource);
|
String incomingIdentifierSystemString = incomingIdentifierSystem.get().getValueAsString();
|
||||||
String mdmSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(resourceType);
|
if (Objects.equals(incomingIdentifierSystemString, mdmEIDSystem)) {
|
||||||
String baseSystem = system.get().getValueAsString();
|
ourLog.debug("Incoming resource EID System {} matches EID system in the MDM rules. Copying to Golden Resource.", incomingIdentifierSystemString);
|
||||||
if (Objects.equals(baseSystem, mdmSystem)) {
|
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource(myFhirContext, theGoldenResourceIdentifier, incomingResourceIdentifier, theNewGoldenResource);
|
||||||
ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource(myFhirContext, theGoldenResourceIdentifier, base, theNewGoldenResource);
|
} else {
|
||||||
ourLog.debug("System {} differs from system in the MDM rules {}", baseSystem, mdmSystem);
|
ourLog.debug("Incoming resource EID System {} differs from EID system in the MDM rules {}. Not copying to Golden Resource.", incomingIdentifierSystemString, mdmEIDSystem);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ourLog.debug("System is missing, skipping");
|
ourLog.debug("No EID System in incoming resource.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,13 +183,14 @@ public class GoldenResourceHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (goldenResourceOfficialEid.isEmpty() || !myMdmSettings.isPreventMultipleEids()) {
|
if (goldenResourceOfficialEid.isEmpty() || !myMdmSettings.isPreventMultipleEids()) {
|
||||||
|
if (addCanonicalEidsToGoldenResourceIfAbsent(theGoldenResource, incomingSourceEid)) {
|
||||||
log(theMdmTransactionContext, "Incoming resource:" + theSourceResource.getIdElement().toUnqualifiedVersionless() + " + with EID " + incomingSourceEid.stream().map(CanonicalEID::toString).collect(Collectors.joining(","))
|
log(theMdmTransactionContext, "Incoming resource:" + theSourceResource.getIdElement().toUnqualifiedVersionless() + " + with EID " + incomingSourceEid.stream().map(CanonicalEID::toString).collect(Collectors.joining(","))
|
||||||
+ " is applying this EIDs to its related Source Resource, as this Source Resource does not yet have an external EID");
|
+ " is applying this EID to its related Golden Resource, as this Golden Resource does not yet have an external EID");
|
||||||
addCanonicalEidsToGoldenResourceIfAbsent(theGoldenResource, incomingSourceEid);
|
}
|
||||||
} else if (!goldenResourceOfficialEid.isEmpty() && myEIDHelper.eidMatchExists(goldenResourceOfficialEid, incomingSourceEid)) {
|
} else if (!goldenResourceOfficialEid.isEmpty() && myEIDHelper.eidMatchExists(goldenResourceOfficialEid, incomingSourceEid)) {
|
||||||
log(theMdmTransactionContext, "incoming resource:" + theSourceResource.getIdElement().toVersionless() + " with EIDs " + incomingSourceEid.stream().map(CanonicalEID::toString).collect(Collectors.joining(",")) + " does not need to overwrite Golden Resource, as this EID is already present");
|
log(theMdmTransactionContext, "Incoming resource:" + theSourceResource.getIdElement().toVersionless() + " with EIDs " + incomingSourceEid.stream().map(CanonicalEID::toString).collect(Collectors.joining(",")) + " does not need to overwrite the EID in the Golden Resource, as this EID is already present in the Golden Resource");
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(Msg.code(1490) + String.format("Source EIDs %s would create a duplicate golden resource, as EIDs %s already exist!",
|
throw new IllegalArgumentException(Msg.code(1490) + String.format("Incoming resource EID %s would create a duplicate Golden Resource, as Golden Resource EID %s already exists!",
|
||||||
incomingSourceEid.toString(), goldenResourceOfficialEid.toString()));
|
incomingSourceEid.toString(), goldenResourceOfficialEid.toString()));
|
||||||
}
|
}
|
||||||
return theGoldenResource;
|
return theGoldenResource;
|
||||||
|
@ -208,7 +215,7 @@ public class GoldenResourceHelper {
|
||||||
String mdmSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(resourceType);
|
String mdmSystem = myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(resourceType);
|
||||||
String baseSystem = system.get().getValueAsString();
|
String baseSystem = system.get().getValueAsString();
|
||||||
if (Objects.equals(baseSystem, mdmSystem)) {
|
if (Objects.equals(baseSystem, mdmSystem)) {
|
||||||
ourLog.debug("Found EID confirming to MDM rules {}. It should not be copied, skipping", baseSystem);
|
ourLog.debug("Found EID confirming to MDM rules {}. It does not need to be copied, skipping", baseSystem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,16 +244,19 @@ public class GoldenResourceHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a list of incoming External EIDs, and a Golden Resource, apply all the EIDs to this resource, which did not already exist on it.
|
* Given a list of incoming External EIDs, and a Golden Resource, apply all the EIDs to this resource, which did not already exist on it.
|
||||||
|
* @return true if an EID was added
|
||||||
*/
|
*/
|
||||||
private void addCanonicalEidsToGoldenResourceIfAbsent(IBaseResource theGoldenResource, List<CanonicalEID> theIncomingSourceExternalEids) {
|
private boolean addCanonicalEidsToGoldenResourceIfAbsent(IBaseResource theGoldenResource, List<CanonicalEID> theIncomingSourceExternalEids) {
|
||||||
List<CanonicalEID> goldenResourceExternalEids = myEIDHelper.getExternalEid(theGoldenResource);
|
List<CanonicalEID> goldenResourceExternalEids = myEIDHelper.getExternalEid(theGoldenResource);
|
||||||
|
boolean addedEid = false;
|
||||||
for (CanonicalEID incomingExternalEid : theIncomingSourceExternalEids) {
|
for (CanonicalEID incomingExternalEid : theIncomingSourceExternalEids) {
|
||||||
if (goldenResourceExternalEids.contains(incomingExternalEid)) {
|
if (goldenResourceExternalEids.contains(incomingExternalEid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cloneEidIntoResource(myFhirContext, theGoldenResource, incomingExternalEid);
|
cloneEidIntoResource(myFhirContext, theGoldenResource, incomingExternalEid);
|
||||||
|
addedEid = true;
|
||||||
}
|
}
|
||||||
|
return addedEid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasIdentifier(IBaseResource theResource) {
|
public boolean hasIdentifier(IBaseResource theResource) {
|
||||||
|
|
Loading…
Reference in New Issue