bundle not throwing an error when multiple matches were found (#4283)

* Added test + condition to throw error

* changelog

* changes made based on comments
This commit is contained in:
karneet1212 2022-11-21 10:08:10 -05:00 committed by GitHub
parent b1e3468dcd
commit 62c630c546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 0 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 4281
title: "Previously, when creating a bundle, if multiple resources matched the conditional URL provided
in the request, it would process the request using the last resource found as a match.
An error is now thrown when multiple resources are found"

View File

@ -1881,6 +1881,41 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
}
}
@Test
public void testTransactionCreateMatchUrlWithTwoMatch2() {
String methodName = "testTransactionCreateMatchUrlWithTwoMatch";
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IIdType id = myPatientDao.create(p, mySrd).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
id = myPatientDao.create(p, mySrd).getId();
ourLog.info("Created patient, got it: {}", id);
Bundle request = new Bundle();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().setFamily("Hello");
p.setId("Patient/" + methodName);
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName);
Observation o = new Observation();
o.addIdentifier().setSystem("urn:system").setValue(methodName);
o.getCode().setText("Some Observation");
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Observation?identifier=urn%3Asystem%7C" + methodName);
try {
mySystemDao.transaction(mySrd, request);
fail();
} catch (PreconditionFailedException e) {
assertThat(e.getMessage(), containsString("Multiple resources match this search"));
}
}
@Test
public void testTransactionCreateMatchUrlWithZeroMatch() {
String methodName = "testTransactionCreateMatchUrlWithZeroMatch";

View File

@ -20,9 +20,11 @@ package ca.uhn.fhir.rest.api.server.storage;
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import org.apache.commons.lang3.Validate;
@ -162,10 +164,20 @@ public class TransactionDetails {
if (myResolvedMatchUrls.isEmpty()) {
myResolvedMatchUrls = new HashMap<>();
} else if (matchUrlWithDiffIdExists(theConditionalUrl, thePersistentId)) {
String msg = "Invalid match URL " + theConditionalUrl + " - Multiple resources match this search";
throw new PreconditionFailedException(Msg.code(2207) + msg);
}
myResolvedMatchUrls.put(theConditionalUrl, thePersistentId);
}
private boolean matchUrlWithDiffIdExists(String theConditionalUrl, @Nonnull ResourcePersistentId thePersistentId) {
if (myResolvedMatchUrls.containsKey(theConditionalUrl) && myResolvedMatchUrls.get(theConditionalUrl) != NOT_FOUND) {
return myResolvedMatchUrls.get(theConditionalUrl).getId() != thePersistentId.getId();
}
return false;
}
/**
* This is the wall-clock time that a given transaction started.
*/