fixed resource fullUrl in _history bundles (#5815)
This commit is contained in:
parent
6ce3b17460
commit
70843cdf45
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 5088
|
||||
title: "Previously, the fullUrl for resources in _history bundles was not generated correctly when using a client
|
||||
provided id. The same problem started to happen for the resources with server generated ids more recently
|
||||
(after 6.9.10). This has now been fixed"
|
|
@ -167,6 +167,14 @@ public class HistoryBuilder {
|
|||
Optional<String> forcedId = pidToForcedId.get(JpaPid.fromId(nextResourceId));
|
||||
if (forcedId.isPresent()) {
|
||||
resourceId = forcedId.get();
|
||||
// IdHelperService returns a forcedId with the '<resourceType>/' prefix
|
||||
// but the transientForcedId is expected to be just the idPart (without the <resourceType>/ prefix).
|
||||
// For that reason, strip the prefix before setting the transientForcedId below.
|
||||
// If not stripped this messes up the id of the resource as the resourceType would be repeated
|
||||
// twice like Patient/Patient/1234 in the resource constructed
|
||||
if (resourceId.startsWith(myResourceType + "/")) {
|
||||
resourceId = resourceId.substring(myResourceType.length() + 1);
|
||||
}
|
||||
} else {
|
||||
resourceId = nextResourceId.toString();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
|||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.term.ZipCollectionBuilder;
|
||||
import ca.uhn.fhir.jpa.test.config.TestR4Config;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.jpa.util.QueryParameterUtils;
|
||||
import ca.uhn.fhir.model.api.StorageResponseCodeEnum;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
|
@ -2404,6 +2405,100 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
assertThat(idValues, hasSize(0));
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"false,PatientWithServerGeneratedId1",
|
||||
"true,PatientWithServerGeneratedId2"
|
||||
})
|
||||
public void testHistoryOnInstanceWithServerGeneratedId(boolean theInvalidateCacheBeforeHistory,
|
||||
String thePatientFamilyName) {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addName().setFamily(thePatientFamilyName);
|
||||
IIdType id = myClient.create().resource(patient).execute().getId().toVersionless();
|
||||
ourLog.info("Res ID: {}", id);
|
||||
|
||||
final String expectedFullUrl = myServerBase + "/Patient/" + id.getIdPart();
|
||||
|
||||
if (theInvalidateCacheBeforeHistory) {
|
||||
// the reason for this test parameterization to invalidate the cache is that
|
||||
// when a resource is created/updated, its id mapping is cached for 1 minute so
|
||||
// retrieving the history right after creating the resource will use the cached value.
|
||||
// By invalidating the cache here and getting the history bundle again,
|
||||
// we test the scenario where the id mapping needs to be read from the db,
|
||||
// hence testing a different code path.
|
||||
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
||||
}
|
||||
|
||||
Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
|
||||
assertEquals(1, history.getEntry().size());
|
||||
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
||||
// validate entry.fullUrl
|
||||
assertEquals(expectedFullUrl, historyEntry0.getFullUrl());
|
||||
//validate entry.request
|
||||
assertEquals(HTTPVerb.POST, historyEntry0.getRequest().getMethod());
|
||||
assertEquals("Patient/" + id.getIdPart() + "/_history/1", historyEntry0.getRequest().getUrl());
|
||||
//validate entry.response
|
||||
assertEquals("201 Created", historyEntry0.getResponse().getStatus());
|
||||
assertNotNull(historyEntry0.getResponse().getEtag());
|
||||
|
||||
//validate patient resource details in the entry
|
||||
Patient historyEntry0Patient = (Patient) historyEntry0.getResource();
|
||||
assertEquals(id.withVersion("1").getValue(), historyEntry0Patient.getId());
|
||||
assertEquals(1, historyEntry0Patient.getName().size());
|
||||
assertEquals(thePatientFamilyName, historyEntry0Patient.getName().get(0).getFamily());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"false,PatientWithForcedId1",
|
||||
"true,PatientWithForcedId2"
|
||||
})
|
||||
public void testHistoryOnInstanceWithForcedId(boolean theInvalidateCacheBeforeHistory,
|
||||
String thePatientFamilyName) {
|
||||
|
||||
final String patientForcedId = thePatientFamilyName + "-ForcedId";
|
||||
Patient patient = new Patient();
|
||||
patient.addName().setFamily(thePatientFamilyName);
|
||||
patient.setId(patientForcedId);
|
||||
IIdType id = myClient.update().resource(patient).execute().getId().toVersionless();
|
||||
ourLog.info("Res ID: {}", id);
|
||||
assertEquals(patientForcedId, id.getIdPart());
|
||||
|
||||
final String expectedFullUrl = myServerBase + "/Patient/" + id.getIdPart();
|
||||
|
||||
if (theInvalidateCacheBeforeHistory) {
|
||||
// the reason for this test parameterization to invalidate the cache is that
|
||||
// when a resource is created/updated, its id mapping is cached for 1 minute so
|
||||
// retrieving the history right after creating the resource will use the cached value.
|
||||
// By invalidating the cache here and getting the history bundle again,
|
||||
// we test the scenario where the id mapping needs to be read from the db,
|
||||
// hence testing a different code path.
|
||||
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
||||
}
|
||||
|
||||
Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
|
||||
assertEquals(1, history.getEntry().size());
|
||||
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
||||
// validate entry.fullUrl
|
||||
assertEquals(expectedFullUrl, historyEntry0.getFullUrl());
|
||||
//validate entry.request
|
||||
assertEquals(HTTPVerb.POST, historyEntry0.getRequest().getMethod());
|
||||
assertEquals("Patient/" + id.getIdPart() + "/_history/1", historyEntry0.getRequest().getUrl());
|
||||
//validate entry.response
|
||||
assertEquals("201 Created", historyEntry0.getResponse().getStatus());
|
||||
assertNotNull(historyEntry0.getResponse().getEtag());
|
||||
|
||||
//validate patient resource details in the entry
|
||||
Patient historyEntry0Patient = (Patient) historyEntry0.getResource();
|
||||
assertEquals(id.withVersion("1").getValue(), historyEntry0Patient.getId());
|
||||
assertEquals(1, historyEntry0Patient.getName().size());
|
||||
assertEquals(thePatientFamilyName, historyEntry0Patient.getName().get(0).getFamily());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistoryWithDeletedResource() {
|
||||
String methodName = "testHistoryWithDeletedResource";
|
||||
|
|
Loading…
Reference in New Issue