Code review

This commit is contained in:
Nick Goupinets 2021-08-23 10:55:09 -04:00
parent 2d2495b3c1
commit 6ea58f74d1
9 changed files with 160 additions and 55 deletions

View File

@ -26,15 +26,14 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.IMdmModelConverterSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmResourceFilteringSvc;
import ca.uhn.fhir.jpa.mdm.svc.candidate.TooManyCandidatesException;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
import ca.uhn.fhir.mdm.api.IMdmLinkSvc;
import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent;
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.rest.server.TransactionLogMessages;
@ -42,7 +41,6 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
@ -69,6 +67,8 @@ public class MdmMessageHandler implements MessageHandler {
private MdmResourceFilteringSvc myMdmResourceFilteringSvc;
@Autowired
private IMdmSettings myMdmSettings;
@Autowired
private IMdmModelConverterSvc myModelConverter;
@Override
public void handleMessage(Message<?> theMessage) throws MessagingException {
@ -119,25 +119,17 @@ public class MdmMessageHandler implements MessageHandler {
ResourceOperationMessage outgoingMsg = new ResourceOperationMessage(myFhirContext, targetResource, theMsg.getOperationType());
outgoingMsg.setTransactionId(theMsg.getTransactionId());
MdmLinkChangeEvent linkChangeEvent = mdmContext.getMdmLinkChangeEvent();
MdmLinkEvent linkChangeEvent = mdmContext.getMdmLinkChangeEvent();
Optional<MdmLink> mdmLinkBySource = myMdmLinkDaoSvc.findMdmLinkBySource(targetResource);
if (!mdmLinkBySource.isPresent()) {
ourLog.warn("Unable to find link by source for {}", targetResource.getIdElement());
}
mdmLinkBySource.ifPresent(link -> {
linkChangeEvent.setMdmMatchResult(link.getMatchResult());
linkChangeEvent.setMdmLinkSource(link.getLinkSource());
linkChangeEvent.setEidMatch(link.isEidMatchPresent());
linkChangeEvent.setNewGoldenResource(link.getHadToCreateNewGoldenResource());
linkChangeEvent.setScore(link.getScore());
linkChangeEvent.setRuleCount(link.getRuleCount());
});
mdmLinkBySource.ifPresent(link -> linkChangeEvent.setFromLink(myModelConverter.toJson(link)));
HookParams params = new HookParams()
.add(ResourceOperationMessage.class, outgoingMsg)
.add(TransactionLogMessages.class, mdmContext.getTransactionLogMessages())
.add(MdmLinkChangeEvent.class, mdmContext.getMdmLinkChangeEvent());
.add(MdmLinkEvent.class, mdmContext.getMdmLinkChangeEvent());
myInterceptorBroadcaster.callHooks(Pointcut.MDM_AFTER_PERSISTED_RESOURCE_CHECKED, params);
}

View File

@ -31,15 +31,17 @@ import ca.uhn.fhir.jpa.mdm.dao.MdmLinkFactory;
import ca.uhn.fhir.jpa.mdm.interceptor.IMdmStorageInterceptor;
import ca.uhn.fhir.jpa.mdm.interceptor.MdmStorageInterceptor;
import ca.uhn.fhir.jpa.mdm.svc.GoldenResourceMergerSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.IMdmModelConverterSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmClearSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmControllerSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmEidUpdateService;
import ca.uhn.fhir.jpa.mdm.svc.MdmGoldenResourceDeletingSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmLinkQuerySvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmLinkQuerySvcImplSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmLinkSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmLinkUpdaterSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmMatchFinderSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmModelConverterSvcImpl;
import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmResourceFilteringSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmSearchParamSvc;
@ -179,7 +181,12 @@ public class MdmConsumerConfig {
@Bean
IMdmLinkQuerySvc mdmLinkQuerySvc() {
return new MdmLinkQuerySvcImpl();
return new MdmLinkQuerySvcImplSvc();
}
@Bean
IMdmModelConverterSvc mdmModelConverterSvc() {
return new MdmModelConverterSvcImpl();
}
@Bean

View File

@ -0,0 +1,39 @@
package ca.uhn.fhir.jpa.mdm.svc;
/*-
* #%L
* HAPI FHIR JPA Server - 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%
*/
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
/**
* Contract for decoupling API dependency from the base / JPA modules.
*/
public interface IMdmModelConverterSvc {
/**
* Creates JSON representation of the provided MDM link
*
* @param theLink Link to convert
* @return Returns the converted link
*/
public MdmLinkJson toJson(MdmLink theLink);
}

View File

@ -36,20 +36,24 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
public class MdmLinkQuerySvcImpl implements IMdmLinkQuerySvc {
public class MdmLinkQuerySvcImplSvc implements IMdmLinkQuerySvc {
private static final Logger ourLog = LoggerFactory.getLogger(MdmLinkQuerySvcImpl.class);
private static final Logger ourLog = LoggerFactory.getLogger(MdmLinkQuerySvcImplSvc.class);
@Autowired
MdmLinkDaoSvc myMdmLinkDaoSvc;
@Autowired
IdHelperService myIdHelperService;
@Autowired
MdmLinkDaoSvc myMdmLinkDaoSvc;
IMdmModelConverterSvc myMdmModelConverterSvc;
@Override
public Page<MdmLinkJson> queryLinks(IIdType theGoldenResourceId, IIdType theSourceResourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) {
Example<MdmLink> exampleLink = exampleLinkFromParameters(theGoldenResourceId, theSourceResourceId, theMatchResult, theLinkSource);
Page<MdmLink> mdmLinkByExample = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest);
Page<MdmLinkJson> map = mdmLinkByExample.map(this::toJson);
Page<MdmLinkJson> map = mdmLinkByExample.map(myMdmModelConverterSvc::toJson);
return map;
}
@ -57,28 +61,10 @@ public class MdmLinkQuerySvcImpl implements IMdmLinkQuerySvc {
public Page<MdmLinkJson> getDuplicateGoldenResources(MdmTransactionContext theMdmContext, MdmPageRequest thePageRequest) {
Example<MdmLink> exampleLink = exampleLinkFromParameters(null, null, MdmMatchResultEnum.POSSIBLE_DUPLICATE, null);
Page<MdmLink> mdmLinkPage = myMdmLinkDaoSvc.findMdmLinkByExample(exampleLink, thePageRequest);
Page<MdmLinkJson> map = mdmLinkPage.map(this::toJson);
Page<MdmLinkJson> map = mdmLinkPage.map(myMdmModelConverterSvc::toJson);
return map;
}
private MdmLinkJson toJson(MdmLink theLink) {
MdmLinkJson retval = new MdmLinkJson();
String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue();
retval.setSourceId(sourceId);
String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue();
retval.setGoldenResourceId(goldenResourceId);
retval.setCreated(theLink.getCreated());
retval.setEidMatch(theLink.getEidMatch());
retval.setLinkSource(theLink.getLinkSource());
retval.setMatchResult(theLink.getMatchResult());
retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource());
retval.setScore(theLink.getScore());
retval.setUpdated(theLink.getUpdated());
retval.setVector(theLink.getVector());
retval.setVersion(theLink.getVersion());
return retval;
}
private Example<MdmLink> exampleLinkFromParameters(IIdType theGoldenResourceId, IIdType theSourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource) {
MdmLink mdmLink = myMdmLinkDaoSvc.newMdmLink();
if (theGoldenResourceId != null) {

View File

@ -0,0 +1,52 @@
package ca.uhn.fhir.jpa.mdm.svc;
/*-
* #%L
* HAPI FHIR JPA Server - 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%
*/
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkJson;
import org.springframework.beans.factory.annotation.Autowired;
public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc {
@Autowired
IdHelperService myIdHelperService;
public MdmLinkJson toJson(MdmLink theLink) {
MdmLinkJson retval = new MdmLinkJson();
String sourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getSourcePid()).toVersionless().getValue();
retval.setSourceId(sourceId);
String goldenResourceId = myIdHelperService.resourceIdFromPidOrThrowException(theLink.getGoldenResourcePid()).toVersionless().getValue();
retval.setGoldenResourceId(goldenResourceId);
retval.setCreated(theLink.getCreated());
retval.setEidMatch(theLink.getEidMatch());
retval.setLinkSource(theLink.getLinkSource());
retval.setMatchResult(theLink.getMatchResult());
retval.setLinkCreatedNewResource(theLink.getHadToCreateNewGoldenResource());
retval.setScore(theLink.getScore());
retval.setUpdated(theLink.getUpdated());
retval.setVector(theLink.getVector());
retval.setVersion(theLink.getVersion());
retval.setRuleCount(theLink.getRuleCount());
return retval;
}
}

View File

@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent;
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
import ca.uhn.fhir.mdm.model.CanonicalEID;
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.rules.config.MdmSettings;
@ -32,14 +32,11 @@ import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Pageable;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD;
import static ca.uhn.fhir.mdm.api.MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED;
@ -89,7 +86,7 @@ public class MdmStorageInterceptorIT extends BaseMdmR4Test {
MdmLink link = getLinkByTargetId(pr);
MdmLinkChangeEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkChangeEvent.class);
MdmLinkEvent linkChangeEvent = myMdmHelper.getAfterMdmLatch().getLatchInvocationParameterOfType(MdmLinkEvent.class);
assertNotNull(linkChangeEvent);
assertEquals(link.getGoldenResourcePid(), new IdDt(linkChangeEvent.getGoldenResourceId()).getIdPartAsLong());
assertEquals(link.getSourcePid(), new IdDt(linkChangeEvent.getTargetResourceId()).getIdPartAsLong());

View File

@ -28,7 +28,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
import java.util.HashSet;
import java.util.Set;
public class MdmLinkChangeEvent implements IModelJson {
public class MdmLinkEvent implements IModelJson {
@JsonProperty(value = "matchResult")
private MdmMatchResultEnum myMdmMatchResult;
@ -92,7 +92,7 @@ public class MdmLinkChangeEvent implements IModelJson {
myDuplicateGoldenResourceIds = theDuplicateGoldenResourceIds;
}
public MdmLinkChangeEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) {
public MdmLinkEvent addDuplicateGoldenResourceId(IBaseResource theDuplicateGoldenResourceId) {
String id = getIdAsString(theDuplicateGoldenResourceId);
if (id != null) {
getDuplicateGoldenResourceIds().add(id);
@ -121,6 +121,10 @@ public class MdmLinkChangeEvent implements IModelJson {
}
public void setEidMatch(Boolean theEidMatch) {
if (theEidMatch == null) {
myEidMatch = Boolean.FALSE;
return;
}
myEidMatch = theEidMatch;
}
@ -129,6 +133,10 @@ public class MdmLinkChangeEvent implements IModelJson {
}
public void setNewGoldenResource(Boolean theNewGoldenResource) {
if (theNewGoldenResource == null) {
myNewGoldenResource = Boolean.FALSE;
return;
}
myNewGoldenResource = theNewGoldenResource;
}
@ -148,6 +156,15 @@ public class MdmLinkChangeEvent implements IModelJson {
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
public String toString() {
return "MdmLinkChangeEvent{" +

View File

@ -48,11 +48,15 @@ public class MdmLinkJson implements IModelJson {
@JsonProperty("version")
private String myVersion;
/** This link was created as a result of an eid match **/
/**
* This link was created as a result of an eid match
**/
@JsonProperty("eidMatch")
private Boolean myEidMatch;
/** This link created a new golden resource **/
/**
* This link created a new golden resource
**/
@JsonProperty("linkCreatedNewGoldenResource")
private Boolean myLinkCreatedNewResource;
@ -62,6 +66,9 @@ public class MdmLinkJson implements IModelJson {
@JsonProperty("score")
private Double myScore;
@JsonProperty("ruleCount")
private Long myRuleCount;
public String getGoldenResourceId() {
return myGoldenResourceId;
}
@ -160,4 +167,12 @@ public class MdmLinkJson implements IModelJson {
myScore = theScore;
return this;
}
public Long getRuleCount() {
return myRuleCount;
}
public void setRuleCount(Long theRuleCount) {
myRuleCount = theRuleCount;
}
}

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.mdm.model;
* #L%
*/
import ca.uhn.fhir.mdm.api.MdmLinkChangeEvent;
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
import ca.uhn.fhir.rest.server.TransactionLogMessages;
public class MdmTransactionContext {
@ -46,7 +46,7 @@ public class MdmTransactionContext {
private String myResourceType;
private MdmLinkChangeEvent myMdmLinkChangeEvent = new MdmLinkChangeEvent();
private MdmLinkEvent myMdmLinkEvent = new MdmLinkEvent();
public TransactionLogMessages getTransactionLogMessages() {
return myTransactionLogMessages;
@ -96,12 +96,12 @@ public class MdmTransactionContext {
this.myResourceType = myResourceType;
}
public MdmLinkChangeEvent getMdmLinkChangeEvent() {
return myMdmLinkChangeEvent;
public MdmLinkEvent getMdmLinkChangeEvent() {
return myMdmLinkEvent;
}
public void setMdmLinkChangeEvent(MdmLinkChangeEvent theMdmLinkChangeEvent) {
myMdmLinkChangeEvent = theMdmLinkChangeEvent;
public void setMdmLinkChangeEvent(MdmLinkEvent theMdmLinkEvent) {
myMdmLinkEvent = theMdmLinkEvent;
}
}