4175-$validate-operation-on-a-resource-update-results-in-an-error-stating-resource-has-no-id (#4181)

* Added unit test + solution

* Changelog

* Cleanup

* changelog filename
This commit is contained in:
karneet1212 2022-10-26 13:29:28 -04:00 committed by GitHub
parent 296ddb8a37
commit 0a160a35ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 1 deletions

View File

@ -0,0 +1,7 @@
---
type: fix
issue: 4175
jira: SMILE-4872
title: "Previously, performing $validate operation on resource update and sending the resource as a
parameter in the request body would result in an error stating that the resource was missing id.
This has been fixed by allowing the resource to be processed correctly when sent as a parameter."

View File

@ -122,6 +122,8 @@ import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Required;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@ -135,6 +137,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.Parameter;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@ -2024,7 +2027,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override @Override
public void validateResource(IValidationContext<IBaseResource> theCtx) { public void validateResource(IValidationContext<IBaseResource> theCtx) {
boolean hasId = theCtx.getResource().getIdElement().hasIdPart(); IBaseResource resource = theCtx.getResource();
if (resource instanceof Parameters) {
List<ParametersParameterComponent> params = ((Parameters) resource).getParameter();
params = params.stream().filter(param -> param.getName().contains("resource")).collect(Collectors.toList());
resource = params.get(0).getResource();
}
boolean hasId = resource.getIdElement().hasIdPart();
if (myMode == ValidationModeEnum.CREATE) { if (myMode == ValidationModeEnum.CREATE) {
if (hasId) { if (hasId) {
throw new UnprocessableEntityException(Msg.code(997) + "Resource has an ID - ID must not be populated for a FHIR create"); throw new UnprocessableEntityException(Msg.code(997) + "Resource has an ID - ID must not be populated for a FHIR create");

View File

@ -57,6 +57,7 @@ import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Observation.ObservationStatus; import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.Quantity;
@ -1633,6 +1634,34 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} }
@Test
public void testValidateRawResourceForUpdateWithId() {
String methodName = "testValidateForUpdate";
Patient pat = new Patient();
pat.setId("Patient/123");
pat.addName().setFamily(methodName);
Parameters params = new Parameters();
params.addParameter().setName("resource").setResource(pat);
String rawResource = myFhirContext.newJsonParser().encodeResourceToString(params);
myPatientDao.validate(pat, null, rawResource, EncodingEnum.JSON, ValidationModeEnum.UPDATE, null, mySrd);
}
@Test
public void testValidateRawResourceForUpdateWithNoId() {
String methodName = "testValidateForUpdate";
Patient pat = new Patient();
pat.addName().setFamily(methodName);
Parameters params = new Parameters();
params.addParameter().setName("resource").setResource(pat);
String rawResource = myFhirContext.newJsonParser().encodeResourceToString(params);
try {
myPatientDao.validate(pat, null, rawResource, EncodingEnum.JSON, ValidationModeEnum.UPDATE, null, mySrd);
fail();
} catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must be populated"));
}
}
@Test @Test
public void testValidateForUpdateWithContained() { public void testValidateForUpdateWithContained() {
String methodName = "testValidateForUpdate"; String methodName = "testValidateForUpdate";