Add support for a NarrativeModeEnum parameter to interact with
_narrative in the request URL
This commit is contained in:
parent
c484425c78
commit
690bcb4b68
|
@ -94,7 +94,7 @@
|
|||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>${maven_assembly_plugin_version}</version>
|
||||
<version>2.5.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
@ -104,8 +104,8 @@
|
|||
<configuration>
|
||||
<attach>true</attach>
|
||||
<descriptors>
|
||||
<descriptor>${project.basedir}/src/assembly/android-sources.xml</descriptor>
|
||||
<descriptor>${project.basedir}/src/assembly/android-javadoc.xml</descriptor>
|
||||
<descriptor>/Users/t3903uhn/git/hapi-fhir/hapi-fhir-android/src/assembly/android-sources.xml</descriptor>
|
||||
<descriptor>/Users/t3903uhn/git/hapi-fhir/hapi-fhir-android/src/assembly/android-javadoc.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PushbackReader;
|
||||
|
@ -77,6 +78,7 @@ import ca.uhn.fhir.rest.param.TokenAndListParam;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
||||
import ca.uhn.fhir.rest.server.SearchParameterMap;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
|
@ -342,6 +344,8 @@ public class MethodUtil {
|
|||
param = new ServletRequestParameter();
|
||||
} else if (parameterType.equals(HttpServletResponse.class) || parameterType.equals(ServletResponse.class)) {
|
||||
param = new ServletResponseParameter();
|
||||
} else if (parameterType.equals(NarrativeModeEnum.class)) {
|
||||
param = new NarrativeModeParameter();
|
||||
} else {
|
||||
for (int i = 0; i < annotations.length && param == null; i++) {
|
||||
Annotation nextAnnotation = annotations[i];
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
class NarrativeModeParameter implements IParameter {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletResponseParameter.class);
|
||||
|
||||
@Override
|
||||
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource)
|
||||
throws InternalErrorException {
|
||||
if (theSourceClientArgument != null) {
|
||||
NarrativeModeEnum n = (NarrativeModeEnum) theSourceClientArgument;
|
||||
theTargetQueryArguments.put(Constants.PARAM_NARRATIVE, Collections.singletonList(n.name().toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
|
||||
String val = theRequest.getServletRequest().getParameter(Constants.PARAM_NARRATIVE);
|
||||
if (val != null) {
|
||||
try {
|
||||
return NarrativeModeEnum.valueOfCaseInsensitive(val);
|
||||
} catch (IllegalArgumentException e) {
|
||||
ourLog.debug("Invalid {} parameger: {}", Constants.PARAM_NARRATIVE, val);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
|
@ -70,8 +70,8 @@ public class RestfulServerUtils {
|
|||
return count;
|
||||
}
|
||||
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip,
|
||||
String theServerBase) throws IOException {
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||
theHttpResponse.setStatus(stausCode);
|
||||
|
||||
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
|
||||
|
@ -267,13 +267,17 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static RestfulServer.NarrativeModeEnum determineNarrativeMode(RequestDetails theRequest) {
|
||||
Map<String, String[]> requestParams = theRequest.getParameters();
|
||||
String[] narrative = requestParams.remove(Constants.PARAM_NARRATIVE);
|
||||
RestfulServer.NarrativeModeEnum narrativeMode = null;
|
||||
if (narrative != null && narrative.length > 0) {
|
||||
try {
|
||||
narrativeMode = RestfulServer.NarrativeModeEnum.valueOfCaseInsensitive(narrative[0]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
ourLog.debug("Invalid {} parameger: {}", Constants.PARAM_NARRATIVE, narrative[0]);
|
||||
narrativeMode = null;
|
||||
}
|
||||
}
|
||||
if (narrativeMode == null) {
|
||||
narrativeMode = RestfulServer.NarrativeModeEnum.NORMAL;
|
||||
|
@ -282,13 +286,12 @@ public class RestfulServerUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's
|
||||
* <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingWithDefault(RestfulServer theServer, HttpServletRequest theReq) {
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq);
|
||||
if (retVal == null) {
|
||||
retVal =theServer.getDefaultResponseEncoding();
|
||||
retVal = theServer.getDefaultResponseEncoding();
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
@ -347,12 +350,13 @@ public class RestfulServerUtils {
|
|||
return RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_COUNT);
|
||||
}
|
||||
|
||||
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, EncodingEnum theResponseEncoding, String theServerBase, boolean thePrettyPrint, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, boolean theRequestIsBrowser) throws IOException {
|
||||
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, EncodingEnum theResponseEncoding, String theServerBase,
|
||||
boolean thePrettyPrint, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, boolean theRequestIsBrowser) throws IOException {
|
||||
assert !theServerBase.endsWith("/");
|
||||
|
||||
theHttpResponse.setStatus(200);
|
||||
|
||||
EncodingEnum responseEncoding = theResponseEncoding!= null? theResponseEncoding : theServer.getDefaultResponseEncoding();
|
||||
EncodingEnum responseEncoding = theResponseEncoding != null ? theResponseEncoding : theServer.getDefaultResponseEncoding();
|
||||
|
||||
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
|
||||
theHttpResponse.setContentType(responseEncoding.getBrowserFriendlyBundleContentType());
|
||||
|
@ -383,10 +387,11 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase)
|
||||
throws IOException {
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||
int stausCode = 200;
|
||||
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip, theServerBase);
|
||||
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
||||
theServerBase);
|
||||
}
|
||||
|
||||
public static void validateResourceListNotNull(List<IResource> theResourceList) {
|
||||
|
@ -395,6 +400,4 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ import ca.uhn.fhir.rest.param.TokenOrListParam;
|
|||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
|
@ -148,7 +149,7 @@ public class ClientTest {
|
|||
HttpPost post = (HttpPost) capt.getValue();
|
||||
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
|
||||
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType()+Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals("200", response.getId().getVersionIdPart());
|
||||
}
|
||||
|
||||
|
@ -173,8 +174,7 @@ public class ClientTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Some servers (older ones?) return the resourcde you created instead of an OperationOutcome. We just need to
|
||||
* ignore it.
|
||||
* Some servers (older ones?) return the resourcde you created instead of an OperationOutcome. We just need to ignore it.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateWithResourceResponse() throws Exception {
|
||||
|
@ -533,12 +533,12 @@ public class ClientTest {
|
|||
|
||||
client.getHistoryPatientInstance(new IdDt("111"), new InstantDt("2012-01-02T12:01:02"), new IntegerDt(12));
|
||||
assertThat(capt.getAllValues().get(0).getURI().toString(), containsString("http://foo/Patient/111/_history?"));
|
||||
assertThat(capt.getAllValues().get(0).getURI().toString(), containsString("_since="+expectedDateString.replaceAll("\\..*", "")));
|
||||
assertThat(capt.getAllValues().get(0).getURI().toString(), containsString("_since=" + expectedDateString.replaceAll("\\..*", "")));
|
||||
assertThat(capt.getAllValues().get(0).getURI().toString(), containsString("_count=12"));
|
||||
|
||||
client.getHistoryPatientInstance(new IdDt("111"), new InstantDt("2012-01-02T12:01:02").getValue(), new IntegerDt(12).getValue());
|
||||
assertThat(capt.getAllValues().get(1).getURI().toString(), containsString("http://foo/Patient/111/_history?"));
|
||||
assertThat(capt.getAllValues().get(1).getURI().toString(), containsString("_since="+expectedDateString));
|
||||
assertThat(capt.getAllValues().get(1).getURI().toString(), containsString("_since=" + expectedDateString));
|
||||
assertThat(capt.getAllValues().get(1).getURI().toString(), containsString("_count=12"));
|
||||
|
||||
client.getHistoryPatientInstance(new IdDt("111"), null, new IntegerDt(12));
|
||||
|
@ -592,7 +592,8 @@ public class ClientTest {
|
|||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"),
|
||||
Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"),
|
||||
new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"),
|
||||
new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") };
|
||||
|
||||
when(httpResponse.getAllHeaders()).thenReturn(headers);
|
||||
|
@ -653,7 +654,6 @@ public class ClientTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReadFailureInternalError() throws Exception {
|
||||
|
||||
|
@ -1085,7 +1085,7 @@ public class ClientTest {
|
|||
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
|
||||
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
|
||||
assertEquals("200", response.getId().getVersionIdPart());
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType()+Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1213,6 +1213,36 @@ public class ClientTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNarrativeModeParam() throws Exception {
|
||||
final String msg = getPatientFeedWithOneResult();
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
ITestClientWithNarrativeParam client = ctx.newRestfulClient(ITestClientWithNarrativeParam.class, "http://foo");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient response = client.getPatients(null);
|
||||
assertEquals("http://foo/Patient", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertNotNull(response);
|
||||
idx++;
|
||||
|
||||
response = client.getPatients(NarrativeModeEnum.ONLY);
|
||||
assertEquals("http://foo/Patient?_narrative=only", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertNotNull(response);
|
||||
|
||||
}
|
||||
|
||||
private Header[] toHeaderArray(String theName, String theValue) {
|
||||
return new Header[] { new BasicHeader(theName, theValue) };
|
||||
}
|
||||
|
@ -1240,4 +1270,10 @@ public class ClientTest {
|
|||
@Search()
|
||||
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam String theInclude);
|
||||
}
|
||||
|
||||
public interface ITestClientWithNarrativeParam extends IBasicClient {
|
||||
@Search()
|
||||
public Patient getPatients(NarrativeModeEnum theNarrativeMode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,10 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.net.UrlEscapers;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -41,7 +40,6 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
@ -50,8 +48,11 @@ import ca.uhn.fhir.rest.param.StringOrListParam;
|
|||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
import com.google.common.net.UrlEscapers;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
|
@ -63,6 +64,12 @@ public class SearchTest {
|
|||
private static int ourPort;
|
||||
|
||||
private static Server ourServer;
|
||||
private static NarrativeModeEnum ourLastNarrativeMode;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourLastNarrativeMode=null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeConvertsReferencesToRelative() throws Exception {
|
||||
|
@ -78,6 +85,36 @@ public class SearchTest {
|
|||
assertEquals("Organization/555", ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNarrativeParamNone() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWithNarrative");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertEquals(null, ourLastNarrativeMode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNarrativeParamPopulated() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWithNarrative&_narrative=ONly");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertEquals(NarrativeModeEnum.ONLY, ourLastNarrativeMode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNarrativeParamPopulatedInvalid() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWithNarrative&_narrative=BLAH");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertEquals(null, ourLastNarrativeMode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOmitEmptyOptionalParam() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id=");
|
||||
|
@ -328,6 +365,14 @@ public class SearchTest {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Search(queryName="searchWithNarrative")
|
||||
public Patient searchWithNarrative(NarrativeModeEnum theNarrativeMode) {
|
||||
ourLastNarrativeMode = theNarrativeMode;
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1/_history/1");
|
||||
return patient;
|
||||
}
|
||||
|
||||
@Search(queryName="searchWithRef")
|
||||
public Patient searchWithRef() {
|
||||
Patient patient = new Patient();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -10,7 +12,6 @@ import org.apache.commons.io.IOUtils;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
@ -26,13 +27,6 @@ import org.junit.Test;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
|
@ -42,7 +36,6 @@ import ca.uhn.fhir.rest.annotation.IdParam;
|
|||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
|
@ -51,10 +44,10 @@ import ca.uhn.fhir.util.PortUtil;
|
|||
*/
|
||||
public class CreateConditionalTest {
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
||||
private static String ourLastConditionalUrl;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CreateConditionalTest.class);
|
||||
private static int ourPort;
|
||||
|
||||
private static Server ourServer;
|
||||
private static IdDt ourLastId;
|
||||
private static IdDt ourLastIdParam;
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class PreferTest {
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PreferTest.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateWithNoPrefer() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), 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());
|
||||
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("location").getValue());
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("content-location").getValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
PatientProvider patientProvider = new PatientProvider();
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer();
|
||||
servlet.setResourceProviders(patientProvider);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourClient = builder.build();
|
||||
|
||||
}
|
||||
|
||||
public static class PatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Create()
|
||||
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||
MethodOutcome retVal = new MethodOutcome(new IdDt("Patient/001/_history/002"));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Update()
|
||||
public MethodOutcome updatePatient(@ResourceParam Patient thePatient, @IdParam IdDt theIdParam) {
|
||||
return new MethodOutcome(new IdDt("Patient/001/_history/002"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -76,6 +76,16 @@
|
|||
Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks
|
||||
to Doug Martin for the suggestion!
|
||||
</action>
|
||||
<action type="add">
|
||||
REST server methods may now have a parameter of
|
||||
type NarrativeModeEnum which will be populated with
|
||||
the value of the _narrative URL parameter
|
||||
if one was supplied. Annotation client methods
|
||||
may also include a parameter of this type, and it
|
||||
will be used to populate this parameter on the request
|
||||
URL if it is not null. Thanks to Neal Acharya for the
|
||||
idea!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.9" date="2015-Mar-14">
|
||||
<action type="add">
|
||||
|
|
|
@ -1006,7 +1006,7 @@
|
|||
<a href="./apidocs/ca/uhn/fhir/model/api/annotation/Description.html">@Description</a>
|
||||
annotation. This annotation allows you to add a description of the method
|
||||
and the individual parameters. These descriptions will be placed in the
|
||||
server's metadata statement, which can be helpful to anyone who is developing
|
||||
server's conformance statement, which can be helpful to anyone who is developing
|
||||
software against your server.
|
||||
</p>
|
||||
|
||||
|
|
|
@ -350,6 +350,19 @@
|
|||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Accessing the _narrative parameter value">
|
||||
|
||||
<p>
|
||||
There are different ways of
|
||||
<a href="./doc_narrative.html">generating narratives</a> for use on your server. HAPI's Server
|
||||
also provides a non-standard parameter called <code>_narrative</code> which can be used to
|
||||
control narrative behavour. If you add a parameter to any server (or annotation client) method
|
||||
with a type of <code>NarrativeModeEnum</code>, the value will be populated with the value
|
||||
of this URL parameter.
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
<!--
|
||||
|
|
Loading…
Reference in New Issue