Improve logging for expunge operation
This commit is contained in:
parent
3e445faf47
commit
9f7e21fec6
|
@ -228,6 +228,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
|
|
||||||
protected ExpungeOutcome doExpunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
|
protected ExpungeOutcome doExpunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
|
||||||
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
|
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
|
ourLog.info("Expunge: ResourceName[{}] Id[{}] Version[{}] Options[{}]", theResourceName, theResourceId, theVersion, theExpungeOptions);
|
||||||
|
|
||||||
if (!getConfig().isExpungeEnabled()) {
|
if (!getConfig().isExpungeEnabled()) {
|
||||||
throw new MethodNotAllowedException("$expunge is not enabled on this server");
|
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());
|
Pageable page = PageRequest.of(0, remainingCount.get());
|
||||||
Slice<Long> resourceIds = txTemplate.execute(t -> {
|
Slice<Long> resourceIds = txTemplate.execute(t -> {
|
||||||
if (theResourceId != null) {
|
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 {
|
} else {
|
||||||
if (theResourceName != null) {
|
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 {
|
} 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) {
|
for (Long next : resourceIds) {
|
||||||
txTemplate.execute(t -> {
|
txTemplate.execute(t -> {
|
||||||
expungeHistoricalVersionsOfId(next, remainingCount);
|
expungeHistoricalVersionsOfId(next, remainingCount);
|
||||||
if (remainingCount.get() <= 0) {
|
if (remainingCount.get() <= 0) {
|
||||||
|
ourLog.info("Expunge limit has been hit - Stopping operation");
|
||||||
return toExpungeOutcome(theExpungeOptions, remainingCount);
|
return toExpungeOutcome(theExpungeOptions, remainingCount);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -273,8 +285,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
*/
|
*/
|
||||||
for (Long next : resourceIds) {
|
for (Long next : resourceIds) {
|
||||||
txTemplate.execute(t -> {
|
txTemplate.execute(t -> {
|
||||||
expungeCurrentVersionOfResource(next);
|
expungeCurrentVersionOfResource(next, remainingCount);
|
||||||
if (remainingCount.get() <= 0) {
|
if (remainingCount.get() <= 0) {
|
||||||
|
ourLog.info("Expunge limit has been hit - Stopping operation");
|
||||||
return toExpungeOutcome(theExpungeOptions, remainingCount);
|
return toExpungeOutcome(theExpungeOptions, remainingCount);
|
||||||
}
|
}
|
||||||
return null;
|
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);
|
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);
|
ResourceTable resource = myResourceTableDao.findById(theResourceId).orElseThrow(IllegalStateException::new);
|
||||||
|
|
||||||
ResourceHistoryTable currentVersion = myResourceHistoryTableDao.findForIdAndVersion(resource.getId(), resource.getVersion());
|
ResourceHistoryTable currentVersion = myResourceHistoryTableDao.findForIdAndVersion(resource.getId(), resource.getVersion());
|
||||||
|
@ -392,7 +405,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
expungeHistoricalVersion(currentVersion.getId());
|
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());
|
myResourceIndexedSearchParamUriDao.deleteAll(resource.getParamsUri());
|
||||||
myResourceIndexedSearchParamCoordsDao.deleteAll(resource.getParamsCoords());
|
myResourceIndexedSearchParamCoordsDao.deleteAll(resource.getParamsCoords());
|
||||||
|
@ -414,6 +427,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
|
|
||||||
myResourceTableDao.delete(resource);
|
myResourceTableDao.delete(resource);
|
||||||
|
|
||||||
|
theRemainingCount.decrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void expungeHistoricalVersion(Long theNextVersionId) {
|
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) {
|
protected void expungeHistoricalVersionsOfId(Long theResourceId, AtomicInteger theRemainingCount) {
|
||||||
ResourceTable resource = myResourceTableDao.findById(theResourceId).orElseThrow(IllegalArgumentException::new);
|
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());
|
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) {
|
for (Long nextVersionId : versionIds) {
|
||||||
expungeHistoricalVersion(nextVersionId);
|
expungeHistoricalVersion(nextVersionId);
|
||||||
if (theRemainingCount.decrementAndGet() <= 0) {
|
if (theRemainingCount.decrementAndGet() <= 0) {
|
||||||
|
|
|
@ -1867,6 +1867,9 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
|
|
||||||
private void searchForIdsWithAndOr(String theResourceName, String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams) {
|
private void searchForIdsWithAndOr(String theResourceName, String theParamName, List<List<? extends IQueryParameterType>> theAndOrParams) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Filter out
|
||||||
|
*/
|
||||||
for (int andListIdx = 0; andListIdx < theAndOrParams.size(); andListIdx++) {
|
for (int andListIdx = 0; andListIdx < theAndOrParams.size(); andListIdx++) {
|
||||||
List<? extends IQueryParameterType> nextOrList = theAndOrParams.get(andListIdx);
|
List<? extends IQueryParameterType> nextOrList = theAndOrParams.get(andListIdx);
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.util;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -20,12 +20,25 @@ package ca.uhn.fhir.jpa.util;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
public class ExpungeOptions {
|
public class ExpungeOptions {
|
||||||
private int myLimit = 1000;
|
private int myLimit = 1000;
|
||||||
private boolean myExpungeOldVersions;
|
private boolean myExpungeOldVersions;
|
||||||
private boolean myExpungeDeletedResources;
|
private boolean myExpungeDeletedResources;
|
||||||
private boolean myExpungeEverything;
|
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
|
* The maximum number of resources versions to expunge
|
||||||
*/
|
*/
|
||||||
|
@ -33,6 +46,13 @@ public class ExpungeOptions {
|
||||||
return myLimit;
|
return myLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of resource versions to expunge
|
||||||
|
*/
|
||||||
|
public void setLimit(int theLimit) {
|
||||||
|
myLimit = theLimit;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isExpungeEverything() {
|
public boolean isExpungeEverything() {
|
||||||
return myExpungeEverything;
|
return myExpungeEverything;
|
||||||
}
|
}
|
||||||
|
@ -42,13 +62,6 @@ public class ExpungeOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of resource versions to expunge
|
|
||||||
*/
|
|
||||||
public void setLimit(int theLimit) {
|
|
||||||
myLimit = theLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExpungeDeletedResources() {
|
public boolean isExpungeDeletedResources() {
|
||||||
return myExpungeDeletedResources;
|
return myExpungeDeletedResources;
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,6 +416,7 @@ public abstract class BaseJpaTest {
|
||||||
if (sw.getMillis() >= theTimeout) {
|
if (sw.getMillis() >= theTimeout) {
|
||||||
fail("Size " + theCallable.call() + " is != target " + theTarget);
|
fail("Size " + theCallable.call() + " is != target " + theTarget);
|
||||||
}
|
}
|
||||||
|
Thread.sleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,6 +376,11 @@
|
||||||
not try to read request parameters from the content stream. This avoids an incompatibility with
|
not try to read request parameters from the content stream. This avoids an incompatibility with
|
||||||
new versions of Jetty.
|
new versions of Jetty.
|
||||||
</action>
|
</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>
|
||||||
<release version="3.4.0" date="2018-05-28">
|
<release version="3.4.0" date="2018-05-28">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue