Rework into new person deleting service
This commit is contained in:
parent
0e88f359f5
commit
102f936156
|
@ -67,7 +67,7 @@ import java.util.List;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Service
|
||||
class ResourceExpungeService implements IResourceExpungeService {
|
||||
public class ResourceExpungeService implements IResourceExpungeService {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(ResourceExpungeService.class);
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -22,13 +22,13 @@ 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.IEmpiResetSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiChannelSubmitterSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiLinkQuerySvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiLinkSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiLinkUpdaterSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiMatchFinderSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiPersonMergerSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiChannelSubmitterSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiResetSvc;
|
||||
import ca.uhn.fhir.empi.api.IEmpiSettings;
|
||||
import ca.uhn.fhir.empi.log.Logs;
|
||||
import ca.uhn.fhir.empi.provider.EmpiProviderLoader;
|
||||
|
@ -44,16 +44,18 @@ import ca.uhn.fhir.jpa.empi.dao.EmpiLinkFactory;
|
|||
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.EmpiChannelSubmitterSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiEidUpdateService;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiResetSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiLinkQuerySvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiLinkSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiLinkUpdaterSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiMatchFinderSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiMatchLinkSvc;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiPersonDeletingSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiPersonMergerSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiChannelSubmitterSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiResetSvcImpl;
|
||||
import ca.uhn.fhir.jpa.empi.svc.EmpiResourceDaoSvc;
|
||||
import ca.uhn.fhir.jpa.empi.svc.IEmpiPersonDeletingSvc;
|
||||
import ca.uhn.fhir.jpa.empi.svc.candidate.EmpiCandidateSearchCriteriaBuilderSvc;
|
||||
import ca.uhn.fhir.jpa.empi.svc.candidate.EmpiCandidateSearchSvc;
|
||||
import ca.uhn.fhir.jpa.empi.svc.candidate.EmpiPersonFindingSvc;
|
||||
|
@ -180,8 +182,13 @@ public class EmpiConsumerConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
IEmpiResetSvc empiResetSvc() {
|
||||
return new EmpiResetSvcImpl();
|
||||
IEmpiResetSvc empiResetSvc(EmpiLinkDaoSvc theEmpiLinkDaoSvc, IEmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl ) {
|
||||
return new EmpiResetSvcImpl(theEmpiLinkDaoSvc, theEmpiPersonDeletingSvcImpl);
|
||||
}
|
||||
|
||||
@Bean
|
||||
IEmpiPersonDeletingSvc empiPersonDeletingSvc() {
|
||||
return new EmpiPersonDeletingSvcImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package ca.uhn.fhir.jpa.empi.svc;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteConflict;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
||||
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
@Service
|
||||
public class EmpiPersonDeletingSvcImpl implements IEmpiPersonDeletingSvc {
|
||||
private static final Logger ourLog = getLogger(EmpiPersonDeletingSvcImpl.class);
|
||||
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
@Autowired
|
||||
private ExpungeService myExpungeService;
|
||||
@Autowired
|
||||
private PlatformTransactionManager myPlatformTransactionManager;
|
||||
|
||||
|
||||
/**
|
||||
* Function which will delete all resources by their PIDs, and also delete any resources that were undeletable due to
|
||||
* VersionConflictException
|
||||
* @param theLongs
|
||||
*/
|
||||
@Override
|
||||
public void deleteResourcesAndHandleConflicts(List<Long> theLongs) {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
|
||||
txTemplate.execute((tx) ->{
|
||||
DeleteConflictList
|
||||
deleteConflictList = new DeleteConflictList();
|
||||
theLongs.stream().forEach(pid -> deleteCascade(pid, deleteConflictList));
|
||||
|
||||
IFhirResourceDao personDao = myDaoRegistry.getResourceDao("Person");
|
||||
while (!deleteConflictList.isEmpty()) {
|
||||
deleteConflictBatch(deleteConflictList, personDao);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the expunge service to expunge all historical and current versions of the resources associated to the PIDs.
|
||||
*/
|
||||
@Override
|
||||
public void expungeHistoricalAndCurrentVersionsOfIds(List<Long> theLongs) {
|
||||
ExpungeOptions options = new ExpungeOptions();
|
||||
options.setExpungeDeletedResources(true);
|
||||
options.setExpungeOldVersions(true);
|
||||
//myResourceExpungeService.expungeHistoricalVersionsOfIds(null, theLongs, new AtomicInteger(Integer.MAX_VALUE - 1));
|
||||
theLongs.stream()
|
||||
.forEach(personId -> {
|
||||
myExpungeService.expunge("Person", personId, null, options, null);
|
||||
});
|
||||
//myResourceExpungeService.expungeCurrentVersionOfResources(null, theLongs, new AtomicInteger(Integer.MAX_VALUE - 1));
|
||||
}
|
||||
|
||||
private void deleteCascade(Long pid, DeleteConflictList theDeleteConflictList) {
|
||||
ourLog.debug("About to cascade delete: " + pid);
|
||||
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao("Person");
|
||||
resourceDao.delete(new IdType("Person/" + pid), theDeleteConflictList, null, null);
|
||||
}
|
||||
|
||||
private void deleteConflictBatch(DeleteConflictList theDcl, IFhirResourceDao<IBaseResource> theDao) {
|
||||
DeleteConflictList newBatch = new DeleteConflictList();
|
||||
for (DeleteConflict next: theDcl) {
|
||||
IdDt nextSource = next.getSourceId();
|
||||
ourLog.info("Have delete conflict {} - Cascading delete", next);
|
||||
theDao.delete(nextSource.toVersionless(), newBatch, null, null);
|
||||
}
|
||||
theDcl.removeIf(x -> true);
|
||||
theDcl.addAll(newBatch);
|
||||
}
|
||||
}
|
|
@ -22,26 +22,14 @@ package ca.uhn.fhir.jpa.empi.svc;
|
|||
|
||||
import ca.uhn.fhir.empi.api.IEmpiResetSvc;
|
||||
import ca.uhn.fhir.empi.util.EmpiUtil;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteConflict;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
||||
import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService;
|
||||
import ca.uhn.fhir.jpa.empi.dao.EmpiLinkDaoSvc;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
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.hl7.fhir.r4.model.IdType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* This class is in charge of Clearing out existing EMPI links, as well as deleting all persons related to those EMPI Links.
|
||||
|
@ -50,96 +38,36 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
public class EmpiResetSvcImpl implements IEmpiResetSvc {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(EmpiResetSvcImpl.class);
|
||||
|
||||
@Autowired
|
||||
EmpiLinkDaoSvc myEmpiLinkDaoSvc;
|
||||
@Autowired
|
||||
private IResourceExpungeService myResourceExpungeService;
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
@Autowired
|
||||
private PlatformTransactionManager myTransactionManager;
|
||||
final EmpiLinkDaoSvc myEmpiLinkDaoSvc;
|
||||
final IEmpiPersonDeletingSvc myEmpiPersonDeletingSvcImpl;
|
||||
|
||||
private TransactionTemplate myTxTemplate;
|
||||
@Autowired
|
||||
public EmpiResetSvcImpl(EmpiLinkDaoSvc theEmpiLinkDaoSvc, IEmpiPersonDeletingSvc theEmpiPersonDeletingSvcImpl) {
|
||||
myEmpiLinkDaoSvc = theEmpiLinkDaoSvc;
|
||||
myEmpiPersonDeletingSvcImpl = theEmpiPersonDeletingSvcImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long expungeAllEmpiLinksOfTargetType(String theResourceType) {
|
||||
throwExceptionIfInvalidTargetType(theResourceType);
|
||||
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksOfTypeAndReturnPersonPids(theResourceType);
|
||||
deleteResourcesAndHandleConflicts(longs);
|
||||
expungeHistoricalAndCurrentVersiondsOfIds(longs);
|
||||
myEmpiPersonDeletingSvcImpl.deleteResourcesAndHandleConflicts(longs);
|
||||
myEmpiPersonDeletingSvcImpl.expungeHistoricalAndCurrentVersionsOfIds(longs);
|
||||
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();
|
||||
myTxTemplate.execute(tx -> {
|
||||
theLongs.stream().forEach(pid -> deleteCascade(pid, deleteConflictList));
|
||||
return null;
|
||||
});
|
||||
|
||||
IFhirResourceDao personDao = myDaoRegistry.getResourceDao("Person");
|
||||
while (!deleteConflictList.isEmpty()) {
|
||||
myTxTemplate.execute(tx -> {
|
||||
deleteConflictBatch(deleteConflictList, personDao);
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void throwExceptionIfInvalidTargetType(String theResourceType) {
|
||||
if (!EmpiUtil.supportedTargetType(theResourceType)) {
|
||||
throw new InvalidRequestException(ProviderConstants.EMPI_CLEAR + " does not support resource type: " + theResourceType);
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void start() {
|
||||
myTxTemplate = new TransactionTemplate(myTransactionManager);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO GGG this operation likely won't scale very well. Consider adding slicing
|
||||
*/
|
||||
@Override
|
||||
public long expungeAllEmpiLinks() {
|
||||
List<Long> longs = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids();
|
||||
deleteResourcesAndHandleConflicts(longs);
|
||||
expungeHistoricalAndCurrentVersiondsOfIds(longs);
|
||||
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) {
|
||||
DeleteConflictList newBatch = new DeleteConflictList();
|
||||
for (DeleteConflict next: theDcl) {
|
||||
IdDt nextSource = next.getSourceId();
|
||||
ourLog.info("Have delete conflict {} - Cascading delete", next);
|
||||
theDao.delete(nextSource.toVersionless(), newBatch, null, null);
|
||||
}
|
||||
theDcl.removeIf(x -> true);
|
||||
theDcl.addAll(newBatch);
|
||||
}
|
||||
|
||||
private void deleteCascade(Long pid, DeleteConflictList theDeleteConflictList) {
|
||||
ourLog.debug("About to cascade delete: " + pid);
|
||||
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao("Person");
|
||||
myTxTemplate.executeWithoutResult((tx) -> resourceDao.delete(new IdType("Person/" + pid), theDeleteConflictList, null, null));
|
||||
|
||||
public long removeAllEmpiLinks() {
|
||||
List<Long> personPids = myEmpiLinkDaoSvc.deleteAllEmpiLinksAndReturnPersonPids();
|
||||
myEmpiPersonDeletingSvcImpl.deleteResourcesAndHandleConflicts(personPids);
|
||||
myEmpiPersonDeletingSvcImpl.expungeHistoricalAndCurrentVersionsOfIds(personPids);
|
||||
return personPids.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package ca.uhn.fhir.jpa.empi.svc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IEmpiPersonDeletingSvc {
|
||||
|
||||
void deleteResourcesAndHandleConflicts(List<Long> theLongs);
|
||||
|
||||
void expungeHistoricalAndCurrentVersionsOfIds(List<Long> theLongs);
|
||||
}
|
|
@ -37,5 +37,5 @@ public interface IEmpiResetSvc {
|
|||
*
|
||||
* @return the count of deleted EMPI links
|
||||
*/
|
||||
long expungeAllEmpiLinks();
|
||||
long removeAllEmpiLinks();
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ public class EmpiProviderDstu3 extends BaseEmpiProvider {
|
|||
public Parameters clearEmpiLinks(@OperationParam(name=ProviderConstants.EMPI_CLEAR_TARGET_TYPE, min = 0, max = 1) StringType theTargetType) {
|
||||
long resetCount;
|
||||
if (theTargetType == null || StringUtils.isBlank(theTargetType.getValue())) {
|
||||
resetCount = myEmpiResetSvc.expungeAllEmpiLinks();
|
||||
resetCount = myEmpiResetSvc.removeAllEmpiLinks();
|
||||
} else {
|
||||
resetCount = myEmpiResetSvc.expungeAllEmpiLinksOfTargetType(theTargetType.getValueNotNull());
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ public class EmpiProviderR4 extends BaseEmpiProvider {
|
|||
public Parameters clearEmpiLinks(@OperationParam(name=ProviderConstants.EMPI_CLEAR_TARGET_TYPE, min = 0, max = 1) StringType theTargetType) {
|
||||
long resetCount;
|
||||
if (theTargetType == null || StringUtils.isBlank(theTargetType.getValue())) {
|
||||
resetCount = myEmpiExpungeSvc.expungeAllEmpiLinks();
|
||||
resetCount = myEmpiExpungeSvc.removeAllEmpiLinks();
|
||||
} else {
|
||||
resetCount = myEmpiExpungeSvc.expungeAllEmpiLinksOfTargetType(theTargetType.getValueNotNull());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue