Conditional update on Partitioned Server fails (#1870)

* Fix #1869

* Remove FIXME

* Test fix

* Test fix
This commit is contained in:
James Agnew 2020-05-27 10:40:29 -04:00 committed by GitHub
parent 5482367e37
commit 22af36ae7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 11 deletions

View File

@ -204,6 +204,9 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails, HttpServletResponse theServletResponse);
/**
* Search for IDs for processing a match URLs, etc.
*/
Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest);
/**

View File

@ -1221,9 +1221,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
@Override
public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
IBasePersistedResource theEntity2, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) {
IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) {
ResourceTable entity = (ResourceTable) theEntity2;
ResourceTable entity = (ResourceTable) theEntity;
// We'll update the resource ID with the correct version later but for
// now at least set it to something useful for the interceptors

View File

@ -35,6 +35,7 @@ import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@Service
@ -67,13 +68,20 @@ public class DaoSearchParamSynchronizer {
}
private <T extends BaseResourceIndex> void synchronize(ResourceTable theEntity, AddRemoveCount theAddRemoveCount, Collection<T> theNewParams, Collection<T> theExistingParams) {
for (T next : theNewParams) {
Collection<T> newParams = theNewParams;
for (T next : newParams) {
next.setPartitionId(theEntity.getPartitionId());
next.calculateHashes();
}
List<T> paramsToRemove = subtract(theExistingParams, theNewParams);
List<T> paramsToAdd = subtract(theNewParams, theExistingParams);
/*
* HashCodes may have changed as a result of setting the partition ID, so
* create a new set that will reflect the new hashcodes
*/
newParams = new HashSet<>(newParams);
List<T> paramsToRemove = subtract(theExistingParams, newParams);
List<T> paramsToAdd = subtract(newParams, theExistingParams);
tryToReuseIndexEntities(paramsToRemove, paramsToAdd);
for (T next : paramsToRemove) {
@ -127,8 +135,12 @@ public class DaoSearchParamSynchronizer {
return new ArrayList<>();
}
ArrayList<T> retVal = new ArrayList<>(theSubtractFrom);
retVal.removeAll(theToSubtract);
ArrayList<T> retVal = new ArrayList<>();
for (T next : theSubtractFrom) {
if (!theToSubtract.contains(next)) {
retVal.add(next);
}
}
return retVal;
}
}

View File

@ -68,6 +68,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
@ -701,6 +702,60 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
}
@Test
public void testUpdateConditionalInPartition() {
myDaoConfig.setIndexMissingFields(DaoConfig.IndexEnabledEnum.DISABLED);
createRequestId();
// Create a resource
addCreatePartition(myPartitionId, myPartitionDate);
addReadPartition(myPartitionId);
Patient p = new Patient();
p.setActive(false);
p.addIdentifier().setValue("12345");
Long patientId = myPatientDao.update(p, "Patient?identifier=12345", mySrd).getId().getIdPartAsLong();
runInTransaction(() -> {
// HFJ_RESOURCE
assertEquals(1, myResourceTableDao.count());
ResourceTable resourceTable = myResourceTableDao.findById(patientId).orElseThrow(IllegalArgumentException::new);
assertEquals(myPartitionId, resourceTable.getPartitionId().getPartitionId().intValue());
assertEquals(myPartitionDate, resourceTable.getPartitionId().getPartitionDate());
// HFJ_SPIDX_TOKEN
ourLog.info("Tokens:\n * {}", myResourceIndexedSearchParamTokenDao.findAll().stream().map(t->t.toString()).collect(Collectors.joining("\n * ")));
assertEquals(3, myResourceIndexedSearchParamTokenDao.countForResourceId(patientId));
});
// Update that resource
addReadPartition(myPartitionId);
p = new Patient();
p.setActive(true);
p.addIdentifier().setValue("12345");
Long patientId2 = myPatientDao.update(p, "Patient?identifier=12345", mySrd).getId().getIdPartAsLong();
assertEquals(patientId, patientId2);
runInTransaction(() -> {
// HFJ_RESOURCE
assertEquals(1, myResourceTableDao.count());
ResourceTable resourceTable = myResourceTableDao.findById(patientId).orElseThrow(IllegalArgumentException::new);
assertEquals(myPartitionId, resourceTable.getPartitionId().getPartitionId().intValue());
assertEquals(myPartitionDate, resourceTable.getPartitionId().getPartitionDate());
// HFJ_SPIDX_TOKEN
ourLog.info("Tokens:\n * {}", myResourceIndexedSearchParamTokenDao.findAll().stream().map(t->t.toString()).collect(Collectors.joining("\n * ")));
assertEquals(3, myResourceIndexedSearchParamTokenDao.countForResourceId(patientId));
// HFJ_RES_VER
int version = 2;
ResourceHistoryTable resVer = myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(patientId, version);
assertEquals(myPartitionId, resVer.getPartitionId().getPartitionId().intValue());
assertEquals(myPartitionDate, resVer.getPartitionId().getPartitionDate());
});
}
@Test
public void testRead_PidId_AllPartitions() {
IIdType patientId1 = createPatient(withPartition(1), withActiveTrue());

View File

@ -104,9 +104,6 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
empiLink.addIndex("20200517.5", "IDX_EMPI_PERSON_TGT").unique(true).withColumns("PERSON_PID", "TARGET_PID");
// TRM_CONCEPT_PROPERTY
// version.onTable("TRM_CONCEPT_PROPERTY").addIndex("20200523.1", "IDX_CONCEPTPROP_CONCEPTPID").unique(false).withColumns("CONCEPT_PID");
}
protected void init500() { // 20200218 - 20200519

View File

@ -59,7 +59,7 @@ import static org.apache.commons.lang3.StringUtils.trim;
@Index(name = "IDX_SP_TOKEN_HASH_S", columnList = "HASH_SYS"),
@Index(name = "IDX_SP_TOKEN_HASH_SV", columnList = "HASH_SYS_AND_VALUE"),
// TODO PERF change this to:
// @Index(name = "IDX_SP_TOKEN_HASH_V", columnList = "HASH_VALUE,RES_ID"),
// @Index(name = "IDX_SP_TOKEN_HASH_V", columnList = "HASH_VALUE,RES_ID"),
@Index(name = "IDX_SP_TOKEN_HASH_V", columnList = "HASH_VALUE"),
@Index(name = "IDX_SP_TOKEN_UPDATED", columnList = "SP_UPDATED"),
@ -232,6 +232,7 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa
b.append(getHashValue());
b.append(getHashSystem());
b.append(getHashSystemAndValue());
return b.toHashCode();
}