Resolve 4952 PUT requests for resources that don't exist get created in sequential format rather than abiding by the ResourceServerIdStrategy (#4953)

* Test implemented, issue resolved

* fixed a logical bug in the previous change

* modified comment

* added tests for Dstu2&3 resources

* Adding afterEach constructions to reset spring context beans.

* resolved comments

---------

Co-authored-by: Ken Stevens <ken@smilecdr.com>
Co-authored-by: peartree <etienne.poirier@smilecdr.com>
This commit is contained in:
TynerGjs 2023-06-08 12:38:24 -04:00 committed by GitHub
parent e28398fc4c
commit fddea8db92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 1 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 4952
title: "Previously, the resource server Id strategy was not honoured when doing a create with a conditional update
operation on a resource where the ID was not assigned. This is now fixed."

View File

@ -1894,6 +1894,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
} }
} else { } else {
// assign UUID if no id provided in the request (numeric id mode is handled in doCreateForPostOrPut)
if (!theResource.getIdElement().hasIdPart() && getStorageSettings().getResourceServerIdStrategy() == JpaStorageSettings.IdStrategyEnum.UUID) {
theResource.setId(UUID.randomUUID().toString());
theResource.setUserData(JpaConstants.RESOURCE_ID_SERVER_ASSIGNED, Boolean.TRUE);
}
DaoMethodOutcome outcome = doCreateForPostOrPut(theRequest, resource, theMatchUrl, false, thePerformIndexing, theRequestPartitionId, update, theTransactionDetails); DaoMethodOutcome outcome = doCreateForPostOrPut(theRequest, resource, theMatchUrl, false, thePerformIndexing, theRequestPartitionId, update, theTransactionDetails);
// Pre-cache the match URL // Pre-cache the match URL

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.dstu2; package ca.uhn.fhir.jpa.dao.dstu2;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
@ -17,6 +18,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
@ -24,6 +26,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
@ -39,6 +42,11 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2UpdateTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2UpdateTest.class);
@AfterEach
public void afterEach(){
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.SEQUENTIAL_NUMERIC);
}
@Test @Test
public void testUpdateByUrl() { public void testUpdateByUrl() {
String methodName = "testUpdateByUrl"; String methodName = "testUpdateByUrl";
@ -350,4 +358,25 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
} }
@Test
void testCreateWithConditionalUpdate_withUuidAsServerResourceStrategyAndNoIdProvided_uuidAssignedAsResourceId() {
// setup
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID);
Patient p = new Patient();
p.addIdentifier().setSystem("http://my-lab-system").setValue("123");
p.addName().addFamily("FAM");
String theMatchUrl = "Patient?identifier=http://my-lab-system|123";
// execute
String result = myPatientDao.update(p, theMatchUrl, mySrd).getId().getIdPart();
// verify
try {
UUID.fromString(result);
} catch (IllegalArgumentException exception){
fail("Result id is not a UUID. Instead, it was: " + result);
}
}
} }

View File

@ -29,6 +29,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
@ -43,6 +44,11 @@ import static org.junit.jupiter.api.Assertions.fail;
public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test { public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3UpdateTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3UpdateTest.class);
@AfterEach
public void afterEach(){
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.SEQUENTIAL_NUMERIC);
}
@Test @Test
public void testReCreateMatchResource() { public void testReCreateMatchResource() {
@ -827,4 +833,24 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
} }
@Test
void testCreateWithConditionalUpdate_withUuidAsServerResourceStrategyAndNoIdProvided_uuidAssignedAsResourceId() {
// setup
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID);
Patient p = new Patient();
p.addIdentifier().setSystem("http://my-lab-system").setValue("123");
p.addName().setFamily("FAM");
String theMatchUrl = "Patient?identifier=http://my-lab-system|123";
// execute
String result = myPatientDao.update(p, theMatchUrl, mySrd).getId().getIdPart();
// verify
try {
UUID.fromString(result);
} catch (IllegalArgumentException exception){
fail("Result id is not a UUID. Instead, it was: " + result);
}
}
} }

View File

@ -52,7 +52,6 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ -71,6 +70,7 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields()); myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields());
myStorageSettings.setResourceServerIdStrategy(new JpaStorageSettings().getResourceServerIdStrategy()); myStorageSettings.setResourceServerIdStrategy(new JpaStorageSettings().getResourceServerIdStrategy());
myStorageSettings.setResourceClientIdStrategy(new JpaStorageSettings().getResourceClientIdStrategy()); myStorageSettings.setResourceClientIdStrategy(new JpaStorageSettings().getResourceClientIdStrategy());
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.SEQUENTIAL_NUMERIC);
} }
@ -1152,6 +1152,24 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
} }
@Test
void testCreateWithConditionalUpdate_withUuidAsServerResourceStrategyAndNoIdProvided_uuidAssignedAsResourceId() {
// setup
myStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID);
Patient p = new Patient();
p.addIdentifier().setSystem("http://my-lab-system").setValue("123");
p.addName().setFamily("FAM");
String theMatchUrl = "Patient?identifier=http://my-lab-system|123";
// execute
String result = myPatientDao.update(p, theMatchUrl, mySrd).getId().getIdPart();
// verify
try {
UUID.fromString(result);
} catch (IllegalArgumentException exception){
fail("Result id is not a UUID. Instead, it was: " + result);
}
}
} }