Resolve 5112 unable to expunge deleted codesystem until several minutes later (#5113)
* returned user-friendlier message, implemented unit tests, added changelog * reformatted file * added Msg.code to the exception thrown * added Msg.code in test * Changed to catch DataIntegrityViolationException only.
This commit is contained in:
parent
d31da211b9
commit
f68f3fbb0f
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 5112
|
||||
title: "Returns better diagnostics message to expunge requests that failed due to unfinished batch deletion"
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
package ca.uhn.fhir.jpa.dao.expunge;
|
||||
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
|
@ -51,6 +52,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
|||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -59,6 +61,7 @@ import org.hl7.fhir.instance.model.api.IIdType;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
@ -315,16 +318,22 @@ public class JpaResourceExpungeService implements IResourceExpungeService<JpaPid
|
|||
|
||||
deleteAllSearchParams(JpaPid.fromId(resource.getResourceId()));
|
||||
|
||||
if (resource.isHasTags()) {
|
||||
myResourceTagDao.deleteByResourceId(resource.getId());
|
||||
}
|
||||
try {
|
||||
if (resource.isHasTags()) {
|
||||
myResourceTagDao.deleteByResourceId(resource.getId());
|
||||
}
|
||||
|
||||
if (resource.getForcedId() != null) {
|
||||
ForcedId forcedId = resource.getForcedId();
|
||||
myForcedIdDao.deleteByPid(forcedId.getId());
|
||||
}
|
||||
if (resource.getForcedId() != null) {
|
||||
ForcedId forcedId = resource.getForcedId();
|
||||
myForcedIdDao.deleteByPid(forcedId.getId());
|
||||
}
|
||||
|
||||
myResourceTableDao.deleteByPid(resource.getId());
|
||||
myResourceTableDao.deleteByPid(resource.getId());
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
throw new PreconditionFailedException(Msg.code(2415)
|
||||
+ "The resource could not be expunged. It is likely due to unfinished asynchronous deletions, please try again later: "
|
||||
+ e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
|||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
|
@ -68,6 +69,7 @@ import static org.awaitility.Awaitility.await;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
@ -119,6 +121,15 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
private void assertNotExpunged(IIdType theId) {
|
||||
try {
|
||||
getDao(theId).read(theId);
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
private void assertStillThere(IIdType theId) {
|
||||
getDao(theId).read(theId);
|
||||
}
|
||||
|
@ -888,6 +899,28 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
|||
runInTransaction(this::verifyCodeSystemsAndChildrenExpunged);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCodeSystemByUrlThenExpungeWithoutWaitingForBatch() {
|
||||
//set up
|
||||
createStandardCodeSystems();
|
||||
|
||||
myCodeSystemDao.deleteByUrl("CodeSystem?url=" + URL_MY_CODE_SYSTEM, null);
|
||||
myTerminologyDeferredStorageSvc.saveDeferred();
|
||||
try {
|
||||
// execute
|
||||
myCodeSystemDao.expunge(new ExpungeOptions()
|
||||
.setExpungeDeletedResources(true)
|
||||
.setExpungeOldVersions(true), null);
|
||||
fail("expunge should not succeed since the delete batch job is not complete");
|
||||
} catch (InternalErrorException e){
|
||||
// verify
|
||||
assertNotExpunged(myOneVersionCodeSystemId.withVersion("2"));
|
||||
assertThat(e.getMessage(), startsWith(
|
||||
"HAPI-1084: ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException: HAPI-2415: The resource could not be ex" +
|
||||
"punged. It is likely due to unfinished asynchronous deletions, please try again later:"));
|
||||
}
|
||||
}
|
||||
|
||||
private List<Patient> createPatientsWithForcedIds(int theNumPatients) {
|
||||
RequestDetails requestDetails = new SystemRequestDetails();
|
||||
List<Patient> createdPatients = new ArrayList<>();
|
||||
|
|
Loading…
Reference in New Issue