diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java index b914dcd3b3b..dc268dee9bb 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionParamBinder.java @@ -98,7 +98,9 @@ class TransactionParamBinder implements IParameter { @Override public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException { - EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingWithDefault(theRequest.getServer(), theRequest.getServletRequest()); + // TODO: don't use a default encoding, just fail! + EncodingEnum encoding = RestfulServerUtils.determineRequestEncoding(theRequest); + IParser parser = encoding.newParser(myContext); BufferedReader reader; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java index b478c7516a4..020489dbfa0 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java @@ -3,11 +3,17 @@ package ca.uhn.fhir.jpa.provider; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketTimeoutException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Date; @@ -280,26 +286,32 @@ public class ResourceProviderDstu2Test { * but we want to make sure that works too.. */ Socket sock = new Socket(); + sock.setSoTimeout(3000); try { sock.connect(new InetSocketAddress("localhost", ourPort)); - sock.getOutputStream().write(("DELETE " + "/fhir/context/Patient?identifier=" + ("http://ghh.org/patient|" + methodName)).getBytes("UTF-8")); - sock.getOutputStream().write("\n\n".getBytes("UTF-8")); - sock.getOutputStream().flush(); + sock.getOutputStream().write(("DELETE /fhir/context/Patient?identifier=http://ghh.org/patient|" + methodName + " HTTP/1.1\n").getBytes("UTF-8")); + sock.getOutputStream().write("Host: localhost\n".getBytes("UTF-8")); + sock.getOutputStream().write("\n".getBytes("UTF-8")); - InputStream inputStream = sock.getInputStream(); + BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream())); - byte[] buf = new byte[10000]; - int count; - StringBuilder b = new StringBuilder(); - while ((count = inputStream.read(buf)) != -1) { - b.append(new String(buf, 0, count, Charset.forName("UTF-8"))); - } + //String response = ""; + StringBuilder b = new StringBuilder(); + char[] buf = new char[1000]; + while(socketInput.read(buf) != -1){ + b.append(buf); + } String resp = b.toString(); ourLog.info("Resp: {}", resp); + } catch (SocketTimeoutException e) { + e.printStackTrace(); } finally { sock.close(); } + + Thread.sleep(1000); + HttpGet read = new HttpGet(ourServerBase + "/Patient/" + id.getIdPart()); response = ourHttpClient.execute(read); try { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java index 8d18c2d0bfa..bb086dc2e02 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java @@ -46,6 +46,16 @@ public class SystemProviderTest { ourLog.info(response); } + // TODO: enable! +// @Test + public void testTransactionFromBundle3() throws Exception { + + InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/grahame-transaction.xml"); + String bundle = IOUtils.toString(bundleRes); + String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute(); + ourLog.info(response); + } + @Test public void testTransactionFromBundle2() throws Exception { diff --git a/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction-with-bad.xml b/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction-with-bad.xml new file mode 100644 index 00000000000..1bded386d93 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction-with-bad.xml @@ -0,0 +1,446 @@ + + + + + + + + + + + + +
Make sure links are updated: Patient +
+
+ + + + + + + +
+
+ + + + +
+ + + + + + + +
Snipped for brevity
+
+ + + + + + + + + + +
+
+ + + + + +
+ + + + + + +
Snipped for brevity
+
+ + + + + + + + + + +
+
+ + + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + + +
+ + + + + + +
Snipped
+
+ + + + + + + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + + + + + +
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Snipped for brevity
+
+ + + + + + + + + + +
+
+ + + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + + +
+ + + + + + +
Snipped
+
+ + + + + + + + + +
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Snipped
+
+ + + + + + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction.xml b/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction.xml new file mode 100644 index 00000000000..d3baf5b5aa8 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/resources/grahame-transaction.xml @@ -0,0 +1,285 @@ + + + + + + + + + + + + +
Make sure links are updated: Patient +
+
+ + + + + + + +
+
+ + + + +
+ + + + + + + +
Snipped for brevity
+
+ + + + + + + + + + +
+
+ + + + + +
+ + + + + + +
Snipped for brevity
+
+ + + + + + + + + + +
+
+ + + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + +
+
+ + + + + +
+ + + + + + +
Snipped
+
+ + + + + + + + + +
+
+ + + + +
+ + + + + + + +
Snipped
+
+ + + + + + + + +
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java index 8c67b58fca7..dce0d9c8bcb 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/TransactionWithBundleResourceParamTest.java @@ -55,7 +55,7 @@ public class TransactionWithBundleResourceParamTest { } @Test - public void testTransaction() throws Exception { + public void testTransactionWithXmlRequest() throws Exception { Bundle b = new Bundle(); InstantDt nowInstant = InstantDt.withCurrentTime(); @@ -79,8 +79,55 @@ public class TransactionWithBundleResourceParamTest { ourLog.info(bundleString); HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); - httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); - httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_ATOM_XML, "UTF-8"))); + httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + ourLog.info(responseContent); + + Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent); + assertEquals(3, bundle.getEntry().size()); + + Entry entry0 = bundle.getEntry().get(0); + assertEquals("Patient/81/_history/91", entry0.getTransactionResponse().getLocation()); + + Entry entry1 = bundle.getEntry().get(1); + assertEquals( "Patient/82/_history/92", entry1.getTransactionResponse().getLocation()); + + Entry entry2 = bundle.getEntry().get(2); + assertEquals("Patient/123/_history/93", entry2.getTransactionResponse().getLocation()); + } + + @Test + public void testTransactionWithJsonRequest() throws Exception { + Bundle b = new Bundle(); + InstantDt nowInstant = InstantDt.withCurrentTime(); + + Patient p1 = new Patient(); + p1.addName().addFamily("Family1"); + Entry entry = b.addEntry(); + p1.getId().setValue("1"); + entry.setResource(p1); + + Patient p2 = new Patient(); + p2.addName().addFamily("Family2"); + entry = b.addEntry(); + p2.getId().setValue("2"); + entry.setResource(p2); + + Entry deletedEntry = b.addEntry(); + deletedEntry.getTransaction().setMethod(HTTPVerbEnum.DELETE); + deletedEntry.getTransaction().setUrl("http://base.com/Patient/123"); + + String bundleString = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b); + ourLog.info(bundleString); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/"); +// httpPost.addHeader("Accept", Constants.CT_ATOM_XML + "; pretty=true"); + httpPost.setEntity(new StringEntity(bundleString, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); HttpResponse status = ourClient.execute(httpPost); String responseContent = IOUtils.toString(status.getEntity().getContent()); IOUtils.closeQuietly(status.getEntity().getContent()); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3a9777ac36a..54b89065e69 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -217,6 +217,10 @@ HTTP 403 Forbidden status code. Thanks to Joel Costigliola for the patch! + + Transaction server operations incorrectly used the "Accept" header instead of the "Content-Type" header to determine the + POST request encoding. Thanks to Rene Spronk for providing a test case! +