Get basic tests running

This commit is contained in:
Tadgh 2020-07-09 15:56:41 -07:00
parent 5a7e1de367
commit c3b89b4ad5
14 changed files with 237 additions and 8 deletions

View File

@ -79,6 +79,7 @@ public class EmpiMessageHandler implements MessageHandler {
handleCreatePatientOrPractitioner(theMsg, empiContext);
break;
case UPDATE:
case MANUALLY_TRIGGERED:
handleUpdatePatientOrPractitioner(theMsg, empiContext);
break;
case DELETE:
@ -106,6 +107,9 @@ public class EmpiMessageHandler implements MessageHandler {
case UPDATE:
empiOperation = EmpiTransactionContext.OperationType.UPDATE;
break;
case MANUALLY_TRIGGERED:
empiOperation = EmpiTransactionContext.OperationType.BATCH;
break;
case DELETE:
default:
ourLog.trace("Not creating an EmpiTransactionContext for {}", theMsg.getOperationType());

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.empi.config;
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiLinkSvc;
@ -38,6 +39,7 @@ import ca.uhn.fhir.jpa.empi.broker.EmpiMessageHandler;
import ca.uhn.fhir.jpa.empi.broker.EmpiQueueConsumerLoader;
import ca.uhn.fhir.jpa.empi.interceptor.EmpiStorageInterceptor;
import ca.uhn.fhir.jpa.empi.interceptor.IEmpiStorageInterceptor;
import ca.uhn.fhir.jpa.empi.svc.EmpiBatchSvcImpl;
import ca.uhn.fhir.jpa.empi.svc.EmpiCandidateSearchCriteriaBuilderSvc;
import ca.uhn.fhir.jpa.empi.svc.EmpiCandidateSearchSvc;
import ca.uhn.fhir.jpa.empi.svc.EmpiEidUpdateService;
@ -93,6 +95,10 @@ public class EmpiConsumerConfig {
EmpiMatchLinkSvc empiMatchLinkSvc() {
return new EmpiMatchLinkSvc();
}
@Bean
IEmpiBatchService myEmpiBatchService() {
return new EmpiBatchSvcImpl();
}
@Bean
EmpiEidUpdateService eidUpdateService() {

View File

@ -0,0 +1,83 @@
package ca.uhn.fhir.jpa.empi.svc;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.entity.EmpiTargetType;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.subscription.channel.api.ChannelProducerSettings;
import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory;
import ca.uhn.fhir.jpa.subscription.channel.subscription.IChannelNamer;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.MessageChannel;
import javax.annotation.PostConstruct;
import java.util.List;
import static ca.uhn.fhir.empi.api.IEmpiSettings.EMPI_CHANNEL_NAME;
public class EmpiBatchSvcImpl implements IEmpiBatchService {
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private EmpiMatchLinkSvc myEmpiMatchLinkSvc;
@Autowired
private IChannelNamer myChannelNamer;
private MessageChannel myEmpiChannelProducer;
@Autowired
private FhirContext myFhirContext;
@Autowired
private IChannelFactory myChannelFactory;
@Override
public void runEmpiOnAllTargets() {
runEmpiOnTargetType("Patient");
runEmpiOnTargetType("Practitioner");
}
@Override
public void runEmpiOnTargetType(String theTargetType) {
getTargetTypeOrThrowException(theTargetType);
IFhirResourceDao patientDao = myDaoRegistry.getResourceDao(theTargetType);
IBundleProvider search = patientDao.search(new SearchParameterMap().setLoadSynchronous(true));
List<IBaseResource> resources = search.getResources(0, search.size());
for (IBaseResource resource : resources) {
ResourceModifiedJsonMessage rmjm = new ResourceModifiedJsonMessage();
ResourceModifiedMessage resourceModifiedMessage = new ResourceModifiedMessage(myFhirContext, resource, ResourceModifiedMessage.OperationTypeEnum.MANUALLY_TRIGGERED);
resourceModifiedMessage.setOperationType(ResourceModifiedMessage.OperationTypeEnum.MANUALLY_TRIGGERED);
rmjm.setPayload(resourceModifiedMessage);
myEmpiChannelProducer.send(rmjm);
}
}
private EmpiTargetType getTargetTypeOrThrowException(String theResourceType) {
if (theResourceType.equalsIgnoreCase("Patient")) {
return EmpiTargetType.PATIENT;
} else if(theResourceType.equalsIgnoreCase("Practitioner")) {
return EmpiTargetType.PRACTITIONER;
} else {
throw new InvalidRequestException(ProviderConstants.EMPI_BATCH_RUN+ " does not support resource type: " + theResourceType);
}
}
@PostConstruct
private void init() {
ChannelProducerSettings channelSettings = new ChannelProducerSettings();
String channelName = myChannelNamer.getChannelName(EMPI_CHANNEL_NAME, channelSettings);
myEmpiChannelProducer= myChannelFactory.getOrCreateProducer(channelName, ResourceModifiedJsonMessage.class, channelSettings);
}
}

View File

@ -51,7 +51,6 @@ public class EmpiExpungeSvcImpl implements IEmpiExpungeSvc {
public void expungeEmpiLinks(String theResourceType) {
EmpiTargetType targetType = getTargetTypeOrThrowException(theResourceType);
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksOfTypeAndReturnPersonPids(targetType);
//TODO this expunge does not work!
myResourceExpungeService.expungeCurrentVersionOfResources(null, longs, new AtomicInteger(longs.size()));
}
@ -68,7 +67,7 @@ public class EmpiExpungeSvcImpl implements IEmpiExpungeSvc {
@Override
public void expungeEmpiLinks() {
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids();
myResourceExpungeService.expungeHistoricalVersionsOfIds(null, longs, new AtomicInteger(longs.size()));
myResourceExpungeService.expungeCurrentVersionOfResources(null, longs, new AtomicInteger(longs.size()));
}
}

View File

@ -154,6 +154,14 @@ abstract public class BaseEmpiR4Test extends BaseJpaR4Test {
patient.setId(outcome.getId());
return patient;
}
@Nonnull
protected Practitioner createPractitioner(Practitioner thePractitioner) {
//Note that since our empi-rules block on active=true, all patients must be active.
thePractitioner.setActive(true);
DaoMethodOutcome daoMethodOutcome = myPractitionerDao.create(thePractitioner);
thePractitioner.setId(daoMethodOutcome.getId());
return thePractitioner;
}
@Nonnull
protected Patient buildPatientWithNameAndId(String theGivenName, String theId) {

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.empi.helper;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.provider.EmpiProviderR4;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
@ -14,9 +15,18 @@ public class EmpiHelperR4 extends BaseEmpiHelper {
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private EmpiProviderR4 myEmpiProviderR4;
public OutcomeAndLogMessageWrapper createWithLatch(IBaseResource theResource) throws InterruptedException {
return createWithLatch(theResource, true);
}
public OutcomeAndLogMessageWrapper batchWithLatch(int expectedRuns) throws InterruptedException {
myAfterEmpiLatch.setExpectedCount(expectedRuns);
myEmpiProviderR4.batchRunEmpi(null, null);
myAfterEmpiLatch.awaitExpected();
return new OutcomeAndLogMessageWrapper(null, null);
}
public OutcomeAndLogMessageWrapper createWithLatch(IBaseResource theBaseResource, boolean isExternalHttpRequest) throws InterruptedException {
myAfterEmpiLatch.setExpectedCount(1);

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.empi.provider;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiLinkUpdaterSvc;
@ -25,9 +26,11 @@ public abstract class BaseProviderR4Test extends BaseEmpiR4Test {
private IResourceLoader myResourceLoader;
@Autowired
private IEmpiExpungeSvc myEmpiExpungeSvc;
@Autowired
private IEmpiBatchService myEmpiBatchSvc;
@BeforeEach
public void before() {
myEmpiProviderR4 = new EmpiProviderR4(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc);
myEmpiProviderR4 = new EmpiProviderR4(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc, myEmpiBatchSvc);
}
}

View File

@ -0,0 +1,88 @@
package ca.uhn.fhir.jpa.empi.svc;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.empi.BaseEmpiR4Test;
import ca.uhn.test.concurrency.PointcutLatch;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
class EmpiBatchSvcImplTest extends BaseEmpiR4Test {
@Autowired
EmpiBatchSvcImpl myEmpiBatchSvc;
@Autowired
IInterceptorService myInterceptorService;
PointcutLatch afterEmpiLatch = new PointcutLatch(Pointcut.EMPI_AFTER_PERSISTED_RESOURCE_CHECKED);
@BeforeEach
public void before() {
myInterceptorService.registerAnonymousInterceptor(Pointcut.EMPI_AFTER_PERSISTED_RESOURCE_CHECKED, afterEmpiLatch);
}
@AfterEach
public void after() {
myInterceptorService.unregisterInterceptor(afterEmpiLatch);
afterEmpiLatch.clear();
super.after();
}
@Test
public void testEmpiBatchRunWorksOverMultipleTargetTypes() throws InterruptedException {
for (int i =0; i < 10; i++) {
createPatient(buildJanePatient());
}
for(int i = 0; i< 10; i++) {
createPractitioner(buildPractitionerWithNameAndId("test", "id"));
}
assertLinkCount(0);
afterEmpiLatch.setExpectedCount(20);
//SUT
myEmpiBatchSvc.runEmpiOnAllTargets();
afterEmpiLatch.awaitExpected();
assertLinkCount(20);
}
@Test
public void testEmpiBatchOnPatientType() throws Exception {
for (int i =0; i < 10; i++) {
createPractitioner(buildPractitionerWithNameAndId("test", "id"));
}
assertLinkCount(0);
afterEmpiLatch.setExpectedCount(10);
//SUT
myEmpiBatchSvc.runEmpiOnAllTargets();
afterEmpiLatch.awaitExpected();
assertLinkCount(10);
}
@Test
public void testEmpiBatchOnPractitionerType() throws Exception {
for (int i =0; i < 10; i++) {
createPractitioner(buildPractitionerWithNameAndId("test", "id"));
}
assertLinkCount(0);
afterEmpiLatch.setExpectedCount(10);
//SUT
myEmpiBatchSvc.runEmpiOnAllTargets();
afterEmpiLatch.awaitExpected();
assertLinkCount(10);
}
}

View File

@ -160,7 +160,6 @@ public class ResourceModifiedMessage extends BaseResourceMessage implements IRes
UPDATE,
DELETE,
MANUALLY_TRIGGERED
}
private static boolean payloadContainsNoPlaceholderReferences(FhirContext theCtx, IBaseResource theNewPayload) {

View File

@ -0,0 +1,8 @@
package ca.uhn.fhir.empi.api;
public interface IEmpiBatchService {
void runEmpiOnAllTargets();
void runEmpiOnTargetType(String theTargetType);
}

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.empi.provider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiLinkUpdaterSvc;
@ -54,6 +55,7 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
private final IEmpiLinkUpdaterSvc myEmpiLinkUpdaterSvc;
private final IEmpiLinkQuerySvc myEmpiLinkQuerySvc;
private final IEmpiExpungeSvc myEmpiExpungeSvc;
private final IEmpiBatchService myEmpiBatchService;
/**
* Constructor
@ -61,13 +63,14 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
* Note that this is not a spring bean. Any necessary injections should
* happen in the constructor
*/
public EmpiProviderDstu3(FhirContext theFhirContext, IEmpiMatchFinderSvc theEmpiMatchFinderSvc, IEmpiPersonMergerSvc thePersonMergerSvc, IEmpiLinkUpdaterSvc theEmpiLinkUpdaterSvc, IEmpiLinkQuerySvc theEmpiLinkQuerySvc, IResourceLoader theResourceLoader, IEmpiExpungeSvc theEmpiExpungeSvc) {
public EmpiProviderDstu3(FhirContext theFhirContext, IEmpiMatchFinderSvc theEmpiMatchFinderSvc, IEmpiPersonMergerSvc thePersonMergerSvc, IEmpiLinkUpdaterSvc theEmpiLinkUpdaterSvc, IEmpiLinkQuerySvc theEmpiLinkQuerySvc, IResourceLoader theResourceLoader, IEmpiExpungeSvc theEmpiExpungeSvc, IEmpiBatchService theEmpiBatchSvc) {
super(theFhirContext, theResourceLoader);
myEmpiMatchFinderSvc = theEmpiMatchFinderSvc;
myPersonMergerSvc = thePersonMergerSvc;
myEmpiLinkUpdaterSvc = theEmpiLinkUpdaterSvc;
myEmpiLinkQuerySvc = theEmpiLinkQuerySvc;
myEmpiExpungeSvc = theEmpiExpungeSvc;
myEmpiBatchService = theEmpiBatchSvc;
}
@Operation(name = ProviderConstants.EMPI_MATCH, type = Patient.class)

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.empi.provider;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiLinkUpdaterSvc;
@ -50,14 +51,16 @@ public class EmpiProviderLoader {
private IResourceLoader myResourceLoader;
@Autowired
private IEmpiExpungeSvc myEmpiExpungeSvc;
@Autowired
private IEmpiBatchService myEmpiBatchSvc;
public void loadProvider() {
switch (myFhirContext.getVersion().getVersion()) {
case DSTU3:
myResourceProviderFactory.addSupplier(() -> new EmpiProviderDstu3(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc));
myResourceProviderFactory.addSupplier(() -> new EmpiProviderDstu3(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc, myEmpiBatchSvc));
break;
case R4:
myResourceProviderFactory.addSupplier(() -> new EmpiProviderR4(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc));
myResourceProviderFactory.addSupplier(() -> new EmpiProviderR4(myFhirContext, myEmpiMatchFinderSvc, myPersonMergerSvc, myEmpiLinkUpdaterSvc, myEmpiLinkQuerySvc, myResourceLoader, myEmpiExpungeSvc, myEmpiBatchSvc));
break;
default:
throw new ConfigurationException("EMPI not supported for FHIR version " + myFhirContext.getVersion().getVersion());

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.empi.provider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.empi.api.EmpiLinkSourceEnum;
import ca.uhn.fhir.empi.api.EmpiMatchResultEnum;
import ca.uhn.fhir.empi.api.IEmpiBatchService;
import ca.uhn.fhir.empi.api.IEmpiExpungeSvc;
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
import ca.uhn.fhir.empi.api.IEmpiLinkUpdaterSvc;
@ -54,6 +55,7 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
private final IEmpiLinkUpdaterSvc myEmpiLinkUpdaterSvc;
private final IEmpiLinkQuerySvc myEmpiLinkQuerySvc;
private final IEmpiExpungeSvc myEmpiExpungeSvc;
private final IEmpiBatchService myEmpiBatchSvc;
/**
* Constructor
@ -61,13 +63,14 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
* Note that this is not a spring bean. Any necessary injections should
* happen in the constructor
*/
public EmpiProviderR4(FhirContext theFhirContext, IEmpiMatchFinderSvc theEmpiMatchFinderSvc, IEmpiPersonMergerSvc thePersonMergerSvc, IEmpiLinkUpdaterSvc theEmpiLinkUpdaterSvc, IEmpiLinkQuerySvc theEmpiLinkQuerySvc, IResourceLoader theResourceLoader, IEmpiExpungeSvc theEmpiExpungeSvc) {
public EmpiProviderR4(FhirContext theFhirContext, IEmpiMatchFinderSvc theEmpiMatchFinderSvc, IEmpiPersonMergerSvc thePersonMergerSvc, IEmpiLinkUpdaterSvc theEmpiLinkUpdaterSvc, IEmpiLinkQuerySvc theEmpiLinkQuerySvc, IResourceLoader theResourceLoader, IEmpiExpungeSvc theEmpiExpungeSvc, IEmpiBatchService theEmpiBatchSvc) {
super(theFhirContext, theResourceLoader);
myEmpiMatchFinderSvc = theEmpiMatchFinderSvc;
myPersonMergerSvc = thePersonMergerSvc;
myEmpiLinkUpdaterSvc = theEmpiLinkUpdaterSvc;
myEmpiLinkQuerySvc = theEmpiLinkQuerySvc;
myEmpiExpungeSvc = theEmpiExpungeSvc;
myEmpiBatchSvc = theEmpiBatchSvc;
}
@Operation(name = ProviderConstants.EMPI_MATCH, type = Patient.class)
@ -162,4 +165,13 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
return (Parameters) myEmpiLinkUpdaterSvc.notDuplicatePerson(person, target, createEmpiContext(theRequestDetails));
}
@Operation(name = ProviderConstants.EMPI_BATCH_RUN, idempotent = true)
public void batchRunEmpi(@OperationParam(name= ProviderConstants.EMPI_BATCH_RUN_TARGET_TYPE, max=1) StringType theTargetType, ServletRequestDetails theRequestDetails) {
if (theTargetType == null) {
myEmpiBatchSvc.runEmpiOnAllTargets();
} else {
myEmpiBatchSvc.runEmpiOnTargetType(theTargetType.toString());
}
}
}

View File

@ -84,4 +84,7 @@ public class ProviderConstants {
public static final String EMPI_CLEAR = "$empi-clear";
public static final String EMPI_CLEAR_TARGET_TYPE = "targetType";
public static final String EMPI_BATCH_RUN = "$empi-run";
public static final String EMPI_BATCH_RUN_TARGET_TYPE = "targetType" ;
public static final String EMPI_BATCH_RUN_RESOURCE_IDS = "resourceIds" ;
}