All Batch tests now passing

This commit is contained in:
Tadgh 2020-11-16 12:50:28 -05:00
parent 514dab7784
commit 54f0021b29
11 changed files with 50 additions and 43 deletions

View File

@ -21,9 +21,9 @@ package ca.uhn.fhir.jpa.empi.broker;
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.IEmpiSettings;
import ca.uhn.fhir.empi.log.Logs;
import ca.uhn.fhir.empi.model.MdmTransactionContext;
import ca.uhn.fhir.empi.util.EmpiUtil;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
@ -54,6 +54,8 @@ public class EmpiMessageHandler implements MessageHandler {
private FhirContext myFhirContext;
@Autowired
private EmpiResourceFilteringSvc myEmpiResourceFilteringSvc;
@Autowired
private IEmpiSettings myEmpiSettings;
@Override
public void handleMessage(Message<?> theMessage) throws MessagingException {
@ -128,7 +130,7 @@ public class EmpiMessageHandler implements MessageHandler {
}
private void validateResourceType(String theResourceType) {
if (!EmpiUtil.supportedTargetType(theResourceType)) {
if (!myEmpiSettings.isSupportedMdmType(theResourceType)) {
throw new IllegalStateException("Unsupported resource type submitted to EMPI matching queue: " + theResourceType);
}
}

View File

@ -174,8 +174,8 @@ public class EmpiConsumerConfig {
}
@Bean
IEmpiExpungeSvc empiResetSvc(EmpiLinkDaoSvc theEmpiLinkDaoSvc, EmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl) {
return new EmpiClearSvcImpl(theEmpiLinkDaoSvc, theEmpiPersonDeletingSvcImpl);
IEmpiExpungeSvc empiResetSvc(EmpiLinkDaoSvc theEmpiLinkDaoSvc, EmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl, IEmpiSettings theIEmpiSettings) {
return new EmpiClearSvcImpl(theEmpiLinkDaoSvc, theEmpiPersonDeletingSvcImpl, theIEmpiSettings);
}
@Bean

View File

@ -231,14 +231,20 @@ public class EmpiLinkDaoSvc {
* @return A list of Long representing the related Person Pids.
*/
@Transactional
public List<Long> deleteAllEmpiLinksAndReturnPersonPids() {
public List<Long> deleteAllEmpiLinksAndReturnGoldenResourcePids() {
List<EmpiLink> all = myEmpiLinkDao.findAll();
return deleteEmpiLinksAndReturnPersonPids(all);
return deleteEmpiLinksAndReturnGoldenResourcePids(all);
}
private List<Long> deleteEmpiLinksAndReturnPersonPids(List<EmpiLink> theLinks) {
private List<Long> deleteEmpiLinksAndReturnGoldenResourcePids(List<EmpiLink> theLinks) {
Set<Long> persons = theLinks.stream().map(EmpiLink::getSourceResourcePid).collect(Collectors.toSet());
persons.addAll(theLinks.stream().filter(link -> "Person".equals(link.getEmpiTargetType())).map(EmpiLink::getTargetPid).collect(Collectors.toSet()));
//TODO GGG this is probably invalid... we are essentially looking for GOLDEN -> GOLDEN links, which are either POSSIBLE_DUPLICATE
//and REDIRECT
//persons.addAll(theLinks.stream().filter(link -> "Person".equals(link.getEmpiTargetType())).map(EmpiLink::getTargetPid).collect(Collectors.toSet()));
persons.addAll(theLinks.stream()
.filter(link -> link.getMatchResult().equals(EmpiMatchResultEnum.REDIRECT)
|| link.getMatchResult().equals(EmpiMatchResultEnum.POSSIBLE_DUPLICATE))
.map(EmpiLink::getTargetPid).collect(Collectors.toSet()));
ourLog.info("Deleting {} EMPI link records...", theLinks.size());
myEmpiLinkDao.deleteAll(theLinks);
ourLog.info("{} EMPI link records deleted", theLinks.size());
@ -257,7 +263,7 @@ public class EmpiLinkDaoSvc {
link.setEmpiTargetType(theTargetType);
Example<EmpiLink> exampleLink = Example.of(link);
List<EmpiLink> allOfType = myEmpiLinkDao.findAll(exampleLink);
return deleteEmpiLinksAndReturnPersonPids(allOfType);
return deleteEmpiLinksAndReturnGoldenResourcePids(allOfType);
}
/**

View File

@ -21,8 +21,8 @@ package ca.uhn.fhir.jpa.empi.svc;
*/
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiSettings;
import ca.uhn.fhir.empi.log.Logs;
import ca.uhn.fhir.empi.util.EmpiUtil;
import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome;
import ca.uhn.fhir.jpa.empi.dao.EmpiLinkDaoSvc;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -42,11 +42,13 @@ public class EmpiClearSvcImpl implements IEmpiExpungeSvc {
final EmpiLinkDaoSvc myEmpiLinkDaoSvc;
final EmpiPersonDeletingSvc myEmpiPersonDeletingSvcImpl;
final IEmpiSettings myEmpiSettings;
@Autowired
public EmpiClearSvcImpl(EmpiLinkDaoSvc theEmpiLinkDaoSvc, EmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl) {
public EmpiClearSvcImpl(EmpiLinkDaoSvc theEmpiLinkDaoSvc, EmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl, IEmpiSettings theIEmpiSettings) {
myEmpiLinkDaoSvc = theEmpiLinkDaoSvc;
myEmpiPersonDeletingSvcImpl = theEmpiPersonDeletingSvcImpl;
myEmpiSettings = theIEmpiSettings;
}
@Override
@ -60,7 +62,7 @@ public class EmpiClearSvcImpl implements IEmpiExpungeSvc {
}
private void throwExceptionIfInvalidTargetType(String theResourceType) {
if (!EmpiUtil.supportedTargetType(theResourceType)) {
if (!myEmpiSettings.isSupportedMdmType(theResourceType)) {
throw new InvalidRequestException(ProviderConstants.MDM_CLEAR + " does not support resource type: " + theResourceType);
}
}
@ -68,7 +70,7 @@ public class EmpiClearSvcImpl implements IEmpiExpungeSvc {
@Override
public long expungeAllEmpiLinks(ServletRequestDetails theRequestDetails) {
ourLog.info("Clearing all EMPI Links...");
List<Long> personPids = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids();
List<Long> personPids = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnGoldenResourcePids();
DeleteMethodOutcome deleteOutcome = myEmpiPersonDeletingSvcImpl.expungePersonPids(personPids, theRequestDetails);
ourLog.info("EMPI clear operation complete. Removed {} EMPI links and expunged {} Person resources.", personPids.size(), deleteOutcome.getExpungedResourcesCount());
return personPids.size();

View File

@ -21,9 +21,9 @@ package ca.uhn.fhir.jpa.empi.svc;
*/
import ca.uhn.fhir.empi.api.IEmpiChannelSubmitterSvc;
import ca.uhn.fhir.empi.api.IEmpiSettings;
import ca.uhn.fhir.empi.api.IEmpiSubmitSvc;
import ca.uhn.fhir.empi.log.Logs;
import ca.uhn.fhir.empi.util.EmpiUtil;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
@ -61,14 +61,18 @@ public class EmpiSubmitSvcImpl implements IEmpiSubmitSvc {
@Autowired
private IEmpiChannelSubmitterSvc myEmpiChannelSubmitterSvc;
@Autowired
private IEmpiSettings myEmpiSettings;
private static final int BUFFER_SIZE = 100;
@Override
@Transactional
public long submitAllTargetTypesToEmpi(@Nullable String theCriteria) {
long submittedCount = 0;
submittedCount += submitPatientTypeToMdm(theCriteria);
submittedCount += submitPractitionerTypeToMdm(theCriteria);
long submittedCount = myEmpiSettings.getEmpiRules().getMdmTypes().stream()
.mapToLong(targetType -> submitTargetTypeToEmpi(targetType, theCriteria))
.sum();
return submittedCount;
}
@ -80,7 +84,8 @@ public class EmpiSubmitSvcImpl implements IEmpiSubmitSvc {
} else {
ourLog.info("Submitting resources of type {} with criteria {} to EMPI", theTargetType, theCriteria);
}
resolveTargetTypeOrThrowException(theTargetType);
validateTargetType(theTargetType);
SearchParameterMap spMap = myEmpiSearchParamSvc.getSearchParameterMapFromCriteria(theTargetType, theCriteria);
spMap.setLoadSynchronousUpTo(BUFFER_SIZE);
ISearchBuilder searchBuilder = myEmpiSearchParamSvc.generateSearchBuilderForType(theTargetType);
@ -136,15 +141,15 @@ public class EmpiSubmitSvcImpl implements IEmpiSubmitSvc {
@Override
@Transactional
public long submitTargetToMdm(IIdType theId) {
resolveTargetTypeOrThrowException(theId.getResourceType());
validateTargetType(theId.getResourceType());
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theId.getResourceType());
IBaseResource read = resourceDao.read(theId);
myEmpiChannelSubmitterSvc.submitResourceToEmpiChannel(read);
return 1;
}
private void resolveTargetTypeOrThrowException(String theResourceType) {
if (!EmpiUtil.supportedTargetType(theResourceType)) {
private void validateTargetType(String theResourceType) {
if(!myEmpiSettings.getEmpiRules().getMdmTypes().contains(theResourceType)) {
throw new InvalidRequestException(ProviderConstants.OPERATION_MDM_SUBMIT + " does not support resource type: " + theResourceType);
}
}

View File

@ -103,7 +103,7 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test {
@Test
public void testBatchRunOnAllPatients() throws InterruptedException {
assertLinkCount(2);
assertLinkCount(3);
StringType criteria = null;
myEmpiProviderR4.clearEmpiLinks(null, myRequestDetails);
afterEmpiLatch.runWithExpectedCount(1, () -> myEmpiProviderR4.empiBatchPatientType(criteria, null));
@ -112,7 +112,7 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test {
@Test
public void testBatchRunOnSpecificPatient() throws InterruptedException {
assertLinkCount(2);
assertLinkCount(3);
myEmpiProviderR4.clearEmpiLinks(null, myRequestDetails);
afterEmpiLatch.runWithExpectedCount(1, () -> myEmpiProviderR4.empiBatchPatientInstance(myPatient.getIdElement(), null));
assertLinkCount(1);
@ -120,7 +120,7 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test {
@Test
public void testBatchRunOnNonExistentSpecificPatient() {
assertLinkCount(2);
assertLinkCount(3);
myEmpiProviderR4.clearEmpiLinks(null, myRequestDetails);
try {
myEmpiProviderR4.empiBatchPatientInstance(new IdType("Patient/999"), null);
@ -130,18 +130,18 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test {
@Test
public void testBatchRunOnAllTypes() throws InterruptedException {
assertLinkCount(2);
assertLinkCount(3);
StringType criteria = new StringType("");
myEmpiProviderR4.clearEmpiLinks(null, myRequestDetails);
afterEmpiLatch.runWithExpectedCount(2, () -> {
afterEmpiLatch.runWithExpectedCount(3, () -> {
myEmpiProviderR4.empiBatchOnAllTargets(null, criteria, null);
});
assertLinkCount(2);
assertLinkCount(3);
}
@Test
public void testBatchRunOnAllTypesWithInvalidCriteria() {
assertLinkCount(2);
assertLinkCount(3);
StringType criteria = new StringType("death-date=2020-06-01");
myEmpiProviderR4.clearEmpiLinks(null, myRequestDetails);

View File

@ -1,4 +1,5 @@
{
"mdmTypes": ["Patient", "Practitioner"],
"version": "1",
"candidateSearchParams": [],
"candidateFilterSearchParams": [

View File

@ -21,7 +21,6 @@ package ca.uhn.fhir.empi.api;
*/
import ca.uhn.fhir.empi.rules.json.EmpiRulesJson;
import org.hl7.fhir.instance.model.api.IAnyResource;
import java.util.stream.Collectors;
@ -46,7 +45,7 @@ public interface IEmpiSettings {
return getEmpiRules().getMdmTypes().contains(theResourceName);
}
default String getSupportedMdmTypeNames() {
default String getSupportedMdmTypes() {
return getEmpiRules().getMdmTypes().stream().collect(Collectors.joining(", "));
}
}

View File

@ -22,7 +22,6 @@ package ca.uhn.fhir.empi.provider;
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.util.EmpiUtil;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IIdType;
@ -67,10 +66,8 @@ public class EmpiControllerUtil {
public static IIdType getTargetIdDtOrThrowException(String theParamName, String theId) {
IdDt targetId = new IdDt(theId);
String resourceType = targetId.getResourceType();
if (!EmpiUtil.supportedTargetType(resourceType) ||
targetId.getIdPart() == null) {
throw new InvalidRequestException(theParamName + " is '" + theId + "'. must have form Patient/<id> or Practitioner/<id> where <id> is the id of the resource");
if (targetId.getIdPart() == null) {
throw new InvalidRequestException(theParamName + " is '" + theId + "'. must have form <resourceType>/<id> where <id> is the id of the resource and <resourceType> is the type of the resource");
}
return targetId;
}

View File

@ -31,9 +31,6 @@ import java.util.Optional;
public final class EmpiUtil {
private EmpiUtil() {}
public static boolean supportedTargetType(String theResourceType) {
return ("Patient".equals(theResourceType) || "Practitioner".equals(theResourceType));
}
public static boolean isEmpiResourceType(FhirContext theFhirContext, IBaseResource theResource) {
String resourceType = theFhirContext.getResourceType(theResource);

View File

@ -3,11 +3,9 @@ package ca.uhn.fhir.empi.util;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.EmpiConstants;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiSettings;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -37,7 +35,7 @@ public class MessageHelper {
public String getMessageForUnsupportedResource(String theName, String theResourceType) {
return String.format("Only %s resources can be merged. The %s points to a %s",
myEmpiSettings.getSupportedMdmTypeNames(), theName, theResourceType);
myEmpiSettings.getSupportedMdmTypes(), theName, theResourceType);
}
public String getMessageForUnsupportedMatchResult() {
@ -46,12 +44,12 @@ public class MessageHelper {
public String getMessageForUnsupportedFirstArgumentTypeInUpdate(String goldenRecordType) {
return "First argument to " + ProviderConstants.MDM_UPDATE_LINK + " must be a "
+ myEmpiSettings.getSupportedMdmTypeNames() + ". Was " + goldenRecordType;
+ myEmpiSettings.getSupportedMdmTypes() + ". Was " + goldenRecordType;
}
public String getMessageForUnsupportedSecondArgumentTypeInUpdate(String theGoldenRecordType) {
return "First argument to " + ProviderConstants.MDM_UPDATE_LINK + " must be a "
+ myEmpiSettings.getSupportedMdmTypeNames() + ". Was " + theGoldenRecordType;
+ myEmpiSettings.getSupportedMdmTypes() + ". Was " + theGoldenRecordType;
}
public String getMessageForArgumentTypeMismatchInUpdate(String theGoldenRecordType, String theTargetType) {