Update syntax highlighter to not use tables

This commit is contained in:
James Agnew 2017-08-28 10:26:07 -04:00
parent ff8b5607f3
commit cae21f4898
8 changed files with 737 additions and 610 deletions

View File

@ -193,8 +193,14 @@ public class Include implements Serializable {
return myRecurse; return myRecurse;
} }
public void setRecurse(boolean theRecurse) { /**
* Should this include recurse
*
* @return Returns a reference to <code>this</code> for easy method chaining
*/
public Include setRecurse(boolean theRecurse) {
myRecurse = theRecurse; myRecurse = theRecurse;
return this;
} }
public void setValue(String theValue) { public void setValue(String theValue) {

View File

@ -439,7 +439,12 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
outcome = resourceDao.update(res, null, false, theRequestDetails); outcome = resourceDao.update(res, null, false, theRequestDetails);
} else { } else {
res.setId((String) null); res.setId((String) null);
String matchUrl = parts.getResourceType() + '?' + parts.getParams(); String matchUrl;
if (isNotBlank(parts.getParams())) {
matchUrl = parts.getResourceType() + '?' + parts.getParams();
} else {
matchUrl = parts.getResourceType();
}
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl); matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
outcome = resourceDao.update(res, matchUrl, false, theRequestDetails); outcome = resourceDao.update(res, matchUrl, false, theRequestDetails);
if (Boolean.TRUE.equals(outcome.getCreated())) { if (Boolean.TRUE.equals(outcome.getCreated())) {

View File

@ -439,7 +439,12 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
outcome = resourceDao.update(res, null, false, theRequestDetails); outcome = resourceDao.update(res, null, false, theRequestDetails);
} else { } else {
res.setId((String) null); res.setId((String) null);
String matchUrl = parts.getResourceType() + '?' + parts.getParams(); String matchUrl;
if (isNotBlank(parts.getParams())) {
matchUrl = parts.getResourceType() + '?' + parts.getParams();
} else {
matchUrl = parts.getResourceType();
}
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl); matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
outcome = resourceDao.update(res, matchUrl, false, theRequestDetails); outcome = resourceDao.update(res, matchUrl, false, theRequestDetails);
if (Boolean.TRUE.equals(outcome.getCreated())) { if (Boolean.TRUE.equals(outcome.getCreated())) {

View File

@ -1,38 +1,12 @@
package ca.uhn.fhir.jpa.dao.dstu3; package ca.uhn.fhir.jpa.dao.dstu3;
import static org.hamcrest.Matchers.*; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import static org.junit.Assert.*; import ca.uhn.fhir.jpa.dao.DaoConfig;
import static org.mockito.Matchers.eq; import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import static org.mockito.Mockito.times; import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
import static org.mockito.Mockito.verify; import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.ResourceTag;
import java.io.*; import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryRequestComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryResponseComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.*;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -43,6 +17,35 @@ import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.*;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
@ -63,36 +66,36 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Patient pat = new Patient(); Patient pat = new Patient();
pat pat
.addIdentifier() .addIdentifier()
.setSystem("http://acme.org") .setSystem("http://acme.org")
.setValue("ID1"); .setValue("ID1");
Observation obs = new Observation(); Observation obs = new Observation();
obs obs
.getCode() .getCode()
.addCoding() .addCoding()
.setSystem("http://loinc.org") .setSystem("http://loinc.org")
.setCode("29463-7"); .setCode("29463-7");
obs.setEffective(new DateTimeType("2011-09-03T11:13:00-04:00")); obs.setEffective(new DateTimeType("2011-09-03T11:13:00-04:00"));
obs.setValue(new Quantity() obs.setValue(new Quantity()
.setValue(new BigDecimal("123.4")) .setValue(new BigDecimal("123.4"))
.setCode("kg") .setCode("kg")
.setSystem("http://unitsofmeasure.org") .setSystem("http://unitsofmeasure.org")
.setUnit("kg")); .setUnit("kg"));
obs.getSubject().setReference("urn:uuid:0001"); obs.getSubject().setReference("urn:uuid:0001");
Observation obs2 = new Observation(); Observation obs2 = new Observation();
obs2 obs2
.getCode() .getCode()
.addCoding() .addCoding()
.setSystem("http://loinc.org") .setSystem("http://loinc.org")
.setCode("29463-7"); .setCode("29463-7");
obs2.setEffective(new DateTimeType("2017-09-03T11:13:00-04:00")); obs2.setEffective(new DateTimeType("2017-09-03T11:13:00-04:00"));
obs2.setValue(new Quantity() obs2.setValue(new Quantity()
.setValue(new BigDecimal("123.4")) .setValue(new BigDecimal("123.4"))
.setCode("kg") .setCode("kg")
.setSystem("http://unitsofmeasure.org") .setSystem("http://unitsofmeasure.org")
.setUnit("kg")); .setUnit("kg"));
obs2.getSubject().setReference("urn:uuid:0001"); obs2.getSubject().setReference("urn:uuid:0001");
/* /*
@ -104,51 +107,51 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
if (theVerb == HTTPVerb.PUT) { if (theVerb == HTTPVerb.PUT) {
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0002") .setFullUrl("urn:uuid:0002")
.setResource(obs) .setResource(obs)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00"); .setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0001") .setFullUrl("urn:uuid:0001")
.setResource(pat) .setResource(pat)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient?identifier=http%3A%2F%2Facme.org|ID1"); .setUrl("Patient?identifier=http%3A%2F%2Facme.org|ID1");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0003") .setFullUrl("urn:uuid:0003")
.setResource(obs2) .setResource(obs2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00"); .setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00");
} else if (theVerb == HTTPVerb.POST) { } else if (theVerb == HTTPVerb.POST) {
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0002") .setFullUrl("urn:uuid:0002")
.setResource(obs) .setResource(obs)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Observation") .setUrl("Observation")
.setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00"); .setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0001") .setFullUrl("urn:uuid:0001")
.setResource(pat) .setResource(pat)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Patient") .setUrl("Patient")
.setIfNoneExist("Patient?identifier=http%3A%2F%2Facme.org|ID1"); .setIfNoneExist("Patient?identifier=http%3A%2F%2Facme.org|ID1");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0003") .setFullUrl("urn:uuid:0003")
.setResource(obs2) .setResource(obs2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Observation") .setUrl("Observation")
.setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00"); .setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00");
} }
return input; return input;
} }
@ -192,7 +195,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus());
@ -226,7 +229,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus());
@ -255,20 +258,20 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Bundle inputBundle = new Bundle(); Bundle inputBundle = new Bundle();
inputBundle.setType(Bundle.BundleType.TRANSACTION); inputBundle.setType(Bundle.BundleType.TRANSACTION);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(ep) .setResource(ep)
.setFullUrl(ep.getId()) .setFullUrl(ep.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(cond) .setResource(cond)
.setFullUrl(cond.getId()) .setFullUrl(cond.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc) .setResource(enc)
.setFullUrl(enc.getId()) .setFullUrl(enc.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
Bundle resp = mySystemDao.transaction(mySrd, inputBundle); Bundle resp = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp)); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
@ -291,17 +294,17 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
inputBundle = new Bundle(); inputBundle = new Bundle();
inputBundle.setType(Bundle.BundleType.TRANSACTION); inputBundle.setType(Bundle.BundleType.TRANSACTION);
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(epId.toUnqualifiedVersionless().getValue()); .setUrl(epId.toUnqualifiedVersionless().getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(encId.toUnqualifiedVersionless().getValue()); .setUrl(encId.toUnqualifiedVersionless().getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(condId.toUnqualifiedVersionless().getValue()); .setUrl(condId.toUnqualifiedVersionless().getValue());
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(inputBundle)); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(inputBundle));
resp = mySystemDao.transaction(mySrd, inputBundle); resp = mySystemDao.transaction(mySrd, inputBundle);
@ -381,12 +384,12 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
Bundle resp = mySystemDao.transaction(mySrd, bundle); Bundle resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -396,12 +399,12 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
resp = mySystemDao.transaction(mySrd, bundle); resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -411,12 +414,12 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
resp = mySystemDao.transaction(mySrd, bundle); resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -960,7 +963,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus());
@ -994,7 +997,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus());
@ -1004,7 +1007,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter")); assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter"));
} }
@Test @Test
public void testTransactionCreateWithDuplicateMatchUrl01() { public void testTransactionCreateWithDuplicateMatchUrl01() {
String methodName = "testTransactionCreateWithDuplicateMatchUrl01"; String methodName = "testTransactionCreateWithDuplicateMatchUrl01";
@ -1024,7 +1027,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals(e.getMessage(), assertEquals(e.getMessage(),
"Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl01\". Does transaction request contain duplicates?"); "Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl01\". Does transaction request contain duplicates?");
} }
} }
@ -1047,10 +1050,10 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals(e.getMessage(), assertEquals(e.getMessage(),
"Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl02\". Does transaction request contain duplicates?"); "Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl02\". Does transaction request contain duplicates?");
} }
} }
@Test @Test
public void testTransactionCreateWithInvalidMatchUrl() { public void testTransactionCreateWithInvalidMatchUrl() {
String methodName = "testTransactionCreateWithInvalidMatchUrl"; String methodName = "testTransactionCreateWithInvalidMatchUrl";
@ -1085,7 +1088,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage()); assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage());
} }
} }
@Test @Test
public void testTransactionCreateWithInvalidReferenceNumeric() { public void testTransactionCreateWithInvalidReferenceNumeric() {
@ -1125,6 +1127,27 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
} }
} }
@Test
public void testTransactionCreateWithLinks() throws IOException {
Bundle request = new Bundle();
request.setType(BundleType.TRANSACTION);
Observation o = new Observation();
o.setId("A");
o.setStatus(ObservationStatus.AMENDED);
request.addEntry()
.setResource(o)
.getRequest().setUrl("A").setMethod(HTTPVerb.PUT);
try {
mySystemDao.transaction(mySrd, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid match URL[A] - URL has no search parameters", e.getMessage());
}
}
@Test @Test
public void testTransactionCreateWithPutUsingAbsoluteUrl() { public void testTransactionCreateWithPutUsingAbsoluteUrl() {
String methodName = "testTransactionCreateWithPutUsingAbsoluteUrl"; String methodName = "testTransactionCreateWithPutUsingAbsoluteUrl";
@ -1498,26 +1521,26 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Encounter enc1 = new Encounter(); Encounter enc1 = new Encounter();
enc1.addIdentifier().setSystem("urn:foo").setValue("12345"); enc1.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc1) .setResource(enc1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setIfNoneExist("Encounter?identifier=urn:foo|12345"); .setIfNoneExist("Encounter?identifier=urn:foo|12345");
Encounter enc2 = new Encounter(); Encounter enc2 = new Encounter();
enc2.addIdentifier().setSystem("urn:foo").setValue("12345"); enc2.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc2) .setResource(enc2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setIfNoneExist("Encounter?identifier=urn:foo|12345"); .setIfNoneExist("Encounter?identifier=urn:foo|12345");
try { try {
mySystemDao.transaction(mySrd, inputBundle); mySystemDao.transaction(mySrd, inputBundle);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?", assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?",
e.getMessage()); e.getMessage());
} }
} }
@ -1529,26 +1552,26 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
Encounter enc1 = new Encounter(); Encounter enc1 = new Encounter();
enc1.addIdentifier().setSystem("urn:foo").setValue("12345"); enc1.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc1) .setResource(enc1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=urn:foo|12345"); .setUrl("Encounter?identifier=urn:foo|12345");
Encounter enc2 = new Encounter(); Encounter enc2 = new Encounter();
enc2.addIdentifier().setSystem("urn:foo").setValue("12345"); enc2.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc2) .setResource(enc2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=urn:foo|12345"); .setUrl("Encounter?identifier=urn:foo|12345");
try { try {
mySystemDao.transaction(mySrd, inputBundle); mySystemDao.transaction(mySrd, inputBundle);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?", assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?",
e.getMessage()); e.getMessage());
} }
} }
@ -1653,17 +1676,17 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
* that they are invoked correctly. * that they are invoked correctly.
*/ */
//@formatter:off //@formatter:off
int pass = 0; int pass = 0;
IdType patientPlaceholderId = IdType.newRandomUuid(); IdType patientPlaceholderId = IdType.newRandomUuid();
Bundle req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId); Bundle req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
Bundle resp = mySystemDao.transaction(mySrd, req); Bundle resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp); testTransactionOrderingValidateResponse(pass, resp);
pass = 1; pass = 1;
patientPlaceholderId = IdType.newRandomUuid(); patientPlaceholderId = IdType.newRandomUuid();
req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId); req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
resp = mySystemDao.transaction(mySrd, req); resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp); testTransactionOrderingValidateResponse(pass, resp);
@ -1673,18 +1696,18 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdType patientPlaceholderId) { private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdType patientPlaceholderId) {
Bundle req = new Bundle(); Bundle req = new Bundle();
req.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?identifier=" + methodName); req.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?identifier=" + methodName);
Observation obs = new Observation(); Observation obs = new Observation();
obs.getSubject().setReferenceElement(patientPlaceholderId); obs.getSubject().setReferenceElement(patientPlaceholderId);
obs.addIdentifier().setValue(methodName); obs.addIdentifier().setValue(methodName);
obs.getCode().setText(methodName + pass); obs.getCode().setText(methodName + pass);
req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerb.PUT).setUrl("Observation?identifier=" + methodName); req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerb.PUT).setUrl("Observation?identifier=" + methodName);
Patient pat = new Patient(); Patient pat = new Patient();
pat.addIdentifier().setValue(methodName); pat.addIdentifier().setValue(methodName);
pat.addName().setFamily(methodName + pass); pat.addName().setFamily(methodName + pass);
req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient"); req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient");
req.addEntry().getRequest().setMethod(HTTPVerb.DELETE).setUrl("Patient?identifier=" + methodName); req.addEntry().getRequest().setMethod(HTTPVerb.DELETE).setUrl("Patient?identifier=" + methodName);
return req; return req;
} }
@ -1709,11 +1732,11 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
} else { } else {
assertEquals("204 No Content", resp.getEntry().get(3).getResponse().getStatus()); assertEquals("204 No Content", resp.getEntry().get(3).getResponse().getStatus());
} }
Bundle respGetBundle = (Bundle) resp.getEntry().get(0).getResource(); Bundle respGetBundle = (Bundle) resp.getEntry().get(0).getResource();
assertEquals(1, respGetBundle.getEntry().size()); assertEquals(1, respGetBundle.getEntry().size());
assertEquals("testTransactionOrdering" + pass, ((Patient)respGetBundle.getEntry().get(0).getResource()).getName().get(0).getFamily()); assertEquals("testTransactionOrdering" + pass, ((Patient) respGetBundle.getEntry().get(0).getResource()).getName().get(0).getFamily());
assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering")); assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering"));
} }
@ -1804,7 +1827,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
details = detailsCapt.getValue(); details = detailsCapt.getValue();
assertEquals("Patient", details.getResourceType()); assertEquals("Patient", details.getResourceType());
} }
@Test @Test
@ -2069,6 +2092,24 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
} }
@Test
public void testTransactionWIthInvalidPlaceholder() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
try {
mySystemDao.transaction(mySrd, res);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid placeholder ID found: cid:observation1 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", e.getMessage());
}
}
/** /**
* Format changed, source isn't valid * Format changed, source isn't valid
*/ */
@ -2087,9 +2128,9 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp); encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp);
//@formatter:off //@formatter:off
assertThat(encoded, containsString("\"response\":{" + assertThat(encoded, containsString("\"response\":{" +
"\"status\":\"201 Created\"," + "\"status\":\"201 Created\"," +
"\"location\":\"Questionnaire/54127-6/_history/1\",")); "\"location\":\"Questionnaire/54127-6/_history/1\","));
//@formatter:on //@formatter:on
/* /*
@ -2103,9 +2144,9 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp); encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp);
//@formatter:off //@formatter:off
assertThat(encoded, containsString("\"response\":{" + assertThat(encoded, containsString("\"response\":{" +
"\"status\":\"200 OK\"," + "\"status\":\"200 OK\"," +
"\"location\":\"Questionnaire/54127-6/_history/2\",")); "\"location\":\"Questionnaire/54127-6/_history/2\","));
//@formatter:on //@formatter:on
} }
@ -2166,24 +2207,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
} }
@Test
public void testTransactionWIthInvalidPlaceholder() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
try {
mySystemDao.transaction(mySrd, res);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid placeholder ID found: cid:observation1 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", e.getMessage());
}
}
@Test @Test
public void testTransactionWithInvalidType() { public void testTransactionWithInvalidType() {
Bundle request = new Bundle(); Bundle request = new Bundle();
@ -2239,11 +2262,11 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
String placeholderId0 = IdDt.newRandomUuid().getValue(); String placeholderId0 = IdDt.newRandomUuid().getValue();
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app0) .setResource(app0)
.setFullUrl(placeholderId0) .setFullUrl(placeholderId0)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Patient"); .setUrl("Patient");
//@formatter:on //@formatter:on
//@formatter:off //@formatter:off
@ -2251,10 +2274,10 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
app1.addParticipant().getActor().setReference(id.getValue()); app1.addParticipant().getActor().setReference(id.getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app1) .setResource(app1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Appointment"); .setUrl("Appointment");
//@formatter:on //@formatter:on
//@formatter:off //@formatter:off
@ -2263,10 +2286,10 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0); app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app2) .setResource(app2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Appointment"); .setUrl("Appointment");
//@formatter:on //@formatter:on
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle); Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
@ -2409,57 +2432,57 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
@Test @Test
public void testTransactionWithReferenceToCreateIfNoneExist() { public void testTransactionWithReferenceToCreateIfNoneExist() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
Medication med = new Medication(); Medication med = new Medication();
IdType medId = IdType.newRandomUuid(); IdType medId = IdType.newRandomUuid();
med.setId(medId); med.setId(medId);
med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode");
MedicationRequest mo = new MedicationRequest(); MedicationRequest mo = new MedicationRequest();
mo.setMedication(new Reference(medId)); mo.setMedication(new Reference(medId));
bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST);
ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
Bundle outcome = mySystemDao.transaction(mySrd, bundle); Bundle outcome = mySystemDao.transaction(mySrd, bundle);
ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation());
/* /*
* Again! * Again!
*/ */
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
med = new Medication(); med = new Medication();
medId = IdType.newRandomUuid(); medId = IdType.newRandomUuid();
med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode");
mo = new MedicationRequest(); mo = new MedicationRequest();
mo.setMedication(new Reference(medId)); mo.setMedication(new Reference(medId));
bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST);
outcome = mySystemDao.transaction(mySrd, bundle); outcome = mySystemDao.transaction(mySrd, bundle);
IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation());
assertTrue(medId1.isIdPartValidLong()); assertTrue(medId1.isIdPartValidLong());
assertTrue(medId2.isIdPartValidLong()); assertTrue(medId2.isIdPartValidLong());
assertTrue(medOrderId1.isIdPartValidLong()); assertTrue(medOrderId1.isIdPartValidLong());
assertTrue(medOrderId2.isIdPartValidLong()); assertTrue(medOrderId2.isIdPartValidLong());
assertEquals(medId1, medId2); assertEquals(medId1, medId2);
assertNotEquals(medOrderId1, medOrderId2); assertNotEquals(medOrderId1, medOrderId2);
} }
// //
// //
@ -2564,7 +2587,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
// } // }
@Test @Test
public void testTransactionWithReferenceUuid() { public void testTransactionWithReferenceUuid() {
Bundle request = new Bundle(); Bundle request = new Bundle();

View File

@ -69,7 +69,55 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
assertThat(ids, contains(moId.getValue())); assertThat(ids, contains(moId.getValue()));
} }
@Test
public void testIncludeLinkedObservations() {
DiagnosticReport dr = new DiagnosticReport();
dr.setId("DiagnosticReport/DR");
dr.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL);
Observation parentObs = new Observation();
parentObs.setStatus(ObservationStatus.FINAL);
parentObs.setId("Observation/parentObs");
Observation childObs = new Observation();
childObs.setId("Observation/childObs");
childObs.setStatus(ObservationStatus.FINAL);
dr.addResult().setReference("Observation/parentObs").setResource(parentObs);
parentObs.addRelated()
.setType(Observation.ObservationRelationshipType.HASMEMBER)
.setTarget(new Reference(childObs).setReference("Observation/childObs"));
childObs.addRelated()
.setType(Observation.ObservationRelationshipType.QUALIFIEDBY)
.setTarget(new Reference(parentObs).setReference("Observation/parentObs"));
Bundle input = new Bundle();
input.setType(BundleType.TRANSACTION);
input.addEntry()
.setResource(dr)
.getRequest().setMethod(HTTPVerb.PUT).setUrl(dr.getId());
input.addEntry()
.setResource(parentObs)
.getRequest().setMethod(HTTPVerb.PUT).setUrl(parentObs.getId());
input.addEntry()
.setResource(childObs)
.getRequest().setMethod(HTTPVerb.PUT).setUrl(childObs.getId());
mySystemDao.transaction(mySrd, input);
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new TokenParam(null, "DR"));
params.addInclude(new Include("DiagnosticReport:subject").setRecurse(true));
params.addInclude(new Include("DiagnosticReport:result").setRecurse(true));
params.addInclude(new Include("Observation:related-target").setRecurse(true));
IBundleProvider result = myDiagnosticReportDao.search(params);
List<String> resultIds = toUnqualifiedVersionlessIdValues(result);
assertThat(resultIds, containsInAnyOrder("DiagnosticReport/DR", "Observation/parentObs", "Observation/childObs"));
}
@Test @Test
public void testEmptyChain() { public void testEmptyChain() {

View File

@ -1,38 +1,12 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao.r4;
import static org.hamcrest.Matchers.*; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import static org.junit.Assert.*; import ca.uhn.fhir.jpa.dao.DaoConfig;
import static org.mockito.Matchers.eq; import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import static org.mockito.Mockito.times; import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
import static org.mockito.Mockito.verify; import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.ResourceTag;
import java.io.*; import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Bundle.BundleEntryRequestComponent;
import org.hl7.fhir.r4.model.Bundle.BundleEntryResponseComponent;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.*;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -43,6 +17,35 @@ import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.*;
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest { public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
@ -63,36 +66,36 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Patient pat = new Patient(); Patient pat = new Patient();
pat pat
.addIdentifier() .addIdentifier()
.setSystem("http://acme.org") .setSystem("http://acme.org")
.setValue("ID1"); .setValue("ID1");
Observation obs = new Observation(); Observation obs = new Observation();
obs obs
.getCode() .getCode()
.addCoding() .addCoding()
.setSystem("http://loinc.org") .setSystem("http://loinc.org")
.setCode("29463-7"); .setCode("29463-7");
obs.setEffective(new DateTimeType("2011-09-03T11:13:00-04:00")); obs.setEffective(new DateTimeType("2011-09-03T11:13:00-04:00"));
obs.setValue(new Quantity() obs.setValue(new Quantity()
.setValue(new BigDecimal("123.4")) .setValue(new BigDecimal("123.4"))
.setCode("kg") .setCode("kg")
.setSystem("http://unitsofmeasure.org") .setSystem("http://unitsofmeasure.org")
.setUnit("kg")); .setUnit("kg"));
obs.getSubject().setReference("urn:uuid:0001"); obs.getSubject().setReference("urn:uuid:0001");
Observation obs2 = new Observation(); Observation obs2 = new Observation();
obs2 obs2
.getCode() .getCode()
.addCoding() .addCoding()
.setSystem("http://loinc.org") .setSystem("http://loinc.org")
.setCode("29463-7"); .setCode("29463-7");
obs2.setEffective(new DateTimeType("2017-09-03T11:13:00-04:00")); obs2.setEffective(new DateTimeType("2017-09-03T11:13:00-04:00"));
obs2.setValue(new Quantity() obs2.setValue(new Quantity()
.setValue(new BigDecimal("123.4")) .setValue(new BigDecimal("123.4"))
.setCode("kg") .setCode("kg")
.setSystem("http://unitsofmeasure.org") .setSystem("http://unitsofmeasure.org")
.setUnit("kg")); .setUnit("kg"));
obs2.getSubject().setReference("urn:uuid:0001"); obs2.getSubject().setReference("urn:uuid:0001");
/* /*
@ -104,51 +107,51 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
if (theVerb == HTTPVerb.PUT) { if (theVerb == HTTPVerb.PUT) {
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0002") .setFullUrl("urn:uuid:0002")
.setResource(obs) .setResource(obs)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00"); .setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0001") .setFullUrl("urn:uuid:0001")
.setResource(pat) .setResource(pat)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient?identifier=http%3A%2F%2Facme.org|ID1"); .setUrl("Patient?identifier=http%3A%2F%2Facme.org|ID1");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0003") .setFullUrl("urn:uuid:0003")
.setResource(obs2) .setResource(obs2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00"); .setUrl("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00");
} else if (theVerb == HTTPVerb.POST) { } else if (theVerb == HTTPVerb.POST) {
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0002") .setFullUrl("urn:uuid:0002")
.setResource(obs) .setResource(obs)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Observation") .setUrl("Observation")
.setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00"); .setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2011-09-03T11:13:00-04:00");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0001") .setFullUrl("urn:uuid:0001")
.setResource(pat) .setResource(pat)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Patient") .setUrl("Patient")
.setIfNoneExist("Patient?identifier=http%3A%2F%2Facme.org|ID1"); .setIfNoneExist("Patient?identifier=http%3A%2F%2Facme.org|ID1");
input input
.addEntry() .addEntry()
.setFullUrl("urn:uuid:0003") .setFullUrl("urn:uuid:0003")
.setResource(obs2) .setResource(obs2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Observation") .setUrl("Observation")
.setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00"); .setIfNoneExist("Observation?subject=urn:uuid:0001&code=http%3A%2F%2Floinc.org|29463-7&date=2017-09-03T11:13:00-04:00");
} }
return input; return input;
} }
@ -192,7 +195,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus());
@ -226,7 +229,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus());
@ -255,20 +258,20 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Bundle inputBundle = new Bundle(); Bundle inputBundle = new Bundle();
inputBundle.setType(Bundle.BundleType.TRANSACTION); inputBundle.setType(Bundle.BundleType.TRANSACTION);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(ep) .setResource(ep)
.setFullUrl(ep.getId()) .setFullUrl(ep.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(cond) .setResource(cond)
.setFullUrl(cond.getId()) .setFullUrl(cond.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc) .setResource(enc)
.setFullUrl(enc.getId()) .setFullUrl(enc.getId())
.getRequest().setMethod(HTTPVerb.POST); .getRequest().setMethod(HTTPVerb.POST);
Bundle resp = mySystemDao.transaction(mySrd, inputBundle); Bundle resp = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp)); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
@ -291,17 +294,17 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
inputBundle = new Bundle(); inputBundle = new Bundle();
inputBundle.setType(Bundle.BundleType.TRANSACTION); inputBundle.setType(Bundle.BundleType.TRANSACTION);
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(epId.toUnqualifiedVersionless().getValue()); .setUrl(epId.toUnqualifiedVersionless().getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(encId.toUnqualifiedVersionless().getValue()); .setUrl(encId.toUnqualifiedVersionless().getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.getRequest().setMethod(HTTPVerb.DELETE) .getRequest().setMethod(HTTPVerb.DELETE)
.setUrl(condId.toUnqualifiedVersionless().getValue()); .setUrl(condId.toUnqualifiedVersionless().getValue());
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(inputBundle)); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(inputBundle));
resp = mySystemDao.transaction(mySrd, inputBundle); resp = mySystemDao.transaction(mySrd, inputBundle);
@ -381,12 +384,12 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
Bundle resp = mySystemDao.transaction(mySrd, bundle); Bundle resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -396,12 +399,12 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
resp = mySystemDao.transaction(mySrd, bundle); resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -411,12 +414,12 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
bundle bundle
.addEntry() .addEntry()
.setResource(p) .setResource(p)
.setFullUrl("Patient/A") .setFullUrl("Patient/A")
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Patient/A"); .setUrl("Patient/A");
resp = mySystemDao.transaction(mySrd, bundle); resp = mySystemDao.transaction(mySrd, bundle);
assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1")); assertThat(resp.getEntry().get(0).getResponse().getLocation(), endsWith("Patient/A/_history/1"));
@ -960,7 +963,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus());
@ -994,7 +997,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Bundle response = mySystemDao.transaction(mySrd, request); Bundle response = mySystemDao.transaction(mySrd, request);
assertEquals(2, response.getEntry().size()); assertEquals(2, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*"));
assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus());
@ -1004,7 +1007,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity());
assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter")); assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter"));
} }
@Test @Test
public void testTransactionCreateWithDuplicateMatchUrl01() { public void testTransactionCreateWithDuplicateMatchUrl01() {
String methodName = "testTransactionCreateWithDuplicateMatchUrl01"; String methodName = "testTransactionCreateWithDuplicateMatchUrl01";
@ -1024,7 +1027,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals(e.getMessage(), assertEquals(e.getMessage(),
"Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl01\". Does transaction request contain duplicates?"); "Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl01\". Does transaction request contain duplicates?");
} }
} }
@ -1047,10 +1050,10 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals(e.getMessage(), assertEquals(e.getMessage(),
"Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl02\". Does transaction request contain duplicates?"); "Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl02\". Does transaction request contain duplicates?");
} }
} }
@Test @Test
public void testTransactionCreateWithInvalidMatchUrl() { public void testTransactionCreateWithInvalidMatchUrl() {
String methodName = "testTransactionCreateWithInvalidMatchUrl"; String methodName = "testTransactionCreateWithInvalidMatchUrl";
@ -1085,7 +1088,6 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage()); assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage());
} }
} }
@Test @Test
public void testTransactionCreateWithInvalidReferenceNumeric() { public void testTransactionCreateWithInvalidReferenceNumeric() {
@ -1125,6 +1127,27 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
} }
} }
@Test
public void testTransactionCreateWithLinks() throws IOException {
Bundle request = new Bundle();
request.setType(BundleType.TRANSACTION);
Observation o = new Observation();
o.setId("A");
o.setStatus(ObservationStatus.AMENDED);
request.addEntry()
.setResource(o)
.getRequest().setUrl("A").setMethod(HTTPVerb.PUT);
try {
mySystemDao.transaction(mySrd, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid match URL[A] - URL has no search parameters", e.getMessage());
}
}
@Test @Test
public void testTransactionCreateWithPutUsingAbsoluteUrl() { public void testTransactionCreateWithPutUsingAbsoluteUrl() {
String methodName = "testTransactionCreateWithPutUsingAbsoluteUrl"; String methodName = "testTransactionCreateWithPutUsingAbsoluteUrl";
@ -1162,7 +1185,8 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
@Test @Test
public void testTransactionCreateWithPutUsingUrl2() throws Exception { public void testTransactionCreateWithPutUsingUrl2() throws Exception {
String req = IOUtils.toString(FhirSystemDaoR4Test.class.getResourceAsStream("/r4/bundle.xml"), StandardCharsets.UTF_8); Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, req); String req = IOUtils.toString(FhirSystemDaoR4Test.class.getResourceAsStream("/r4/bundle.xml"), StandardCharsets.UTF_8);
Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, req);
mySystemDao.transaction(mySrd, request); mySystemDao.transaction(mySrd, request);
} }
@ -1497,26 +1521,26 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Encounter enc1 = new Encounter(); Encounter enc1 = new Encounter();
enc1.addIdentifier().setSystem("urn:foo").setValue("12345"); enc1.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc1) .setResource(enc1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setIfNoneExist("Encounter?identifier=urn:foo|12345"); .setIfNoneExist("Encounter?identifier=urn:foo|12345");
Encounter enc2 = new Encounter(); Encounter enc2 = new Encounter();
enc2.addIdentifier().setSystem("urn:foo").setValue("12345"); enc2.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc2) .setResource(enc2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setIfNoneExist("Encounter?identifier=urn:foo|12345"); .setIfNoneExist("Encounter?identifier=urn:foo|12345");
try { try {
mySystemDao.transaction(mySrd, inputBundle); mySystemDao.transaction(mySrd, inputBundle);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?", assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?",
e.getMessage()); e.getMessage());
} }
} }
@ -1528,26 +1552,26 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
Encounter enc1 = new Encounter(); Encounter enc1 = new Encounter();
enc1.addIdentifier().setSystem("urn:foo").setValue("12345"); enc1.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc1) .setResource(enc1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=urn:foo|12345"); .setUrl("Encounter?identifier=urn:foo|12345");
Encounter enc2 = new Encounter(); Encounter enc2 = new Encounter();
enc2.addIdentifier().setSystem("urn:foo").setValue("12345"); enc2.addIdentifier().setSystem("urn:foo").setValue("12345");
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(enc2) .setResource(enc2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.PUT) .setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=urn:foo|12345"); .setUrl("Encounter?identifier=urn:foo|12345");
try { try {
mySystemDao.transaction(mySrd, inputBundle); mySystemDao.transaction(mySrd, inputBundle);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?", assertEquals("Unable to process Transaction - Request would cause multiple resources to match URL: \"Encounter?identifier=urn:foo|12345\". Does transaction request contain duplicates?",
e.getMessage()); e.getMessage());
} }
} }
@ -1652,17 +1676,17 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
* that they are invoked correctly. * that they are invoked correctly.
*/ */
//@formatter:off //@formatter:off
int pass = 0; int pass = 0;
IdType patientPlaceholderId = IdType.newRandomUuid(); IdType patientPlaceholderId = IdType.newRandomUuid();
Bundle req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId); Bundle req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
Bundle resp = mySystemDao.transaction(mySrd, req); Bundle resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp); testTransactionOrderingValidateResponse(pass, resp);
pass = 1; pass = 1;
patientPlaceholderId = IdType.newRandomUuid(); patientPlaceholderId = IdType.newRandomUuid();
req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId); req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
resp = mySystemDao.transaction(mySrd, req); resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp); testTransactionOrderingValidateResponse(pass, resp);
@ -1672,18 +1696,18 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdType patientPlaceholderId) { private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdType patientPlaceholderId) {
Bundle req = new Bundle(); Bundle req = new Bundle();
req.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?identifier=" + methodName); req.addEntry().getRequest().setMethod(HTTPVerb.GET).setUrl("Patient?identifier=" + methodName);
Observation obs = new Observation(); Observation obs = new Observation();
obs.getSubject().setReferenceElement(patientPlaceholderId); obs.getSubject().setReferenceElement(patientPlaceholderId);
obs.addIdentifier().setValue(methodName); obs.addIdentifier().setValue(methodName);
obs.getCode().setText(methodName + pass); obs.getCode().setText(methodName + pass);
req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerb.PUT).setUrl("Observation?identifier=" + methodName); req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerb.PUT).setUrl("Observation?identifier=" + methodName);
Patient pat = new Patient(); Patient pat = new Patient();
pat.addIdentifier().setValue(methodName); pat.addIdentifier().setValue(methodName);
pat.addName().setFamily(methodName + pass); pat.addName().setFamily(methodName + pass);
req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient"); req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient");
req.addEntry().getRequest().setMethod(HTTPVerb.DELETE).setUrl("Patient?identifier=" + methodName); req.addEntry().getRequest().setMethod(HTTPVerb.DELETE).setUrl("Patient?identifier=" + methodName);
return req; return req;
} }
@ -1708,11 +1732,11 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
} else { } else {
assertEquals("204 No Content", resp.getEntry().get(3).getResponse().getStatus()); assertEquals("204 No Content", resp.getEntry().get(3).getResponse().getStatus());
} }
Bundle respGetBundle = (Bundle) resp.getEntry().get(0).getResource(); Bundle respGetBundle = (Bundle) resp.getEntry().get(0).getResource();
assertEquals(1, respGetBundle.getEntry().size()); assertEquals(1, respGetBundle.getEntry().size());
assertEquals("testTransactionOrdering" + pass, ((Patient)respGetBundle.getEntry().get(0).getResource()).getName().get(0).getFamily()); assertEquals("testTransactionOrdering" + pass, ((Patient) respGetBundle.getEntry().get(0).getResource()).getName().get(0).getFamily());
assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering")); assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering"));
} }
@ -1803,7 +1827,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
details = detailsCapt.getValue(); details = detailsCapt.getValue();
assertEquals("Patient", details.getResourceType()); assertEquals("Patient", details.getResourceType());
} }
@Test @Test
@ -2068,6 +2092,24 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
} }
@Test
public void testTransactionWIthInvalidPlaceholder() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
try {
mySystemDao.transaction(mySrd, res);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid placeholder ID found: cid:observation1 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", e.getMessage());
}
}
/** /**
* Format changed, source isn't valid * Format changed, source isn't valid
*/ */
@ -2086,9 +2128,9 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp); encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp);
//@formatter:off //@formatter:off
assertThat(encoded, containsString("\"response\":{" + assertThat(encoded, containsString("\"response\":{" +
"\"status\":\"201 Created\"," + "\"status\":\"201 Created\"," +
"\"location\":\"Questionnaire/54127-6/_history/1\",")); "\"location\":\"Questionnaire/54127-6/_history/1\","));
//@formatter:on //@formatter:on
/* /*
@ -2102,9 +2144,9 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp); encoded = myFhirCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(resp);
//@formatter:off //@formatter:off
assertThat(encoded, containsString("\"response\":{" + assertThat(encoded, containsString("\"response\":{" +
"\"status\":\"200 OK\"," + "\"status\":\"200 OK\"," +
"\"location\":\"Questionnaire/54127-6/_history/2\",")); "\"location\":\"Questionnaire/54127-6/_history/2\","));
//@formatter:on //@formatter:on
} }
@ -2165,24 +2207,6 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
} }
@Test
public void testTransactionWIthInvalidPlaceholder() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Observation o1 = new Observation();
o1.setId("cid:observation1");
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
try {
mySystemDao.transaction(mySrd, res);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid placeholder ID found: cid:observation1 - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", e.getMessage());
}
}
@Test @Test
public void testTransactionWithInvalidType() { public void testTransactionWithInvalidType() {
Bundle request = new Bundle(); Bundle request = new Bundle();
@ -2238,11 +2262,11 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
String placeholderId0 = IdDt.newRandomUuid().getValue(); String placeholderId0 = IdDt.newRandomUuid().getValue();
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app0) .setResource(app0)
.setFullUrl(placeholderId0) .setFullUrl(placeholderId0)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Patient"); .setUrl("Patient");
//@formatter:on //@formatter:on
//@formatter:off //@formatter:off
@ -2250,10 +2274,10 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
app1.addParticipant().getActor().setReference(id.getValue()); app1.addParticipant().getActor().setReference(id.getValue());
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app1) .setResource(app1)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Appointment"); .setUrl("Appointment");
//@formatter:on //@formatter:on
//@formatter:off //@formatter:off
@ -2262,10 +2286,10 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0); app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0);
inputBundle inputBundle
.addEntry() .addEntry()
.setResource(app2) .setResource(app2)
.getRequest() .getRequest()
.setMethod(HTTPVerb.POST) .setMethod(HTTPVerb.POST)
.setUrl("Appointment"); .setUrl("Appointment");
//@formatter:on //@formatter:on
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle); Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
@ -2408,57 +2432,57 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
@Test @Test
public void testTransactionWithReferenceToCreateIfNoneExist() { public void testTransactionWithReferenceToCreateIfNoneExist() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
Medication med = new Medication(); Medication med = new Medication();
IdType medId = IdType.newRandomUuid(); IdType medId = IdType.newRandomUuid();
med.setId(medId); med.setId(medId);
med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode");
MedicationRequest mo = new MedicationRequest(); MedicationRequest mo = new MedicationRequest();
mo.setMedication(new Reference(medId)); mo.setMedication(new Reference(medId));
bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST);
ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
Bundle outcome = mySystemDao.transaction(mySrd, bundle); Bundle outcome = mySystemDao.transaction(mySrd, bundle);
ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation());
/* /*
* Again! * Again!
*/ */
bundle = new Bundle(); bundle = new Bundle();
bundle.setType(BundleType.TRANSACTION); bundle.setType(BundleType.TRANSACTION);
med = new Medication(); med = new Medication();
medId = IdType.newRandomUuid(); medId = IdType.newRandomUuid();
med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode");
mo = new MedicationRequest(); mo = new MedicationRequest();
mo.setMedication(new Reference(medId)); mo.setMedication(new Reference(medId));
bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST);
outcome = mySystemDao.transaction(mySrd, bundle); outcome = mySystemDao.transaction(mySrd, bundle);
IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation());
assertTrue(medId1.isIdPartValidLong()); assertTrue(medId1.isIdPartValidLong());
assertTrue(medId2.isIdPartValidLong()); assertTrue(medId2.isIdPartValidLong());
assertTrue(medOrderId1.isIdPartValidLong()); assertTrue(medOrderId1.isIdPartValidLong());
assertTrue(medOrderId2.isIdPartValidLong()); assertTrue(medOrderId2.isIdPartValidLong());
assertEquals(medId1, medId2); assertEquals(medId1, medId2);
assertNotEquals(medOrderId1, medOrderId2); assertNotEquals(medOrderId1, medOrderId2);
} }
// //
// //
@ -2563,7 +2587,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
// } // }
@Test @Test
public void testTransactionWithReferenceUuid() { public void testTransactionWithReferenceUuid() {
Bundle request = new Bundle(); Bundle request = new Bundle();

View File

@ -1,8 +1,33 @@
package ca.uhn.fhir.rest.server.interceptor; package ca.uhn.fhir.rest.server.interceptor;
import static org.apache.commons.lang3.StringUtils.defaultString; import ca.uhn.fhir.parser.IParser;
import static org.apache.commons.lang3.StringUtils.isBlank; import ca.uhn.fhir.rest.api.Constants;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.*;
/* /*
* #%L * #%L
@ -13,9 +38,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -24,40 +49,14 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* #L% * #L%
*/ */
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.util.UrlUtil;
/** /**
* This interceptor detects when a request is coming from a browser, and automatically returns a response with syntax * This interceptor detects when a request is coming from a browser, and automatically returns a response with syntax
* highlighted (coloured) HTML for the response instead of just returning raw XML/JSON. * highlighted (coloured) HTML for the response instead of just returning raw XML/JSON.
* *
* @since 1.0 * @since 1.0
*/ */
public class ResponseHighlighterInterceptor extends InterceptorAdapter { public class ResponseHighlighterInterceptor extends InterceptorAdapter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseHighlighterInterceptor.class);
private static final String[] PARAM_FORMAT_VALUE_JSON = new String[] { Constants.FORMAT_JSON };
private static final String[] PARAM_FORMAT_VALUE_XML = new String[] { Constants.FORMAT_XML };
/** /**
* TODO: As of HAPI 1.6 (2016-06-10) this parameter has been replaced with simply * TODO: As of HAPI 1.6 (2016-06-10) this parameter has been replaced with simply
* requesting _format=json or xml so eventually this parameter should be removed * requesting _format=json or xml so eventually this parameter should be removed
@ -65,7 +64,9 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
public static final String PARAM_RAW = "_raw"; public static final String PARAM_RAW = "_raw";
public static final String PARAM_RAW_TRUE = "true"; public static final String PARAM_RAW_TRUE = "true";
public static final String PARAM_TRUE = "true"; public static final String PARAM_TRUE = "true";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseHighlighterInterceptor.class);
private static final String[] PARAM_FORMAT_VALUE_JSON = new String[]{Constants.FORMAT_JSON};
private static final String[] PARAM_FORMAT_VALUE_XML = new String[]{Constants.FORMAT_XML};
private boolean myShowRequestHeaders = false; private boolean myShowRequestHeaders = false;
private boolean myShowResponseHeaders = true; private boolean myShowResponseHeaders = true;
@ -226,7 +227,7 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
@Override @Override
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
throws ServletException, IOException { throws ServletException, IOException {
/* /*
* It's not a browser... * It's not a browser...
*/ */
@ -267,6 +268,18 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
return myShowRequestHeaders; return myShowRequestHeaders;
} }
/**
* If set to <code>true</code> (default is <code>false</code>) response will include the
* request headers
*
* @return Returns a reference to this for easy method chaining
*/
@SuppressWarnings("UnusedReturnValue")
public ResponseHighlighterInterceptor setShowRequestHeaders(boolean theShowRequestHeaders) {
myShowRequestHeaders = theShowRequestHeaders;
return this;
}
/** /**
* If set to <code>true</code> (default is <code>true</code>) response will include the * If set to <code>true</code> (default is <code>true</code>) response will include the
* response headers * response headers
@ -275,9 +288,21 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
return myShowResponseHeaders; return myShowResponseHeaders;
} }
/**
* If set to <code>true</code> (default is <code>true</code>) response will include the
* response headers
*
* @return Returns a reference to this for easy method chaining
*/
@SuppressWarnings("UnusedReturnValue")
public ResponseHighlighterInterceptor setShowResponseHeaders(boolean theShowResponseHeaders) {
myShowResponseHeaders = theShowResponseHeaders;
return this;
}
@Override @Override
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
throws AuthenticationException { throws AuthenticationException {
/* /*
* Request for _raw * Request for _raw
@ -345,30 +370,6 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
return false; return false;
} }
/**
* If set to <code>true</code> (default is <code>false</code>) response will include the
* request headers
*
* @return Returns a reference to this for easy method chaining
*/
@SuppressWarnings("UnusedReturnValue")
public ResponseHighlighterInterceptor setShowRequestHeaders(boolean theShowRequestHeaders) {
myShowRequestHeaders = theShowRequestHeaders;
return this;
}
/**
* If set to <code>true</code> (default is <code>true</code>) response will include the
* response headers
*
* @return Returns a reference to this for easy method chaining
*/
@SuppressWarnings("UnusedReturnValue")
public ResponseHighlighterInterceptor setShowResponseHeaders(boolean theShowResponseHeaders) {
myShowResponseHeaders = theShowResponseHeaders;
return this;
}
private void streamRequestHeaders(ServletRequest theServletRequest, StringBuilder b) { private void streamRequestHeaders(ServletRequest theServletRequest, StringBuilder b) {
if (theServletRequest instanceof HttpServletRequest) { if (theServletRequest instanceof HttpServletRequest) {
HttpServletRequest sr = (HttpServletRequest) theServletRequest; HttpServletRequest sr = (HttpServletRequest) theServletRequest;
@ -479,14 +480,21 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
b.append(" font-family: monospace;\n"); b.append(" font-family: monospace;\n");
b.append("}"); b.append("}");
b.append(".responseBodyTable {"); b.append(".responseBodyTable {");
b.append(" width: 100%;"); b.append(" width: 100%;\n");
b.append(" margin-left: 0px;"); b.append(" margin-left: 0px;\n");
b.append(" margin-top: 20px;"); b.append(" margin-top: -10px;\n");
b.append(" position: relative;\n");
b.append("}"); b.append("}");
b.append(".responseBodyTableFirstColumn {"); b.append(".responseBodyTableFirstColumn {");
b.append(" position: absolute;\n");
b.append(" width: 70px;\n");
b.append("}"); b.append("}");
b.append(".responseBodyTableSecondColumn {"); b.append(".responseBodyTableSecondColumn {");
b.append(" width: 100%;"); b.append(" position: absolute;\n");
b.append(" margin-left: 70px;\n");
b.append(" vertical-align: top;\n");
b.append(" left: 0px;\n");
b.append(" right: 0px;\n");
b.append("}"); b.append("}");
b.append(".lineAnchor A {"); b.append(".lineAnchor A {");
b.append(" text-decoration: none;"); b.append(" text-decoration: none;");
@ -561,23 +569,29 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
b.append("\n"); b.append("\n");
try { try {
if (isShowRequestHeaders()) { if (isShowRequestHeaders()) {
streamRequestHeaders(theServletRequest, b); streamRequestHeaders(theServletRequest, b);
} }
if (isShowResponseHeaders()) { if (isShowResponseHeaders()) {
streamResponseHeaders(theRequestDetails, theServletResponse, b); streamResponseHeaders(theRequestDetails, theServletResponse, b);
} }
} catch (Throwable t) { } catch (Throwable t) {
// ignore (this will hit if we're running in a servlet 2.5 environment) // ignore (this will hit if we're running in a servlet 2.5 environment)
} }
b.append("<h1>Response Body</h1>");
b.append("<div class=\"responseBodyTable\">");
// Response Body
b.append("<div class=\"responseBodyTableSecondColumn\"><pre>");
StringBuilder target = new StringBuilder(); StringBuilder target = new StringBuilder();
int linesCount = format(encoded, target, encoding); int linesCount = format(encoded, target, encoding);
b.append(target);
b.append("</pre></div>");
b.append("<table class=\"responseBodyTable\" cellspacing=\"0\">"); // Line Numbers
b.append("<tr>"); b.append("<div class=\"responseBodyTableFirstColumn\"><pre>");
b.append("<td class=\"responseBodyTableFirstColumn\"><pre>");
for (int i = 1; i <= linesCount; i++) { for (int i = 1; i <= linesCount; i++) {
b.append("<div class=\"lineAnchor\" id=\"anchor"); b.append("<div class=\"lineAnchor\" id=\"anchor");
b.append(i); b.append(i);
@ -593,15 +607,9 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
b.append(i); b.append(i);
b.append("</a></div>"); b.append("</a></div>");
} }
b.append("</pre></td>"); b.append("</div></td>");
// Response Body b.append("</div>");
b.append("<td class=\"responseBodyTableSecondColumn\"><pre>");
b.append(target);
b.append("</pre></td>");
b.append("</tr>");
b.append("</table>");
b.append("\n"); b.append("\n");
@ -614,9 +622,7 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
b.append("</body>"); b.append("</body>");
b.append("</html>"); b.append("</html>");
//@formatter:off String out = b.toString();
String out = b.toString();
//@formatter:on
theServletResponse.getWriter().append(out); theServletResponse.getWriter().append(out);
theServletResponse.getWriter().close(); theServletResponse.getWriter().close();
@ -627,7 +633,7 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
private void streamResponseHeaders(RequestDetails theRequestDetails, HttpServletResponse theServletResponse, StringBuilder b) { private void streamResponseHeaders(RequestDetails theRequestDetails, HttpServletResponse theServletResponse, StringBuilder b) {
if (theServletResponse.getHeaderNames().isEmpty() == false) { if (theServletResponse.getHeaderNames().isEmpty() == false) {
b.append("<h1>Response</h1>"); b.append("<h1>Response Headers</h1>");
b.append("<div class=\"headersDiv\">"); b.append("<div class=\"headersDiv\">");
for (String nextHeaderName : theServletResponse.getHeaderNames()) { for (String nextHeaderName : theServletResponse.getHeaderNames()) {

View File

@ -14,6 +14,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -79,7 +80,15 @@ public class ResponseHighlightingInterceptorTest {
ourInterceptor.setShowRequestHeaders(new ResponseHighlighterInterceptor().isShowRequestHeaders()); ourInterceptor.setShowRequestHeaders(new ResponseHighlighterInterceptor().isShowRequestHeaders());
ourInterceptor.setShowResponseHeaders(new ResponseHighlighterInterceptor().isShowResponseHeaders()); ourInterceptor.setShowResponseHeaders(new ResponseHighlighterInterceptor().isShowResponseHeaders());
} }
/**
* For interactive testing only
*/
@Test
public void waitForInput() throws IOException {
System.in.read();
}
/** /**
* See #464 * See #464
*/ */
@ -661,6 +670,7 @@ public class ResponseHighlightingInterceptorTest {
assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase()); assertEquals(Constants.CT_FHIR_JSON + ";charset=utf-8", status.getFirstHeader("content-type").getValue().replace(" ", "").toLowerCase());
assertThat(responseContent, not(containsString("html"))); assertThat(responseContent, not(containsString("html")));
} }
@Test @Test
public void testForceApplicationJsonPlusFhir() throws Exception { public void testForceApplicationJsonPlusFhir() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/json+fhir")); HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/json+fhir"));