Support ifNoneMatch in transaction request

This commit is contained in:
James Agnew 2015-06-19 16:08:35 -04:00
parent 84571f993c
commit 886fa76ef2
3 changed files with 75 additions and 2 deletions

View File

@ -32,6 +32,7 @@ import java.util.Set;
import javax.persistence.TypedQuery;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.jmx.access.InvalidInvocationException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -51,6 +52,7 @@ import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.method.MethodUtil;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -254,16 +256,37 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
@SuppressWarnings("rawtypes")
IFhirResourceDao resourceDao = parts.getDao();
String ifNoneMatch = nextEntry.getTransaction().getIfNoneMatch();
if (isNotBlank(ifNoneMatch)) {
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
}
if (parts.getResourceId() != null && parts.getParams() == null) {
IResource found;
boolean notChanged = false;
if (parts.getVersionId() != null) {
if (isNotBlank(ifNoneMatch)) {
throw new InvalidRequestException("Unable to perform vread on '" + url + "' with ifNoneMatch also set. Do not include a version in the URL to perform a conditional read.");
}
found = resourceDao.read(new IdDt(parts.getResourceType(), parts.getResourceId(), parts.getVersionId()));
} else {
found = resourceDao.read(new IdDt(parts.getResourceType(), parts.getResourceId()));
if (isNotBlank(ifNoneMatch) && ifNoneMatch.equals(found.getId().getVersionIdPart())) {
notChanged = true;
}
}
EntryTransactionResponse resp = response.addEntry().setResource(found).getTransactionResponse();
Entry entry = response.addEntry();
if (notChanged == false) {
entry.setResource(found);
}
EntryTransactionResponse resp = entry.getTransactionResponse();
resp.setLocation(found.getId().toUnqualified().getValue());
resp.setEtag(found.getId().getVersionIdPart());
if (!notChanged) {
resp.setStatus(Integer.toString(Constants.STATUS_HTTP_200_OK));
} else {
resp.setStatus(Integer.toString(Constants.STATUS_HTTP_304_NOT_MODIFIED));
}
} else if (parts.getParams() != null) {
RuntimeResourceDefinition def = getContext().getResourceDefinition(parts.getDao().getResourceType());
SearchParameterMap params = translateMatchUrl(url, def);
@ -282,7 +305,9 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
searchBundle.addEntry().setResource((IResource) next);
}
response.addEntry().setResource(searchBundle);
Entry newEntry = response.addEntry();
newEntry.setResource(searchBundle);
newEntry.getTransactionResponse().setStatus(Integer.toString(Constants.STATUS_HTTP_200_OK));
}
}
}

View File

@ -558,6 +558,51 @@ public class FhirSystemDaoDstu2Test {
assertEquals(1, respBundle.getTotal().intValue());
}
@Test
public void testTransactionReadWithIfNoneMatch() {
String methodName = "testTransactionReadWithIfNoneMatch";
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt idv1 = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got id: {}", idv1);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("Family Name");
p.setId("Patient/" + methodName);
IdDt idv2 = ourPatientDao.update(p).getId();
ourLog.info("Updated patient, got id: {}", idv2);
Bundle request = new Bundle();
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue());
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv1.getVersionIdPart() + "\"");
request.addEntry().getTransaction().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv2.getVersionIdPart() + "\"");
Bundle resp = ourSystemDao.transaction(request);
assertEquals(4, resp.getEntry().size());
Entry nextEntry;
nextEntry = resp.getEntry().get(1);
assertNotNull(nextEntry.getResource());
assertEquals(Patient.class, nextEntry.getResource().getClass());
assertEquals(idv2.toUnqualified(), nextEntry.getResource().getId().toUnqualified());
assertEquals("200", nextEntry.getTransactionResponse().getStatus());
nextEntry = resp.getEntry().get(2);
assertNotNull(nextEntry.getResource());
assertEquals(Patient.class, nextEntry.getResource().getClass());
assertEquals(idv2.toUnqualified(), nextEntry.getResource().getId().toUnqualified());
assertEquals("200", nextEntry.getTransactionResponse().getStatus());
nextEntry = resp.getEntry().get(3);
assertNull(nextEntry.getResource());
assertEquals("304", nextEntry.getTransactionResponse().getStatus());
}
@Test
public void testTransactionUpdateMatchUrlWithOneMatch() {
String methodName = "testTransactionUpdateMatchUrlWithOneMatch";

View File

@ -108,6 +108,9 @@
<action type="add">
Questionnaire.title now gets correctly indexed in JPA server (it has no path, so it is a special case)
</action>
<action type="add">
JPA server now supports ifNoneMatch in GET within a transaction request.
</action>
</release>
<release version="1.0" date="2015-May-8">
<action type="add">