-
Notifications
You must be signed in to change notification settings - Fork 1.4k
$delete-expunge over 10k resources will now delete all resources #5144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
lukedegruchy
merged 18 commits into
rel_6_8
from
ld-20230728-delete-expunge-over-10k-resources-deletes-only-10k
Aug 3, 2023
Merged
Changes from 11 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
76c2c66
First commit with very rough fix and unit test.
0ed77cf
Refinements to ResourceIdListStep and Batch2DaoSvcImpl. Make LoadIds…
fe106cf
Spotless
078e230
Fix checkstyle errors.
6ba6ea8
Fix test failures.
fc97ee7
Minor refactoring. New unit test. Finalize changelist.
910c49c
Spotless fix.
301315e
Delete now useless code from unit test.
fedb7c8
Delete more useless code.
289e49c
Test pre-commit hook
6f56260
More spotless fixes.
52d04a6
Merge remote-tracking branch 'origin/rel_6_8' into ld-20230728-delete…
32e2c8f
Address most code review feedback.
6d34ccf
Remove use of pageSize parameter and see if this breaks the pipeline.
f5438f3
Remove use of pageSize parameter and see if this breaks the pipeline.
d0ed91f
Fix the noUrl case by passing an unlimited Pegeable instead. Effecti…
daf419f
Deprecate the old method and have it call the new one by default.
610b4df
Add Msg code to Exception.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
...n/hapi/fhir/changelog/6_8_0/5150--delete-expunge-over-10k-resources-deletes-only-10k.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| type: fix | ||
| issue: 5150 | ||
| title: "When running a $delete-expunge with over 10,000 resources, only the first 10,000 resources were deleted. | ||
| This is now fixed." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/reindex/Batch2DaoSvcImplTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| package ca.uhn.fhir.jpa.reindex; | ||
|
|
||
| import ca.uhn.fhir.interceptor.model.RequestPartitionId; | ||
| import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; | ||
| import ca.uhn.fhir.jpa.api.dao.DaoRegistry; | ||
| import ca.uhn.fhir.jpa.api.pid.IResourcePidList; | ||
| import ca.uhn.fhir.jpa.api.svc.IBatch2DaoSvc; | ||
| import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService; | ||
| import ca.uhn.fhir.jpa.dao.tx.NonTransactionalHapiTransactionService; | ||
| import ca.uhn.fhir.jpa.searchparam.MatchUrlService; | ||
| import ca.uhn.fhir.jpa.test.BaseJpaR4Test; | ||
| import ca.uhn.fhir.model.primitive.IdDt; | ||
| import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; | ||
| import org.hl7.fhir.instance.model.api.IIdType; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.ValueSource; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
|
|
||
| import javax.annotation.Nonnull; | ||
| import java.time.LocalDate; | ||
| import java.time.Month; | ||
| import java.time.ZoneId; | ||
| import java.util.Date; | ||
| import java.util.List; | ||
| import java.util.stream.IntStream; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
| import static org.mockito.Mockito.spy; | ||
| import static org.mockito.Mockito.times; | ||
| import static org.mockito.Mockito.verify; | ||
|
|
||
| class Batch2DaoSvcImplTest extends BaseJpaR4Test { | ||
|
|
||
| private static final Date PREVIOUS_MILLENNIUM = toDate(LocalDate.of(1999, Month.DECEMBER, 31)); | ||
| private static final Date TOMORROW = toDate(LocalDate.now().plusDays(1)); | ||
| private static final String URL_PATIENT_EXPUNGE_TRUE = "Patient?_expunge=true"; | ||
| private static final String PATIENT = "Patient"; | ||
| private static final int INTERNAL_SYNCHRONOUS_SEARCH_SIZE = 10; | ||
|
|
||
| private final IHapiTransactionService myTransactionService = new NonTransactionalHapiTransactionService(); | ||
|
|
||
| @Autowired | ||
| private JpaStorageSettings myJpaStorageSettings; | ||
| @Autowired | ||
| private MatchUrlService myMatchUrlService; | ||
|
|
||
| private DaoRegistry mySpiedDaoRegistry; | ||
|
|
||
| private IBatch2DaoSvc mySubject; | ||
|
|
||
| @BeforeEach | ||
| void beforeEach() { | ||
| myJpaStorageSettings.setInternalSynchronousSearchSize(INTERNAL_SYNCHRONOUS_SEARCH_SIZE); | ||
|
|
||
| mySpiedDaoRegistry = spy(myDaoRegistry); | ||
|
|
||
| mySubject = new Batch2DaoSvcImpl(myResourceTableDao, myMatchUrlService, mySpiedDaoRegistry, myFhirContext, myTransactionService, myJpaStorageSettings); | ||
| } | ||
|
|
||
| // TODO: LD this test won't work with the nonUrl variant yet: error: No existing transaction found for transaction marked with propagation 'mandatory' | ||
|
|
||
| @Test | ||
| void fetchResourcesByUrlEmptyUrl() { | ||
| try { | ||
| mySubject.fetchResourceIdsPage(PREVIOUS_MILLENNIUM, TOMORROW, 800, RequestPartitionId.defaultPartition(), ""); | ||
| } catch (InternalErrorException exception) { | ||
| assertEquals("HAPI-2422: this should never happen: URL is missing a '?'", exception.getMessage()); | ||
| } catch (Exception exception) { | ||
| fail("caught wrong Exception"); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| void fetchResourcesByUrlSingleQuestionMark() { | ||
| try { | ||
| mySubject.fetchResourceIdsPage(PREVIOUS_MILLENNIUM, TOMORROW, 800, RequestPartitionId.defaultPartition(), "?"); | ||
| } catch (InternalErrorException exception) { | ||
| assertEquals("HAPI-2223: theResourceName must not be blank", exception.getMessage()); | ||
| } catch (Exception exception) { | ||
| fail("caught wrong Exception"); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| void fetchResourcesByUrlNonsensicalResource() { | ||
| try { | ||
| mySubject.fetchResourceIdsPage(PREVIOUS_MILLENNIUM, TOMORROW, 800, RequestPartitionId.defaultPartition(), "Banana?_expunge=true"); | ||
| } catch (InternalErrorException exception) { | ||
| assertEquals("HAPI-2223: HAPI-1684: Unknown resource name \"Banana\" (this name is not known in FHIR version \"R4\")", exception.getMessage()); | ||
| } catch (Exception exception) { | ||
| fail("caught wrong Exception"); | ||
| } | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @ValueSource(ints = {0, 9, 10, 11, 21, 22, 23, 45}) | ||
| void fetchResourcesByUrl(int expectedNumResults) { | ||
| final List<IIdType> patientIds = IntStream.range(0, expectedNumResults) | ||
| .mapToObj(num -> createPatient()) | ||
| .toList(); | ||
|
|
||
| final IResourcePidList resourcePidList = mySubject.fetchResourceIdsPage(PREVIOUS_MILLENNIUM, TOMORROW, 800, RequestPartitionId.defaultPartition(), URL_PATIENT_EXPUNGE_TRUE); | ||
|
|
||
| final List<? extends IIdType> actualPatientIds = | ||
| resourcePidList.getTypedResourcePids() | ||
| .stream() | ||
| .map(typePid -> new IdDt(typePid.resourceType, (Long) typePid.id.getId())) | ||
| .toList(); | ||
| assertIdsEqual(patientIds, actualPatientIds); | ||
|
|
||
| verify(mySpiedDaoRegistry, times(getExpectedNumOfInvocations(expectedNumResults))).getResourceDao(PATIENT); | ||
| } | ||
|
|
||
| private int getExpectedNumOfInvocations(int expectedNumResults) { | ||
| final int maxResultsPerQuery = INTERNAL_SYNCHRONOUS_SEARCH_SIZE + 1; | ||
| final int division = expectedNumResults / maxResultsPerQuery; | ||
| return division + 1; | ||
| } | ||
|
|
||
| private static void assertIdsEqual(List<IIdType> expectedResourceIds, List<? extends IIdType> actualResourceIds) { | ||
| assertEquals(expectedResourceIds.size(), actualResourceIds.size()); | ||
|
|
||
| for (int index = 0; index < expectedResourceIds.size(); index++) { | ||
| final IIdType expectedIdType = expectedResourceIds.get(index); | ||
| final IIdType actualIdType = actualResourceIds.get(index); | ||
|
|
||
| assertEquals(expectedIdType.getResourceType(), actualIdType.getResourceType()); | ||
| assertEquals(expectedIdType.getIdPartAsLong(), actualIdType.getIdPartAsLong()); | ||
| } | ||
| } | ||
|
|
||
| @Nonnull | ||
| private static Date toDate(LocalDate theLocalDate) { | ||
| return Date.from(theLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.