Correctly process ifMatch in Bundle entries for JPA server transaction
This commit is contained in:
parent
78b7188fbc
commit
9b31741147
|
@ -29,6 +29,7 @@ import java.util.Map.Entry;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||||
|
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
@ -438,7 +439,11 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
DaoMethodOutcome outcome;
|
DaoMethodOutcome outcome;
|
||||||
UrlParts parts = UrlUtil.parseUrl(url);
|
UrlParts parts = UrlUtil.parseUrl(url);
|
||||||
if (isNotBlank(parts.getResourceId())) {
|
if (isNotBlank(parts.getResourceId())) {
|
||||||
res.setId(new IdType(parts.getResourceType(), parts.getResourceId()));
|
String version = null;
|
||||||
|
if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) {
|
||||||
|
version = ParameterUtil.parseETagValue(nextReqEntry.getRequest().getIfMatch());
|
||||||
|
}
|
||||||
|
res.setId(new IdType(parts.getResourceType(), parts.getResourceId(), version));
|
||||||
outcome = resourceDao.update(res, null, false, theRequestDetails);
|
outcome = resourceDao.update(res, null, false, theRequestDetails);
|
||||||
} else {
|
} else {
|
||||||
res.setId((String) null);
|
res.setId((String) null);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
|
@ -435,7 +436,11 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
DaoMethodOutcome outcome;
|
DaoMethodOutcome outcome;
|
||||||
UrlParts parts = UrlUtil.parseUrl(url);
|
UrlParts parts = UrlUtil.parseUrl(url);
|
||||||
if (isNotBlank(parts.getResourceId())) {
|
if (isNotBlank(parts.getResourceId())) {
|
||||||
res.setId(new IdType(parts.getResourceType(), parts.getResourceId()));
|
String version = null;
|
||||||
|
if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) {
|
||||||
|
version = ParameterUtil.parseETagValue(nextReqEntry.getRequest().getIfMatch());
|
||||||
|
}
|
||||||
|
res.setId(new IdType(parts.getResourceType(), parts.getResourceId(), version));
|
||||||
outcome = resourceDao.update(res, null, false, theRequestDetails);
|
outcome = resourceDao.update(res, null, false, theRequestDetails);
|
||||||
} else {
|
} else {
|
||||||
res.setId((String) null);
|
res.setId((String) null);
|
||||||
|
|
|
@ -1879,6 +1879,91 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
||||||
assertNull(nextEntry.getResource());
|
assertNull(nextEntry.getResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionWithIfMatch() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("P1");
|
||||||
|
p.setActive(true);
|
||||||
|
myPatientDao.update(p);
|
||||||
|
|
||||||
|
p.setActive(false);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient/P1")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.PUT)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfMatch("2");
|
||||||
|
|
||||||
|
try {
|
||||||
|
mySystemDao.transaction(mySrd, b);
|
||||||
|
} catch (ResourceVersionConflictException e) {
|
||||||
|
assertEquals("Trying to update Patient/P1/_history/2 but this is not the current version", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient/P1")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.PUT)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfMatch("1");
|
||||||
|
|
||||||
|
Bundle resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertEquals("Patient/P1/_history/2", new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionWithIfNoneExist() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("P1");
|
||||||
|
p.setActive(true);
|
||||||
|
myPatientDao.update(p);
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.addName().setFamily("AAA");
|
||||||
|
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.POST)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfNoneExist("Patient?active=true");
|
||||||
|
|
||||||
|
Bundle resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertEquals("Patient/P1/_history/1", new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue());
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.addName().setFamily("AAA");
|
||||||
|
|
||||||
|
b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.POST)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfNoneExist("Patient?active=false");
|
||||||
|
|
||||||
|
resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertThat( new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue(), matchesPattern("Patient/[0-9]+/_history/1"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionSearchWithCount() {
|
public void testTransactionSearchWithCount() {
|
||||||
String methodName = "testTransactionSearchWithCount";
|
String methodName = "testTransactionSearchWithCount";
|
||||||
|
|
|
@ -587,6 +587,90 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionWithIfMatch() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("P1");
|
||||||
|
p.setActive(true);
|
||||||
|
myPatientDao.update(p);
|
||||||
|
|
||||||
|
p.setActive(false);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient/P1")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.PUT)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfMatch("2");
|
||||||
|
|
||||||
|
try {
|
||||||
|
mySystemDao.transaction(mySrd, b);
|
||||||
|
} catch (ResourceVersionConflictException e) {
|
||||||
|
assertEquals("Trying to update Patient/P1/_history/2 but this is not the current version", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient/P1")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.PUT)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfMatch("1");
|
||||||
|
|
||||||
|
Bundle resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertEquals("Patient/P1/_history/2", new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionWithIfNoneExist() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("P1");
|
||||||
|
p.setActive(true);
|
||||||
|
myPatientDao.update(p);
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.addName().setFamily("AAA");
|
||||||
|
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.POST)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfNoneExist("Patient?active=true");
|
||||||
|
|
||||||
|
Bundle resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertEquals("Patient/P1/_history/1", new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue());
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.addName().setFamily("AAA");
|
||||||
|
|
||||||
|
b = new Bundle();
|
||||||
|
b.setType(BundleType.TRANSACTION);
|
||||||
|
b.addEntry()
|
||||||
|
.setFullUrl("Patient")
|
||||||
|
.setResource(p)
|
||||||
|
.getRequest()
|
||||||
|
.setMethod(HTTPVerb.POST)
|
||||||
|
.setUrl("Patient/P1")
|
||||||
|
.setIfNoneExist("Patient?active=false");
|
||||||
|
|
||||||
|
resp = mySystemDao.transaction(mySrd, b);
|
||||||
|
assertThat( new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualified().getValue(), matchesPattern("Patient/[0-9]+/_history/1"));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransaction1() throws IOException {
|
public void testTransaction1() throws IOException {
|
||||||
String inputBundleString = loadClasspath("/david-bundle-error.json");
|
String inputBundleString = loadClasspath("/david-bundle-error.json");
|
||||||
|
|
|
@ -116,6 +116,20 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateWrongResourceType() throws IOException {
|
||||||
|
String input = IOUtils.toString(getClass().getResourceAsStream("/dstu3-person.json"), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
try {
|
||||||
|
MethodOutcome resp = ourClient.update().resource(input).withId("Patient/PERSON1").execute();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertEquals("", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodOutcome resp = ourClient.update().resource(input).withId("Person/PERSON1").execute();
|
||||||
|
assertEquals("Person/PERSON1/_history/1", resp.getId().toUnqualified().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See #484
|
* See #484
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Person",
|
||||||
|
"id": "PERSON1",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "1",
|
||||||
|
"lastUpdated": "2017-08-17T16:19:40.109+03:00"
|
||||||
|
},
|
||||||
|
"identifier": [
|
||||||
|
{
|
||||||
|
"value": "081181-9984"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": [
|
||||||
|
{
|
||||||
|
"text": "Anna Testi",
|
||||||
|
"family": "Testi",
|
||||||
|
"given": [
|
||||||
|
"Anna"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "asdfas"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"telecom": [
|
||||||
|
{
|
||||||
|
"use": "home"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": "phone",
|
||||||
|
"value": "(044) 1234567",
|
||||||
|
"use": "work"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gender": "female",
|
||||||
|
"birthDate": "1981-11-08",
|
||||||
|
"address": [
|
||||||
|
{
|
||||||
|
"line": [
|
||||||
|
"Osuuspankkitie 2"
|
||||||
|
],
|
||||||
|
"city": "Helsinki",
|
||||||
|
"postalCode": "00120",
|
||||||
|
"country": "Suomi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"city": "Blo-49847020"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,11 @@
|
||||||
Fix a NullPointerException when validating a Bundle (in DSTU3/R4) with no
|
Fix a NullPointerException when validating a Bundle (in DSTU3/R4) with no
|
||||||
<![CDATA[<code>Bundle.type</code>]]> value
|
<![CDATA[<code>Bundle.type</code>]]> value
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
The JPA server transaction operation (DSTU3/R4) did not correctly process the
|
||||||
|
If-Match header when passed in via
|
||||||
|
<![CDATA[<code>Bundle.entry.request.ifMatch</code>]]> value
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.0.0" date="2017-09-27">
|
<release version="3.0.0" date="2017-09-27">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue