Turns out expunge atomic integer didn't do what I expected for historical versions...

This commit is contained in:
Tadgh 2020-07-27 17:29:27 -07:00
parent 82dcc395ec
commit 606b642b1e
5 changed files with 47 additions and 39 deletions

View File

@ -238,7 +238,7 @@ public class EmpiLinkDaoSvc {
} }
private List<Long> deleteEmpiLinksAndReturnPersonPids(List<EmpiLink> theLinks) { private List<Long> deleteEmpiLinksAndReturnPersonPids(List<EmpiLink> theLinks) {
List<Long> collect = theLinks.stream().map(EmpiLink::getPersonPid).collect(Collectors.toList()); List<Long> collect = theLinks.stream().map(EmpiLink::getPersonPid).distinct().collect(Collectors.toList());
theLinks.forEach(empiLink -> myEmpiLinkDao.delete(empiLink)); theLinks.forEach(empiLink -> myEmpiLinkDao.delete(empiLink));
return collect; return collect;
} }

View File

@ -26,7 +26,6 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.model.DeleteConflict; import ca.uhn.fhir.jpa.api.model.DeleteConflict;
import ca.uhn.fhir.jpa.api.model.DeleteConflictList; import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService; import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService;
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
import ca.uhn.fhir.jpa.empi.dao.EmpiLinkDaoSvc; import ca.uhn.fhir.jpa.empi.dao.EmpiLinkDaoSvc;
@ -41,7 +40,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/** /**
* This class is in charge of Clearing out existing EMPI links, as well as deleting all persons related to those EMPI Links. * This class is in charge of Clearing out existing EMPI links, as well as deleting all persons related to those EMPI Links.
@ -52,13 +50,8 @@ public class EmpiResetSvcImpl implements IEmpiResetSvc {
@Autowired @Autowired
EmpiLinkDaoSvc myEmpiLinkDaoSvc; EmpiLinkDaoSvc myEmpiLinkDaoSvc;
@Autowired @Autowired
private IResourceExpungeService myResourceExpungeService; private IResourceExpungeService myResourceExpungeService;
@Autowired
private IResourceTableDao myResourceTable;
@Autowired @Autowired
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Autowired @Autowired
@ -67,12 +60,35 @@ public class EmpiResetSvcImpl implements IEmpiResetSvc {
@Override @Override
public long expungeAllEmpiLinksOfTargetType(String theResourceType) { public long expungeAllEmpiLinksOfTargetType(String theResourceType) {
throwExceptionIfInvalidTargetType(theResourceType); throwExceptionIfInvalidTargetType(theResourceType);
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksOfTypeAndReturnPersonPids(theResourceType); List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksOfTypeAndReturnPersonPids(theResourceType);
myResourceExpungeService.expungeCurrentVersionOfResources(null, longs, new AtomicInteger(longs.size())); deleteResourcesAndHandleConflicts(longs);
expungeHistoricalAndCurrentVersiondsOfIds(longs);
return longs.size(); return longs.size();
} }
/**
* Function which will delete all resources by their PIDs, and also delete any resources that were undeletable due to
* VersionConflictException
* @param theLongs
*/
private void deleteResourcesAndHandleConflicts(List<Long> theLongs) {
DeleteConflictList
deleteConflictList = new DeleteConflictList();
myTransactionService.execute(null, tx -> {
theLongs.stream().forEach(pid -> deleteCascade(pid, deleteConflictList));
return null;
});
IFhirResourceDao personDao = myDaoRegistry.getResourceDao("Person");
while (!deleteConflictList.isEmpty()) {
myTransactionService.execute(null, tx -> {
deleteConflictBatch(deleteConflictList, personDao);
return null;
});
}
}
private void throwExceptionIfInvalidTargetType(String theResourceType) { private void throwExceptionIfInvalidTargetType(String theResourceType) {
if (!EmpiUtil.supportedTargetType(theResourceType)) { if (!EmpiUtil.supportedTargetType(theResourceType)) {
throw new InvalidRequestException(ProviderConstants.EMPI_CLEAR + " does not support resource type: " + theResourceType); throw new InvalidRequestException(ProviderConstants.EMPI_CLEAR + " does not support resource type: " + theResourceType);
@ -85,30 +101,19 @@ public class EmpiResetSvcImpl implements IEmpiResetSvc {
@Override @Override
public long expungeAllEmpiLinks() { public long expungeAllEmpiLinks() {
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids(); List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids();
longs = longs.stream() deleteResourcesAndHandleConflicts(longs);
.distinct().collect(Collectors.toList()); expungeHistoricalAndCurrentVersiondsOfIds(longs);
DeleteConflictList dlc = new DeleteConflictList();
List<Long> finalLongs = longs;
myTransactionService.execute(null, tx -> {
finalLongs.stream().forEach(pid -> {
deleteCascade(pid, dlc);
});
return null;
});
IFhirResourceDao personDao = myDaoRegistry.getResourceDao("Person");
while (!dlc.isEmpty()) {
myTransactionService.execute(null, tx -> {
deleteConflictBatch(dlc, personDao);
return null;
});
}
myResourceExpungeService.expungeHistoricalVersionsOfIds(null, longs, new AtomicInteger(longs.size()));
//myResourceExpungeService.expungeCurrentVersionOfResources(null, longs, new AtomicInteger(longs.size()));
return longs.size(); return longs.size();
} }
/**
* Use the expunge service to expunge all historical and current versions of the resources associated to the PIDs.
*/
private void expungeHistoricalAndCurrentVersiondsOfIds(List<Long> theLongs) {
myResourceExpungeService.expungeHistoricalVersionsOfIds(null, theLongs, new AtomicInteger(Integer.MAX_VALUE - 1));
myResourceExpungeService.expungeCurrentVersionOfResources(null, theLongs, new AtomicInteger(Integer.MAX_VALUE - 1));
}
private void deleteConflictBatch(DeleteConflictList theDcl, IFhirResourceDao<IBaseResource> theDao) { private void deleteConflictBatch(DeleteConflictList theDcl, IFhirResourceDao<IBaseResource> theDao) {
DeleteConflictList newBatch = new DeleteConflictList(); DeleteConflictList newBatch = new DeleteConflictList();
for (DeleteConflict next: theDcl) { for (DeleteConflict next: theDcl) {
@ -120,10 +125,10 @@ public class EmpiResetSvcImpl implements IEmpiResetSvc {
theDcl.addAll(newBatch); theDcl.addAll(newBatch);
} }
private void deleteCascade(Long pid, DeleteConflictList theDcl) { private void deleteCascade(Long pid, DeleteConflictList theDeleteConflictList) {
ourLog.debug("About to cascade delete: " + pid); ourLog.debug("About to cascade delete: " + pid);
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao("Person"); IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao("Person");
resourceDao.delete(new IdType("Person/" + pid), theDcl, null, null); resourceDao.delete(new IdType("Person/" + pid), theDeleteConflictList, null, null);
} }
} }

View File

@ -14,6 +14,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@ -42,7 +44,7 @@ public class EmpiProviderBatchR4Test extends BaseLinkR4Test {
} }
@AfterEach @AfterEach
public void after() { public void after() throws IOException {
myInterceptorService.unregisterInterceptor(afterEmpiLatch); myInterceptorService.unregisterInterceptor(afterEmpiLatch);
super.after(); super.after();
} }

View File

@ -66,7 +66,7 @@ public class EmpiProviderClearLinkR4Test extends BaseLinkR4Test {
assertLinkCount(2); assertLinkCount(2);
Person read = myPersonDao.read(new IdDt(myPersonId.getValueAsString()).toVersionless()); Person read = myPersonDao.read(new IdDt(myPersonId.getValueAsString()).toVersionless());
assertThat(read, is(notNullValue())); assertThat(read, is(notNullValue()));
myEmpiProviderR4.clearEmpiLinks(new StringType("patient")); myEmpiProviderR4.clearEmpiLinks(new StringType("Patient"));
assertNoPatientLinksExist(); assertNoPatientLinksExist();
try { try {
myPersonDao.read(new IdDt(myPersonId.getValueAsString()).toVersionless()); myPersonDao.read(new IdDt(myPersonId.getValueAsString()).toVersionless());
@ -141,7 +141,7 @@ public class EmpiProviderClearLinkR4Test extends BaseLinkR4Test {
assertLinkCount(2); assertLinkCount(2);
Person read = myPersonDao.read(new IdDt(myPractitionerPersonId.getValueAsString()).toVersionless()); Person read = myPersonDao.read(new IdDt(myPractitionerPersonId.getValueAsString()).toVersionless());
assertThat(read, is(notNullValue())); assertThat(read, is(notNullValue()));
myEmpiProviderR4.clearEmpiLinks(new StringType("practitioner")); myEmpiProviderR4.clearEmpiLinks(new StringType("Practitioner"));
assertNoPractitionerLinksExist(); assertNoPractitionerLinksExist();
try { try {
myPersonDao.read(new IdDt(myPractitionerPersonId.getValueAsString()).toVersionless()); myPersonDao.read(new IdDt(myPractitionerPersonId.getValueAsString()).toVersionless());
@ -152,10 +152,10 @@ public class EmpiProviderClearLinkR4Test extends BaseLinkR4Test {
@Test @Test
public void testClearInvalidTargetType() { public void testClearInvalidTargetType() {
try { try {
myEmpiProviderR4.clearEmpiLinks(new StringType("observation")); myEmpiProviderR4.clearEmpiLinks(new StringType("Observation"));
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertThat(e.getMessage(), is(equalTo("$empi-clear does not support resource type: observation"))); assertThat(e.getMessage(), is(equalTo("$empi-clear does not support resource type: Observation")));
} }
} }

View File

@ -11,6 +11,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.Date; import java.util.Date;
class EmpiBatchSvcImplTest extends BaseEmpiR4Test { class EmpiBatchSvcImplTest extends BaseEmpiR4Test {
@ -28,7 +29,7 @@ class EmpiBatchSvcImplTest extends BaseEmpiR4Test {
myInterceptorService.registerAnonymousInterceptor(Pointcut.EMPI_AFTER_PERSISTED_RESOURCE_CHECKED, afterEmpiLatch); myInterceptorService.registerAnonymousInterceptor(Pointcut.EMPI_AFTER_PERSISTED_RESOURCE_CHECKED, afterEmpiLatch);
} }
@AfterEach @AfterEach
public void after() { public void after() throws IOException {
myInterceptorService.unregisterInterceptor(afterEmpiLatch); myInterceptorService.unregisterInterceptor(afterEmpiLatch);
afterEmpiLatch.clear(); afterEmpiLatch.clear();
super.after(); super.after();