Improve logging for expunge operation

This commit is contained in:
James Agnew 2018-09-29 18:38:27 -04:00
parent 3e445faf47
commit 9f7e21fec6
5 changed files with 53 additions and 16 deletions

View File

@ -228,6 +228,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
protected ExpungeOutcome doExpunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
ourLog.info("Expunge: ResourceName[{}] Id[{}] Version[{}] Options[{}]", theResourceName, theResourceId, theVersion, theExpungeOptions);
if (!getConfig().isExpungeEnabled()) {
throw new MethodNotAllowedException("$expunge is not enabled on this server");
@ -249,19 +250,30 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
Pageable page = PageRequest.of(0, remainingCount.get());
Slice<Long> resourceIds = txTemplate.execute(t -> {
if (theResourceId != null) {
return myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId, theResourceName);
Slice<Long> ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId, theResourceName);
ourLog.info("Expunging {} deleted resources of type[{}] and ID[{}]", ids.getNumberOfElements(), theResourceName, theResourceId);
return ids;
} else {
if (theResourceName != null) {
return myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceName);
Slice<Long> ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceName);
ourLog.info("Expunging {} deleted resources of type[{}]", ids.getNumberOfElements(), theResourceName);
return ids;
} else {
return myResourceTableDao.findIdsOfDeletedResources(page);
Slice<Long> ids = myResourceTableDao.findIdsOfDeletedResources(page);
ourLog.info("Expunging {} deleted resources (all types)", ids.getNumberOfElements(), theResourceName);
return ids;
}
}
});
/*
* Delete historical versions
*/
for (Long next : resourceIds) {
txTemplate.execute(t -> {
expungeHistoricalVersionsOfId(next, remainingCount);
if (remainingCount.get() <= 0) {
ourLog.info("Expunge limit has been hit - Stopping operation");
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
return null;
@ -273,8 +285,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
*/
for (Long next : resourceIds) {
txTemplate.execute(t -> {
expungeCurrentVersionOfResource(next);
expungeCurrentVersionOfResource(next, remainingCount);
if (remainingCount.get() <= 0) {
ourLog.info("Expunge limit has been hit - Stopping operation");
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
return null;
@ -384,7 +397,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
ourLog.info("Query affected {} rows in {}: {}", outcome, sw.toString(), theQuery);
}
private void expungeCurrentVersionOfResource(Long theResourceId) {
private void expungeCurrentVersionOfResource(Long theResourceId, AtomicInteger theRemainingCount) {
ResourceTable resource = myResourceTableDao.findById(theResourceId).orElseThrow(IllegalStateException::new);
ResourceHistoryTable currentVersion = myResourceHistoryTableDao.findForIdAndVersion(resource.getId(), resource.getVersion());
@ -392,7 +405,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
expungeHistoricalVersion(currentVersion.getId());
}
ourLog.info("Deleting current version of resource {}", resource.getIdDt().getValue());
ourLog.info("Expunging current version of resource {}", resource.getIdDt().getValue());
myResourceIndexedSearchParamUriDao.deleteAll(resource.getParamsUri());
myResourceIndexedSearchParamCoordsDao.deleteAll(resource.getParamsCoords());
@ -414,6 +427,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
myResourceTableDao.delete(resource);
theRemainingCount.decrementAndGet();
}
protected void expungeHistoricalVersion(Long theNextVersionId) {
@ -427,9 +441,10 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
protected void expungeHistoricalVersionsOfId(Long theResourceId, AtomicInteger theRemainingCount) {
ResourceTable resource = myResourceTableDao.findById(theResourceId).orElseThrow(IllegalArgumentException::new);
Pageable page = new PageRequest(0, theRemainingCount.get());
Pageable page = PageRequest.of(0, theRemainingCount.get());
Slice<Long> versionIds = myResourceHistoryTableDao.findForResourceId(page, resource.getId(), resource.getVersion());
ourLog.info("Found {} versions of resource {} to expunge", versionIds.getNumberOfElements(), resource.getIdDt().getValue());
for (Long nextVersionId : versionIds) {
expungeHistoricalVersion(nextVersionId);
if (theRemainingCount.decrementAndGet() <= 0) {

View File

@ -1867,6 +1867,9 @@ public class SearchBuilder implements ISearchBuilder {
private void searchForIdsWithAndOr(String theResourceName, String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams) {
/*
* Filter out
*/
for (int andListIdx = 0; andListIdx < theAndOrParams.size(); andListIdx++) {
List<? extends IQueryParameterType> nextOrList = theAndOrParams.get(andListIdx);

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.util;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,12 +20,25 @@ package ca.uhn.fhir.jpa.util;
* #L%
*/
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class ExpungeOptions {
private int myLimit = 1000;
private boolean myExpungeOldVersions;
private boolean myExpungeDeletedResources;
private boolean myExpungeEverything;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("myLimit", myLimit)
.append("myExpungeOldVersions", myExpungeOldVersions)
.append("myExpungeDeletedResources", myExpungeDeletedResources)
.append("myExpungeEverything", myExpungeEverything)
.toString();
}
/**
* The maximum number of resources versions to expunge
*/
@ -33,6 +46,13 @@ public class ExpungeOptions {
return myLimit;
}
/**
* The maximum number of resource versions to expunge
*/
public void setLimit(int theLimit) {
myLimit = theLimit;
}
public boolean isExpungeEverything() {
return myExpungeEverything;
}
@ -42,13 +62,6 @@ public class ExpungeOptions {
return this;
}
/**
* The maximum number of resource versions to expunge
*/
public void setLimit(int theLimit) {
myLimit = theLimit;
}
public boolean isExpungeDeletedResources() {
return myExpungeDeletedResources;
}

View File

@ -416,6 +416,7 @@ public abstract class BaseJpaTest {
if (sw.getMillis() >= theTimeout) {
fail("Size " + theCallable.call() + " is != target " + theTarget);
}
Thread.sleep(500);
}
}

View File

@ -376,6 +376,11 @@
not try to read request parameters from the content stream. This avoids an incompatibility with
new versions of Jetty.
</action>
<action type="fix" issue="1050">
Custom profile names when not matching standard FHIR profile names, are now
handled properly by the validator. Thanks to Anthony Sute
for the Pull Request!
</action>
</release>
<release version="3.4.0" date="2018-05-28">
<action type="add">