Further expunge refactoring (#3550)

* convert expunge public interfaces to use ResourcePersistentId instead of Long

* changelog

* version bump
This commit is contained in:
JasonRoberts-smile 2022-04-21 09:51:19 -04:00 committed by GitHub
parent 612ee0af32
commit 1114c72f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 185 additions and 169 deletions

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<packaging>pom</packaging>
<name>HAPI FHIR BOM</name>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -0,0 +1,5 @@
---
type: change
issue: 3550
title: "Method signatures on several interfaces and classes related to the `$expunge` operation have changed to support
the case where the primary identifier of a resource is not necessarily a `Long`."

View File

@ -11,7 +11,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -25,11 +25,11 @@ import ca.uhn.fhir.jpa.dao.data.IMdmLinkDao;
import ca.uhn.fhir.jpa.dao.expunge.PartitionRunner;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.SliceImpl;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
@ -58,14 +58,14 @@ public class MdmLinkDeleter implements ItemProcessor<List<Long>, List<Long>> {
public List<Long> process(List<Long> thePidList) throws Exception {
ConcurrentLinkedQueue<Long> goldenPidAggregator = new ConcurrentLinkedQueue<>();
PartitionRunner partitionRunner = new PartitionRunner(PROCESS_NAME, THREAD_PREFIX, myDaoConfig.getReindexBatchSize(), myDaoConfig.getReindexThreadCount());
partitionRunner.runInPartitionedThreads(thePidList, pids -> removeLinks(pids, goldenPidAggregator));
partitionRunner.runInPartitionedThreads(ResourcePersistentId.fromLongList(thePidList), pids -> removeLinks(pids, goldenPidAggregator));
return new ArrayList<>(goldenPidAggregator);
}
private void removeLinks(List<Long> pidList, ConcurrentLinkedQueue<Long> theGoldenPidAggregator) {
private void removeLinks(List<ResourcePersistentId> pidList, ConcurrentLinkedQueue<Long> theGoldenPidAggregator) {
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
txTemplate.executeWithoutResult(t -> theGoldenPidAggregator.addAll(deleteMdmLinksAndReturnGoldenResourcePids(pidList)));
txTemplate.executeWithoutResult(t -> theGoldenPidAggregator.addAll(deleteMdmLinksAndReturnGoldenResourcePids(ResourcePersistentId.toLongList(pidList))));
}
public List<Long> deleteMdmLinksAndReturnGoldenResourcePids(List<Long> thePids) {

View File

@ -139,6 +139,7 @@ import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.mdm.api.IMdmClearJobSubmitter;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationInterceptor;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
@ -757,8 +758,8 @@ public class JpaConfig {
@Bean
@Scope("prototype")
public ExpungeOperation expungeOperation(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return new ExpungeOperation(theResourceName, theResourceId, theVersion, theExpungeOptions, theRequestDetails);
public ExpungeOperation expungeOperation(String theResourceName, ResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return new ExpungeOperation(theResourceName, theResourceId, theExpungeOptions, theRequestDetails);
}
@Bean

View File

@ -77,6 +77,7 @@ import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -1422,7 +1423,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
*/
if (thePerformIndexing) {
if (newParams == null) {
myExpungeService.deleteAllSearchParams(entity.getId());
myExpungeService.deleteAllSearchParams(new ResourcePersistentId(entity.getId()));
} else {
// Synchronize search param indexes

View File

@ -887,10 +887,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
throw new PreconditionFailedException(Msg.code(969) + "Can not perform version-specific expunge of resource " + theId.toUnqualified().getValue() + " as this is the current version");
}
return myExpungeService.expunge(getResourceName(), entity.getResourceId(), entity.getVersion(), theExpungeOptions, theRequest);
return myExpungeService.expunge(getResourceName(), new ResourcePersistentId(entity.getResourceId(), entity.getVersion()), theExpungeOptions, theRequest);
}
return myExpungeService.expunge(getResourceName(), entity.getResourceId(), null, theExpungeOptions, theRequest);
return myExpungeService.expunge(getResourceName(), new ResourcePersistentId(entity.getResourceId()), theExpungeOptions, theRequest);
}
@Override
@ -898,7 +898,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
ourLog.info("Beginning TYPE[{}] expunge operation", getResourceName());
return myExpungeService.expunge(getResourceName(), null, null, theExpungeOptions, theRequestDetails);
return myExpungeService.expunge(getResourceName(), null, theExpungeOptions, theRequestDetails);
}
@Override

View File

@ -83,7 +83,7 @@ public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends B
@Override
@Transactional(propagation = Propagation.NEVER)
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return myExpungeService.expunge(null, null, null, theExpungeOptions, theRequestDetails);
return myExpungeService.expunge(null, null, theExpungeOptions, theRequestDetails);
}
@Transactional(propagation = Propagation.REQUIRED)

View File

@ -48,6 +48,7 @@ import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.model.primitive.IdDt;
@ -125,15 +126,15 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override
@Transactional
public List<Long> findHistoricalVersionsOfNonDeletedResources(String theResourceName, Long theResourceId, Long theVersion, int theRemainingCount) {
public List<ResourcePersistentId> findHistoricalVersionsOfNonDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theRemainingCount) {
Pageable page = PageRequest.of(0, theRemainingCount);
Slice<Long> ids;
if (theResourceId != null) {
if (theVersion != null) {
ids = toSlice(myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(theResourceId, theVersion));
if (theResourceId != null && theResourceId.getId() != null) {
if (theResourceId.getVersion() != null) {
ids = toSlice(myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(theResourceId.getIdAsLong(), theResourceId.getVersion()));
} else {
ids = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResourceId(page, theResourceId);
ids = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResourceId(page, theResourceId.getIdAsLong());
}
} else {
if (theResourceName != null) {
@ -143,16 +144,16 @@ public class ResourceExpungeService implements IResourceExpungeService {
}
}
return ids.getContent();
return ResourcePersistentId.fromLongList(ids.getContent());
}
@Override
@Transactional
public List<Long> findHistoricalVersionsOfDeletedResources(String theResourceName, Long theResourceId, int theRemainingCount) {
public List<ResourcePersistentId> findHistoricalVersionsOfDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theRemainingCount) {
Pageable page = PageRequest.of(0, theRemainingCount);
Slice<Long> ids;
if (theResourceId != null) {
ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId, theResourceName);
ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId.getIdAsLong(), theResourceName);
ourLog.info("Expunging {} deleted resources of type[{}] and ID[{}]", ids.getNumberOfElements(), theResourceName, theResourceId);
} else {
if (theResourceName != null) {
@ -163,14 +164,14 @@ public class ResourceExpungeService implements IResourceExpungeService {
ourLog.info("Expunging {} deleted resources (all types)", ids.getNumberOfElements());
}
}
return ids.getContent();
return ResourcePersistentId.fromLongList(ids.getContent());
}
@Override
@Transactional
public void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<Long> theResourceIds, AtomicInteger theRemainingCount) {
for (Long next : theResourceIds) {
expungeCurrentVersionOfResource(theRequestDetails, next, theRemainingCount);
public void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theResourceIds) {
expungeCurrentVersionOfResource(theRequestDetails, next.getIdAsLong(), theRemainingCount);
if (theRemainingCount.get() <= 0) {
return;
}
@ -226,9 +227,9 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override
@Transactional
public void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<Long> theResourceIds, AtomicInteger theRemainingCount) {
for (Long next : theResourceIds) {
expungeHistoricalVersionsOfId(theRequestDetails, next, theRemainingCount);
public void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theResourceIds) {
expungeHistoricalVersionsOfId(theRequestDetails, next.getIdAsLong(), theRemainingCount);
if (theRemainingCount.get() <= 0) {
return;
}
@ -237,9 +238,9 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override
@Transactional
public void expungeHistoricalVersions(RequestDetails theRequestDetails, List<Long> theHistoricalIds, AtomicInteger theRemainingCount) {
for (Long next : theHistoricalIds) {
expungeHistoricalVersion(theRequestDetails, next, theRemainingCount);
public void expungeHistoricalVersions(RequestDetails theRequestDetails, List<ResourcePersistentId> theHistoricalIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theHistoricalIds) {
expungeHistoricalVersion(theRequestDetails, next.getIdAsLong(), theRemainingCount);
if (theRemainingCount.get() <= 0) {
return;
}
@ -256,7 +257,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
ourLog.info("Expunging current version of resource {}", resource.getIdDt().getValue());
deleteAllSearchParams(resource.getResourceId());
deleteAllSearchParams(new ResourcePersistentId(resource.getResourceId()));
resource.getTags().clear();
if (resource.getForcedId() != null) {
@ -271,48 +272,48 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override
@Transactional
public void deleteAllSearchParams(Long theResourceId) {
ResourceTable resource = myResourceTableDao.findById(theResourceId).orElse(null);
public void deleteAllSearchParams(ResourcePersistentId theResourceId) {
ResourceTable resource = myResourceTableDao.findById(theResourceId.getIdAsLong()).orElse(null);
if (resource == null || resource.isParamsUriPopulated()) {
myResourceIndexedSearchParamUriDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamUriDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsCoordsPopulated()) {
myResourceIndexedSearchParamCoordsDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamCoordsDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsDatePopulated()) {
myResourceIndexedSearchParamDateDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamDateDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsNumberPopulated()) {
myResourceIndexedSearchParamNumberDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamNumberDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsQuantityPopulated()) {
myResourceIndexedSearchParamQuantityDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamQuantityDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsQuantityNormalizedPopulated()) {
myResourceIndexedSearchParamQuantityNormalizedDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamQuantityNormalizedDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsStringPopulated()) {
myResourceIndexedSearchParamStringDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamStringDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsTokenPopulated()) {
myResourceIndexedSearchParamTokenDao.deleteByResourceId(theResourceId);
myResourceIndexedSearchParamTokenDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsComboStringUniquePresent()) {
myResourceIndexedCompositeStringUniqueDao.deleteByResourceId(theResourceId);
myResourceIndexedCompositeStringUniqueDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isParamsComboTokensNonUniquePresent()) {
myResourceIndexedComboTokensNonUniqueDao.deleteByResourceId(theResourceId);
myResourceIndexedComboTokensNonUniqueDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.ENABLED) {
mySearchParamPresentDao.deleteByResourceId(theResourceId);
mySearchParamPresentDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isHasLinks()) {
myResourceLinkDao.deleteByResourceId(theResourceId);
myResourceLinkDao.deleteByResourceId(theResourceId.getIdAsLong());
}
if (resource == null || resource.isHasTags()) {
myResourceTagDao.deleteByResourceId(theResourceId);
myResourceTagDao.deleteByResourceId(theResourceId.getIdAsLong());
}
}

View File

@ -28,6 +28,7 @@ import ca.uhn.fhir.jpa.dao.expunge.ResourceForeignKey;
import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider;
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -84,10 +85,11 @@ public class DeleteExpungeProcessor implements ItemProcessor<List<Long>, List<St
return;
}
List<ResourcePersistentId> targetPidsAsResourceIds = ResourcePersistentId.fromLongList(thePids);
List<ResourceLink> conflictResourceLinks = Collections.synchronizedList(new ArrayList<>());
PartitionRunner partitionRunner = new PartitionRunner(PROCESS_NAME, THREAD_PREFIX, myDaoConfig.getExpungeBatchSize(), myDaoConfig.getExpungeThreadCount());
Consumer<List<Long>> listConsumer = someTargetPids -> findResourceLinksWithTargetPidIn(thePids, someTargetPids, conflictResourceLinks);
partitionRunner.runInPartitionedThreads(thePids, listConsumer);
Consumer<List<ResourcePersistentId>> listConsumer = someTargetPids -> findResourceLinksWithTargetPidIn(targetPidsAsResourceIds, someTargetPids, conflictResourceLinks);
partitionRunner.runInPartitionedThreads(targetPidsAsResourceIds, listConsumer);
if (conflictResourceLinks.isEmpty()) {
return;
@ -105,14 +107,16 @@ public class DeleteExpungeProcessor implements ItemProcessor<List<Long>, List<St
targetResourceId + " because " + sourceResourceId + " refers to it via the path " + firstConflict.getSourcePath());
}
public void findResourceLinksWithTargetPidIn(List<Long> theAllTargetPids, List<Long> theSomeTargetPids, List<ResourceLink> theConflictResourceLinks) {
public void findResourceLinksWithTargetPidIn(List<ResourcePersistentId> theAllTargetPids, List<ResourcePersistentId> theSomeTargetPids, List<ResourceLink> theConflictResourceLinks) {
List<Long> allTargetPidsAsLongs = ResourcePersistentId.toLongList(theAllTargetPids);
List<Long> someTargetPidsAsLongs = ResourcePersistentId.toLongList(theSomeTargetPids);
// We only need to find one conflict, so if we found one already in an earlier partition run, we can skip the rest of the searches
if (theConflictResourceLinks.isEmpty()) {
List<ResourceLink> conflictResourceLinks = myResourceLinkDao.findWithTargetPidIn(theSomeTargetPids).stream()
List<ResourceLink> conflictResourceLinks = myResourceLinkDao.findWithTargetPidIn(someTargetPidsAsLongs).stream()
// Filter out resource links for which we are planning to delete the source.
// theAllTargetPids contains a list of all the pids we are planning to delete. So we only want
// to consider a link to be a conflict if the source of that link is not in theAllTargetPids.
.filter(link -> !theAllTargetPids.contains(link.getSourceResourcePid()))
.filter(link -> !allTargetPidsAsLongs.contains(link.getSourceResourcePid()))
.collect(Collectors.toList());
// We do this in two steps to avoid lock contention on this synchronized list

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
import ca.uhn.fhir.jpa.test.BaseJpaDstu3Test;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.test.concurrency.PointcutLatch;
import org.hl7.fhir.dstu3.model.Patient;
@ -61,7 +62,7 @@ public class ExpungeHookTest extends BaseJpaDstu3Test {
myEverythingLatch.setExpectedCount(1);
ExpungeOptions options = new ExpungeOptions();
options.setExpungeEverything(true);
myExpungeService.expunge(null, null, null, options, null);
myExpungeService.expunge(null, null, options, null);
myEverythingLatch.awaitExpected();
assertPatientGone(id);
@ -94,7 +95,7 @@ public class ExpungeHookTest extends BaseJpaDstu3Test {
// Expunge everything with the service.
myEverythingLatch.setExpectedCount(1);
myExpungeService.expunge(null, null, null, options, mySrd);
myExpungeService.expunge(null, null, options, mySrd);
myEverythingLatch.awaitExpected();
assertPatientGone(id);
@ -122,7 +123,7 @@ public class ExpungeHookTest extends BaseJpaDstu3Test {
options.setExpungeDeletedResources(true);
myExpungeResourceLatch.setExpectedCount(2);
myExpungeService.expunge("Patient", expungeId.getIdPartAsLong(), null, options, null);
myExpungeService.expunge("Patient", new ResourcePersistentId(expungeId.getIdPartAsLong()), options, null);
HookParams hookParams = myExpungeResourceLatch.awaitExpected().get(0);
IIdType hookId = hookParams.get(IIdType.class);

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.expunge;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.test.concurrency.PointcutLatch;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.builder.ToStringBuilder;
@ -34,8 +35,8 @@ public class PartitionRunnerTest {
@Test
public void emptyList() {
List<Long> resourceIds = buildPidList(0);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
List<ResourcePersistentId> resourceIds = buildPidList(0);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(0);
getPartitionRunner().runInPartitionedThreads(resourceIds, partitionConsumer);
@ -54,19 +55,19 @@ public class PartitionRunnerTest {
return new PartitionRunner("TEST", "test", theBatchSize, theThreadCount);
}
private List<Long> buildPidList(int size) {
List<Long> list = new ArrayList<>();
private List<ResourcePersistentId> buildPidList(int size) {
List<ResourcePersistentId> list = new ArrayList<>();
for (long i = 0; i < size; ++i) {
list.add(i + 1);
list.add(new ResourcePersistentId(i + 1));
}
return list;
}
@Test
public void oneItem() throws InterruptedException {
List<Long> resourceIds = buildPidList(1);
List<ResourcePersistentId> resourceIds = buildPidList(1);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(1);
getPartitionRunner().runInPartitionedThreads(resourceIds, partitionConsumer);
PartitionCall partitionCall = (PartitionCall) PointcutLatch.getLatchInvocationParameter(myLatch.awaitExpected());
@ -77,9 +78,9 @@ public class PartitionRunnerTest {
@Test
public void twoItems() throws InterruptedException {
List<Long> resourceIds = buildPidList(2);
List<ResourcePersistentId> resourceIds = buildPidList(2);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(1);
getPartitionRunner().runInPartitionedThreads(resourceIds, partitionConsumer);
PartitionCall partitionCall = (PartitionCall) PointcutLatch.getLatchInvocationParameter(myLatch.awaitExpected());
@ -89,9 +90,9 @@ public class PartitionRunnerTest {
@Test
public void tenItemsBatch5() throws InterruptedException {
List<Long> resourceIds = buildPidList(10);
List<ResourcePersistentId> resourceIds = buildPidList(10);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(2);
getPartitionRunner(5).runInPartitionedThreads(resourceIds, partitionConsumer);
List<HookParams> calls = myLatch.awaitExpected();
@ -106,13 +107,13 @@ public class PartitionRunnerTest {
@Test
public void nineItemsBatch5() throws InterruptedException {
List<Long> resourceIds = buildPidList(9);
List<ResourcePersistentId> resourceIds = buildPidList(9);
// We don't care in which order, but one partition size should be
// 5 and one should be 4
Set<Integer> nums = Sets.newHashSet(5, 4);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(2);
getPartitionRunner(5).runInPartitionedThreads(resourceIds, partitionConsumer);
List<HookParams> calls = myLatch.awaitExpected();
@ -127,9 +128,9 @@ public class PartitionRunnerTest {
@Test
public void tenItemsOneThread() throws InterruptedException {
List<Long> resourceIds = buildPidList(10);
List<ResourcePersistentId> resourceIds = buildPidList(10);
Consumer<List<Long>> partitionConsumer = buildPartitionConsumer(myLatch);
Consumer<List<ResourcePersistentId>> partitionConsumer = buildPartitionConsumer(myLatch);
myLatch.setExpectedCount(2);
getPartitionRunner(5, 1).runInPartitionedThreads(resourceIds, partitionConsumer);
List<HookParams> calls = myLatch.awaitExpected();
@ -145,7 +146,7 @@ public class PartitionRunnerTest {
}
}
private Consumer<List<Long>> buildPartitionConsumer(PointcutLatch latch) {
private Consumer<List<ResourcePersistentId>> buildPartitionConsumer(PointcutLatch latch) {
return list -> latch.call(new PartitionCall(Thread.currentThread().getName(), list.size()));
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -47,16 +48,14 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
private DaoConfig myDaoConfig;
private final String myResourceName;
private final Long myResourceId;
private final Long myVersion;
private final ResourcePersistentId myResourceId;
private final ExpungeOptions myExpungeOptions;
private final RequestDetails myRequestDetails;
private final AtomicInteger myRemainingCount;
public ExpungeOperation(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
public ExpungeOperation(String theResourceName, ResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
myResourceName = theResourceName;
myResourceId = theResourceId;
myVersion = theVersion;
myExpungeOptions = theExpungeOptions;
myRequestDetails = theRequestDetails;
myRemainingCount = new AtomicInteger(myExpungeOptions.getLimit());
@ -64,7 +63,7 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
@Override
public ExpungeOutcome call() {
if (myExpungeOptions.isExpungeDeletedResources() && myVersion == null) {
if (myExpungeOptions.isExpungeDeletedResources() && (myResourceId == null || myResourceId.getVersion() == null)) {
expungeDeletedResources();
if (expungeLimitReached()) {
return expungeOutcome();
@ -82,7 +81,7 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
}
private void expungeDeletedResources() {
List<Long> resourceIds = findHistoricalVersionsOfDeletedResources();
List<ResourcePersistentId> resourceIds = findHistoricalVersionsOfDeletedResources();
deleteHistoricalVersions(resourceIds);
if (expungeLimitReached()) {
@ -92,14 +91,14 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
deleteCurrentVersionsOfDeletedResources(resourceIds);
}
private List<Long> findHistoricalVersionsOfDeletedResources() {
List<Long> retVal = myExpungeDaoService.findHistoricalVersionsOfDeletedResources(myResourceName, myResourceId, myRemainingCount.get());
private List<ResourcePersistentId> findHistoricalVersionsOfDeletedResources() {
List<ResourcePersistentId> retVal = myExpungeDaoService.findHistoricalVersionsOfDeletedResources(myResourceName, myResourceId, myRemainingCount.get());
ourLog.debug("Found {} historical versions", retVal.size());
return retVal;
}
private List<Long> findHistoricalVersionsOfNonDeletedResources() {
return myExpungeDaoService.findHistoricalVersionsOfNonDeletedResources(myResourceName, myResourceId, myVersion, myRemainingCount.get());
private List<ResourcePersistentId> findHistoricalVersionsOfNonDeletedResources() {
return myExpungeDaoService.findHistoricalVersionsOfNonDeletedResources(myResourceName, myResourceId, myRemainingCount.get());
}
private boolean expungeLimitReached() {
@ -111,7 +110,7 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
}
private void expungeOldVersions() {
List<Long> historicalIds = findHistoricalVersionsOfNonDeletedResources();
List<ResourcePersistentId> historicalIds = findHistoricalVersionsOfNonDeletedResources();
getPartitionRunner().runInPartitionedThreads(historicalIds, partition -> myExpungeDaoService.expungeHistoricalVersions(myRequestDetails, partition, myRemainingCount));
}
@ -120,11 +119,11 @@ public class ExpungeOperation implements Callable<ExpungeOutcome> {
return new PartitionRunner(PROCESS_NAME, THREAD_PREFIX, myDaoConfig.getExpungeBatchSize(), myDaoConfig.getExpungeThreadCount());
}
private void deleteCurrentVersionsOfDeletedResources(List<Long> theResourceIds) {
private void deleteCurrentVersionsOfDeletedResources(List<ResourcePersistentId> theResourceIds) {
getPartitionRunner().runInPartitionedThreads(theResourceIds, partition -> myExpungeDaoService.expungeCurrentVersionOfResources(myRequestDetails, partition, myRemainingCount));
}
private void deleteHistoricalVersions(List<Long> theResourceIds) {
private void deleteHistoricalVersions(List<ResourcePersistentId> theResourceIds) {
getPartitionRunner().runInPartitionedThreads(theResourceIds, partition -> myExpungeDaoService.expungeHistoricalVersionsOfIds(myRequestDetails, partition, myRemainingCount));
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,28 +43,28 @@ public class ExpungeService {
@Autowired
private ApplicationContext myApplicationContext;
protected ExpungeOperation getExpungeOperation(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return myApplicationContext.getBean(ExpungeOperation.class, theResourceName, theResourceId, theVersion, theExpungeOptions, theRequestDetails);
protected ExpungeOperation getExpungeOperation(String theResourceName, ResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return myApplicationContext.getBean(ExpungeOperation.class, theResourceName, theResourceId, theExpungeOptions, theRequestDetails);
}
public ExpungeOutcome expunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequest) {
ourLog.info("Expunge: ResourceName[{}] Id[{}] Version[{}] Options[{}]", theResourceName, theResourceId, theVersion, theExpungeOptions);
public ExpungeOutcome expunge(String theResourceName, ResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequest) {
ourLog.info("Expunge: ResourceName[{}] Id[{}] Version[{}] Options[{}]", theResourceName, theResourceId != null ? theResourceId.getId() : null, theResourceId != null ? theResourceId.getVersion() : null, theExpungeOptions);
if (theExpungeOptions.getLimit() < 1) {
throw new InvalidRequestException(Msg.code(1087) + "Expunge limit may not be less than 1. Received expunge limit " + theExpungeOptions.getLimit() + ".");
}
if (theResourceName == null && theResourceId == null && theVersion == null) {
if (theResourceName == null && (theResourceId == null || (theResourceId.getId() == null && theResourceId.getVersion() == null))) {
if (theExpungeOptions.isExpungeEverything()) {
myExpungeEverythingService.expungeEverything(theRequest);
}
}
ExpungeOperation expungeOperation = getExpungeOperation(theResourceName, theResourceId, theVersion, theExpungeOptions, theRequest);
ExpungeOperation expungeOperation = getExpungeOperation(theResourceName, theResourceId, theExpungeOptions, theRequest);
return expungeOperation.call();
}
public void deleteAllSearchParams(Long theResourceId) {
public void deleteAllSearchParams(ResourcePersistentId theResourceId) {
myExpungeDaoService.deleteAllSearchParams(theResourceId);
}
}

View File

@ -21,20 +21,21 @@ package ca.uhn.fhir.jpa.dao.expunge;
*/
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public interface IResourceExpungeService {
List<Long> findHistoricalVersionsOfDeletedResources(String theResourceName, Long theResourceId, int theI);
List<ResourcePersistentId> findHistoricalVersionsOfDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theI);
List<Long> findHistoricalVersionsOfNonDeletedResources(String theResourceName, Long theResourceId, Long theVersion, int theI);
List<ResourcePersistentId> findHistoricalVersionsOfNonDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theI);
void expungeHistoricalVersions(RequestDetails theRequestDetails, List<Long> thePartition, AtomicInteger theRemainingCount);
void expungeHistoricalVersions(RequestDetails theRequestDetails, List<ResourcePersistentId> thePartition, AtomicInteger theRemainingCount);
void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<Long> theResourceIds, AtomicInteger theRemainingCount);
void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount);
void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<Long> theResourceIds, AtomicInteger theRemainingCount);
void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount);
void deleteAllSearchParams(Long theResourceId);
void deleteAllSearchParams(ResourcePersistentId theResourceId);
}

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao.expunge;
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.StopWatch;
import com.google.common.collect.Lists;
@ -57,7 +58,7 @@ public class PartitionRunner {
myThreadCount = theThreadCount;
}
public void runInPartitionedThreads(List<Long> theResourceIds, Consumer<List<Long>> partitionConsumer) {
public void runInPartitionedThreads(List<ResourcePersistentId> theResourceIds, Consumer<List<ResourcePersistentId>> partitionConsumer) {
List<Callable<Void>> callableTasks = buildCallableTasks(theResourceIds, partitionConsumer);
if (callableTasks.size() == 0) {
@ -92,7 +93,7 @@ public class PartitionRunner {
}
}
private List<Callable<Void>> buildCallableTasks(List<Long> theResourceIds, Consumer<List<Long>> partitionConsumer) {
private List<Callable<Void>> buildCallableTasks(List<ResourcePersistentId> theResourceIds, Consumer<List<ResourcePersistentId>> partitionConsumer) {
List<Callable<Void>> retval = new ArrayList<>();
if (myBatchSize > theResourceIds.size()) {
@ -100,9 +101,9 @@ public class PartitionRunner {
} else {
ourLog.info("Creating batch job of {} entries", theResourceIds.size());
}
List<List<Long>> partitions = Lists.partition(theResourceIds, myBatchSize);
List<List<ResourcePersistentId>> partitions = Lists.partition(theResourceIds, myBatchSize);
for (List<Long> nextPartition : partitions) {
for (List<ResourcePersistentId> nextPartition : partitions) {
if (nextPartition.size() > 0) {
Callable<Void> callableTask = () -> {
ourLog.info(myProcessName + " {} resources", nextPartition.size());

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -58,37 +58,37 @@
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu3</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r4</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r5</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<packaging>pom</packaging>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<name>HAPI-FHIR</name>
<description>An open-source implementation of the FHIR specification in Java.</description>
<url>https://hapifhir.io</url>
@ -2015,7 +2015,7 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-checkstyle</artifactId>
<!-- Remember to bump this when you upgrade the version -->
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.0.0-PRE10-SNAPSHOT</version>
<version>6.0.0-PRE11-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>