Work on conditional operations in JPA
This commit is contained in:
parent
7585256037
commit
a09c4438f2
|
@ -24,8 +24,10 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
|||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.text.Normalizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -636,7 +638,12 @@ public abstract class BaseFhirDao implements IDao {
|
|||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
List<NameValuePair> parameters;
|
||||
try {
|
||||
parameters = URLEncodedUtils.parse(new URI(theMatchUrl), "UTF-8");
|
||||
String matchUrl = theMatchUrl;
|
||||
if (matchUrl.indexOf('?') == -1) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Error was: URL does not contain any parameters ('?' not detected)");
|
||||
}
|
||||
matchUrl = matchUrl.replace("|", "%7C");
|
||||
parameters = URLEncodedUtils.parse(new URI(matchUrl), "UTF-8");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Error was: " + e.toString());
|
||||
}
|
||||
|
|
|
@ -200,7 +200,10 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
|
|||
String url = extractTransactionUrlOrThrowException(nextEntry, verb);
|
||||
|
||||
UrlParts parts = parseUrl(verb.getCode(), url);
|
||||
if (parts.getResourceId() != null) {
|
||||
if (res.getId().hasIdPart() && isBlank(parts.getResourceId())) {
|
||||
parts.setResourceId(res.getId().getIdPart());
|
||||
}
|
||||
if (isNotBlank(parts.getResourceId())) {
|
||||
res.setId(new IdDt(parts.getResourceType(), parts.getResourceId()));
|
||||
outcome = resourceDao.update(res, null, false);
|
||||
} else {
|
||||
|
|
|
@ -446,6 +446,22 @@ class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implements ISea
|
|||
}
|
||||
systems.add(null);
|
||||
codes.add(nextValue.getValueAsString());
|
||||
} else if (nextObject instanceof CodingDt) {
|
||||
CodingDt nextValue = (CodingDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String nextSystem = nextValue.getSystemElement().getValueAsString();
|
||||
String nextCode = nextValue.getCodeElement().getValue();
|
||||
if (isNotBlank(nextSystem) || isNotBlank(nextCode)) {
|
||||
systems.add(nextSystem);
|
||||
codes.add(nextCode);
|
||||
}
|
||||
|
||||
if (!nextValue.getDisplayElement().isEmpty()) {
|
||||
systems.add(null);
|
||||
codes.add(nextValue.getDisplayElement().getValue());
|
||||
}
|
||||
} else if (nextObject instanceof CodeableConceptDt) {
|
||||
CodeableConceptDt nextCC = (CodeableConceptDt) nextObject;
|
||||
if (!nextCC.getTextElement().isEmpty()) {
|
||||
|
|
|
@ -217,8 +217,8 @@ public class FhirResourceDaoDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithIfNoneExist() {
|
||||
String methodName = "testCreateWithIfNoneExist";
|
||||
public void testCreateWithIfNoneExistBasic() {
|
||||
String methodName = "testCreateWithIfNoneExistBasic";
|
||||
MethodOutcome results;
|
||||
|
||||
Patient p = new Patient();
|
||||
|
|
|
@ -4,7 +4,15 @@ import static org.hamcrest.Matchers.*;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
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.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -13,6 +21,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
@ -31,6 +40,8 @@ import org.junit.BeforeClass;
|
|||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.google.common.net.UrlEscapers;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
|
@ -89,6 +100,7 @@ public class ResourceProviderDstu2Test {
|
|||
private static DaoConfig ourDaoConfig;
|
||||
private static CloseableHttpClient ourHttpClient;
|
||||
private static String ourServerBase;
|
||||
private static int ourPort;
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
|
@ -147,6 +159,7 @@ public class ResourceProviderDstu2Test {
|
|||
String resource = ourFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
post.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?name=" + methodName);
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
IdDt id;
|
||||
|
@ -166,7 +179,7 @@ public class ResourceProviderDstu2Test {
|
|||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
|
||||
assertEquals(id.getValue(), newIdString);
|
||||
assertEquals(id.getValue(), newIdString); // version should match for conditional create
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
@ -181,7 +194,7 @@ public class ResourceProviderDstu2Test {
|
|||
pt.addName().addFamily(methodName);
|
||||
String resource = ourFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient?name=" + methodName);
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
IdDt id;
|
||||
|
@ -200,7 +213,7 @@ public class ResourceProviderDstu2Test {
|
|||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
IdDt newId = new IdDt(response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue());
|
||||
assertEquals(id.toVersionless(), newId.toVersionless());
|
||||
assertEquals(id.toVersionless(), newId.toVersionless()); // version shouldn't match for conditional update
|
||||
assertNotEquals(id, newId);
|
||||
} finally {
|
||||
response.close();
|
||||
|
@ -209,8 +222,8 @@ public class ResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteResourceConditional() throws IOException {
|
||||
String methodName = "testDeleteResourceConditional";
|
||||
public void testDeleteResourceConditional1() throws IOException {
|
||||
String methodName = "testDeleteResourceConditional1";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
|
@ -248,6 +261,67 @@ public class ResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on email from Rene Spronk
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteResourceConditional2() throws IOException, Exception {
|
||||
String methodName = "testDeleteResourceConditional2";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
pt.addIdentifier().setSystem("http://ghh.org/patient").setValue("555-44-4444");
|
||||
String resource = ourFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
IdDt id;
|
||||
try {
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
|
||||
assertThat(newIdString, startsWith(ourServerBase + "/Patient/"));
|
||||
id = new IdDt(newIdString);
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL
|
||||
* but we want to make sure that works too..
|
||||
*/
|
||||
Socket sock = new Socket();
|
||||
try {
|
||||
sock.connect(new InetSocketAddress("localhost", ourPort));
|
||||
sock.getOutputStream().write(("DELETE " + "/fhir/context/Patient?identifier=" + ("http://ghh.org/patient|555-44-4444")).getBytes("UTF-8"));
|
||||
sock.getOutputStream().write("\n\n".getBytes("UTF-8"));
|
||||
sock.getOutputStream().flush();
|
||||
|
||||
InputStream inputStream = sock.getInputStream();
|
||||
|
||||
byte[] buf = new byte[10000];
|
||||
int count;
|
||||
StringBuilder b = new StringBuilder();
|
||||
while ((count = inputStream.read(buf)) > 0) {
|
||||
b.append(new String(buf, 0, count, Charset.forName("UTF-8")));
|
||||
}
|
||||
String resp = b.toString();
|
||||
|
||||
ourLog.info("Resp: {}", resp);
|
||||
} finally {
|
||||
sock.close();
|
||||
}
|
||||
HttpGet read = new HttpGet(ourServerBase + "/Patient/" + id.getIdPart());
|
||||
response = ourHttpClient.execute(read);
|
||||
try {
|
||||
ourLog.info(response.toString());
|
||||
assertEquals(Constants.STATUS_HTTP_410_GONE, response.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
|
@ -746,8 +820,7 @@ public class ResourceProviderDstu2Test {
|
|||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
||||
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
||||
.execute();
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getResource().getId().getIdPart());
|
||||
|
||||
|
@ -845,8 +918,7 @@ public class ResourceProviderDstu2Test {
|
|||
|
||||
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2/_history"));
|
||||
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2"))
|
||||
.encodedJson().prettyPrint().execute();
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2")).encodedJson().prettyPrint().execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getResource().getId().getIdPart());
|
||||
|
||||
|
@ -862,13 +934,13 @@ public class ResourceProviderDstu2Test {
|
|||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
|
||||
RestfulServer restServer = new RestfulServer();
|
||||
ourFhirCtx = FhirContext.forDstu2();
|
||||
restServer.setFhirContext(ourFhirCtx);
|
||||
|
||||
ourServerBase = "http://localhost:" + port + "/fhir/context";
|
||||
ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
|
||||
|
||||
ourAppCtx = new ClassPathXmlApplicationContext("hapi-fhir-server-resourceproviders-dstu2.xml", "fhir-jpabase-spring-test-config.xml");
|
||||
|
||||
|
@ -886,7 +958,7 @@ public class ResourceProviderDstu2Test {
|
|||
|
||||
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
ourServer = new Server(port);
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
|
|
@ -41,6 +41,14 @@ public class SystemProviderTest {
|
|||
ourLog.info(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionFromBundle2() throws Exception {
|
||||
|
||||
InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
||||
String bundle = IOUtils.toString(bundleRes);
|
||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||
ourLog.info(response);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="ringholm1430996763590912"/>
|
||||
<type value="transaction"/>
|
||||
<entry>
|
||||
<resource>
|
||||
<Provenance>
|
||||
<id value="ringholm1430996763591053"/>
|
||||
<text>
|
||||
<status value="generated"/>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">Authored on 15-Feb 2015 by GHH.</div>
|
||||
</text>
|
||||
<target>
|
||||
<!-- unversioned, part of a transaction -->
|
||||
<reference value="Patient/b555-44-4444"/>
|
||||
</target>
|
||||
<recorded value="2015-05-07T13:06:03+01:00"/>
|
||||
<reason>
|
||||
<text value="Patient validated demographics."/>
|
||||
</reason>
|
||||
<agent>
|
||||
<role>
|
||||
<system value="http://hl7.org/fhir/provenance-participant-role"/>
|
||||
<code value="author"/>
|
||||
</role>
|
||||
<type>
|
||||
<system value="http://hl7.org/fhir/provenance-participant-type"/>
|
||||
<code value="patient"/>
|
||||
</type>
|
||||
<referenceReference>
|
||||
<reference value="Patient/b555-44-4444"/>
|
||||
<display value="Patient Everywoman"/>
|
||||
</referenceReference>
|
||||
<display value="Eve Everywoman"/>
|
||||
</agent>
|
||||
</Provenance>
|
||||
</resource>
|
||||
<transaction>
|
||||
<method value="POST"/>
|
||||
</transaction>
|
||||
</entry>
|
||||
<entry>
|
||||
<resource>
|
||||
<Patient>
|
||||
<id value="b555-44-4444"/>
|
||||
<extension url="http://ihe.net/ITI-78/Profile/pdqm#mothersMaidenName">
|
||||
<valueHumanName>
|
||||
<family value="Jones"/>
|
||||
</valueHumanName>
|
||||
</extension>
|
||||
<identifier>
|
||||
<use value="official"/>
|
||||
<system value="http://ghh.org/patient"/>
|
||||
<value value="555-44-4444"/>
|
||||
</identifier>
|
||||
<identifier>
|
||||
<use value="official"/>
|
||||
<system value="http://www.ohio.gov/dmv/driverslicence"/>
|
||||
<value value="67-A4335"/>
|
||||
<period>
|
||||
<end value="2003-05-20"/>
|
||||
</period>
|
||||
</identifier>
|
||||
<name>
|
||||
<use value="official"/>
|
||||
<family value="Everywoman"/>
|
||||
<given value="Eve E."/>
|
||||
</name>
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="(206)3345232"/>
|
||||
<use value="home"/>
|
||||
</telecom>
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="(206)752-121"/>
|
||||
<use value="work"/>
|
||||
</telecom>
|
||||
<gender value="female"/>
|
||||
<birthDate value="1962-03-20"/>
|
||||
<address>
|
||||
<line value="153 Fernwood Dr."/>
|
||||
<city value="Statesville"/>
|
||||
<state value="OH"/>
|
||||
<postalCode value="35292"/>
|
||||
</address>
|
||||
<managingOrganization>
|
||||
<reference value="Organization/GHH"/>
|
||||
<display value="Good Health Hospital"/>
|
||||
</managingOrganization>
|
||||
<link>
|
||||
<other>
|
||||
<reference value="Patient/temp6789"/>
|
||||
</other>
|
||||
<type value="seealso"/>
|
||||
</link>
|
||||
<active value="true"/>
|
||||
</Patient>
|
||||
</resource>
|
||||
<transaction>
|
||||
<method value="PUT"/>
|
||||
<url value="Patient/?identifier=http://ghh.org/patient%7C555-44-4444"/>
|
||||
</transaction>
|
||||
</entry>
|
||||
<entry>
|
||||
<resource>
|
||||
<Patient>
|
||||
<!-- Jane Doe registered in the emergency department -->
|
||||
<id value="temp6789"/>
|
||||
<identifier>
|
||||
<use value="temp"/>
|
||||
<system value="http://ghh.org/patient"/>
|
||||
<value value="temp6789"/>
|
||||
</identifier>
|
||||
<name>
|
||||
<use value="temp"/>
|
||||
<family value="Doe 6789"/>
|
||||
<given value="Jane"/>
|
||||
</name>
|
||||
<gender value="female"/>
|
||||
<managingOrganization>
|
||||
<reference value="Organization/GHH"/>
|
||||
<display value="Good Health Hospital"/>
|
||||
</managingOrganization>
|
||||
<link>
|
||||
<other>
|
||||
<reference value="Patient/b555-44-4444"/>
|
||||
</other>
|
||||
<type value="replace"/>
|
||||
</link>
|
||||
<active value="true"/>
|
||||
</Patient>
|
||||
</resource>
|
||||
<transaction>
|
||||
<method value="PUT"/>
|
||||
<url value="Patient/?identifier=http://ghh.org/patient%7Ctemp6789"/>
|
||||
</transaction>
|
||||
</entry>
|
||||
<entry>
|
||||
<resource>
|
||||
<Organization>
|
||||
<id value="GHH"/>
|
||||
<identifier>
|
||||
<!-- Identifier for the GHH hospital -->
|
||||
<use value="official"/>
|
||||
<system value="http://ghh.org/department"/>
|
||||
<value value="GHH"/>
|
||||
</identifier>
|
||||
<name value="Good Health Hospital"/>
|
||||
<type>
|
||||
<!-- GHH is a Hospital -->
|
||||
<coding>
|
||||
<system value="http://snomed.info/sct"/>
|
||||
<code value="22232009"/>
|
||||
<display value="Hospital"/>
|
||||
</coding>
|
||||
</type>
|
||||
<active value="true"/>
|
||||
</Organization>
|
||||
</resource>
|
||||
<transaction>
|
||||
<method value="POST"/>
|
||||
<url value="Organization"/>
|
||||
<ifNoneExist value="Organization/?identifier=http://ghh.org/department%7CGHH"/>
|
||||
</transaction>
|
||||
</entry>
|
||||
</Bundle>
|
||||
|
Loading…
Reference in New Issue