Lots of tweaks for DSTU2 support

This commit is contained in:
James Agnew 2015-01-29 11:34:57 -05:00
parent 9d7796f0be
commit 6c6685137f
21 changed files with 360 additions and 108 deletions

View File

@ -41,6 +41,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
@ -64,6 +65,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
private final String myContents;
private boolean myContentsIsBundle;
private Map<String, List<String>> myParams;
private final BundleTypeEnum myBundleType;
public BaseHttpClientInvocationWithContents(FhirContext theContext, IResource theResource, String theUrlPath) {
super();
@ -74,6 +76,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myResources = null;
myBundle = null;
myContents = null;
myBundleType = null;
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, TagList theTagList, String... theUrlPath) {
@ -88,11 +91,12 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myResources = null;
myBundle = null;
myContents = null;
myBundleType = null;
myUrlPath = StringUtils.join(theUrlPath, '/');
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<IResource> theResources) {
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<IResource> theResources, BundleTypeEnum theBundleType) {
myContext = theContext;
myResource = null;
myTagList = null;
@ -100,6 +104,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myResources = theResources;
myBundle = null;
myContents = null;
myBundleType = theBundleType;
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, Bundle theBundle) {
@ -110,6 +115,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myResources = null;
myBundle = theBundle;
myContents = null;
myBundleType = null;
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, String theContents, boolean theIsBundle, String theUrlPath) {
@ -121,6 +127,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundle = null;
myContents = theContents;
myContentsIsBundle = theIsBundle;
myBundleType = null;
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, Map<String, List<String>> theParams, String... theUrlPath) {
@ -133,6 +140,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myContents = null;
myContentsIsBundle = false;
myParams = theParams;
myBundleType = null;
}
@Override
@ -201,7 +209,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
contents = parser.encodeBundleToString(myBundle);
contentType = encoding.getBundleContentType();
} else if (myResources != null) {
Bundle bundle = RestfulServer.createBundleFromResourceList(myContext, "", myResources, "", "", myResources.size());
Bundle bundle = RestfulServer.createBundleFromResourceList(myContext, "", myResources, "", "", myResources.size(), myBundleType);
contents = parser.encodeBundleToString(bundle);
contentType = encoding.getBundleContentType();
} else if (myContents != null) {

View File

@ -98,37 +98,6 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
protected abstract BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource resource);
/*
* @Override public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse)
* throws BaseServerResponseException, IOException { Object[] params = new Object[getParameters().size()]; for (int
* i = 0; i < getParameters().size(); i++) { IParameter param = getParameters().get(i); if (param != null) {
* params[i] = param.translateQueryParametersIntoServerArgument(theRequest, null); } }
*
* addParametersForServerRequest(theRequest, params);
*
* MethodOutcome response = (MethodOutcome) invokeServerMethod(getProvider(), params);
*
* if (response == null) { if (myReturnVoid == false) { throw new ConfigurationException("Method " +
* getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null"); }
* else { theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT); } } else if (!myReturnVoid) { if
* (response.isCreated()) { theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED); StringBuilder b = new
* StringBuilder(); b.append(theRequest.getFhirServerBase()); b.append('/'); b.append(getResourceName());
* b.append('/'); b.append(response.getId().getValue()); if (response.getVersionId() != null &&
* response.getVersionId().isEmpty() == false) { b.append("/_history/");
* b.append(response.getVersionId().getValue()); } theResponse.addHeader("Location", b.toString()); } else {
* theResponse.setStatus(Constants.STATUS_HTTP_200_OK); } } else {
* theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT); }
*
* theServer.addHeadersToResponse(theResponse);
*
* Writer writer = theResponse.getWriter(); try { if (response != null) { OperationOutcome outcome = new
* OperationOutcome(); if (response.getOperationOutcome() != null && response.getOperationOutcome().getIssue() !=
* null) { outcome.getIssue().addAll(response.getOperationOutcome().getIssue()); } EncodingUtil encoding =
* BaseMethodBinding.determineResponseEncoding(theRequest .getServletRequest(), theRequest.getParameters());
* theResponse.setContentType(encoding.getResourceContentType()); IParser parser = encoding.newParser(getContext());
* parser.encodeResourceToWriter(outcome, writer); } } finally { writer.close(); } // getMethod().in }
*/
/**
* For servers, this method will match only incoming requests that match the given operation, or which have no
* operation in the URL if this method returns null.
@ -232,7 +201,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
} else {
servletResponse.setStatus(Constants.STATUS_HTTP_200_OK);
}
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_LOCATION);
addContentLocationHeaders(theRequest, servletResponse, response);
break;
case UPDATE:
@ -241,10 +210,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
} else {
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
}
if (response != null && response.getId() != null) {
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_LOCATION);
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_CONTENT_LOCATION);
}
addContentLocationHeaders(theRequest, servletResponse, response);
break;
case VALIDATE:
@ -279,7 +245,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
writer.close();
}
} else {
servletResponse.setContentType(Constants.CT_TEXT);
servletResponse.setContentType(Constants.CT_TEXT_WITH_UTF8);
Writer writer = servletResponse.getWriter();
writer.close();
}
@ -287,6 +253,13 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
// getMethod().in
}
private void addContentLocationHeaders(Request theRequest, HttpServletResponse servletResponse, MethodOutcome response) {
if (response != null && response.getId() != null) {
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_LOCATION);
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_CONTENT_LOCATION);
}
}
public boolean isReturnVoid() {
return myReturnVoid;
}

View File

@ -103,18 +103,6 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
}
}
@Override
public RestfulOperationTypeEnum getResourceOperationType() {
// TODO Auto-generated method stub
return null;
}
@Override
public RestfulOperationSystemEnum getSystemOperationType() {
// TODO Auto-generated method stub
return null;
}
/**
* For subclasses to override
*/

View File

@ -41,6 +41,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
import ca.uhn.fhir.rest.server.Constants;
@ -242,7 +243,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
switch (getReturnType()) {
case BUNDLE:
Bundle bundle = RestfulServer.createBundleFromBundleProvider(theServer, response, result, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, 0, count, null);
Bundle bundle = RestfulServer.createBundleFromBundleProvider(theServer, response, result, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, 0, count, null, getResponseBundleType());
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = theServer.getInterceptors().get(i);
@ -276,6 +277,11 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
}
}
/**
* If the response is a bundle, this type will be placed in the root of the bundle (can be null)
*/
protected abstract BundleTypeEnum getResponseBundleType();
/**
* Subclasses may override
*

View File

@ -28,6 +28,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseConformance;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
@ -101,4 +102,9 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
return OtherOperationTypeEnum.METADATA;
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return null;
}
}

View File

@ -31,6 +31,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
import ca.uhn.fhir.rest.server.Constants;
@ -61,6 +62,12 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
@Override
public List<IParameter> getParameters() {
List<IParameter> retVal = new ArrayList<IParameter>(super.getParameters());

View File

@ -35,6 +35,7 @@ import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.server.Constants;
@ -125,6 +126,11 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
return retVal;
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.HISTORY;
}
public static HttpGetClientInvocation createHistoryInvocation(String theResourceName, IdDt theId, DateTimeDt theSince, Integer theLimit) {
StringBuilder b = new StringBuilder();
if (theResourceName != null) {

View File

@ -30,6 +30,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
public class HttpPostClientInvocation extends BaseHttpClientInvocationWithContents {
@ -43,8 +44,8 @@ public class HttpPostClientInvocation extends BaseHttpClientInvocationWithConten
}
public HttpPostClientInvocation(FhirContext theContext, List<IResource> theResources) {
super(theContext, theResources);
public HttpPostClientInvocation(FhirContext theContext, List<IResource> theResources, BundleTypeEnum theBundleType) {
super(theContext, theResources, theBundleType);
}

View File

@ -40,6 +40,7 @@ import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
@ -237,4 +238,9 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return null;
}
}

View File

@ -42,6 +42,7 @@ import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.BaseQueryParameter;
@ -475,4 +476,9 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
DELETE, GET, OPTIONS, POST, PUT
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
}

View File

@ -36,6 +36,7 @@ import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
@ -172,11 +173,16 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
}
public static BaseHttpClientInvocation createTransactionInvocation(List<IResource> theResources, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theResources);
return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
}
public static BaseHttpClientInvocation createTransactionInvocation(Bundle theBundle, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theBundle);
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.TRANSACTION_RESPONSE;
}
}

View File

@ -37,6 +37,7 @@ public class Constants {
public static final String CT_JSON = "application/json";
public static final String CT_OCTET_STREAM = "application/octet-stream";
public static final String CT_TEXT = "text/plain";
public static final String CT_TEXT_WITH_UTF8 = CT_TEXT + "; charset=UTF-8";
public static final String CT_XML = "application/xml";
public static final String ENCODING_GZIP = "gzip";
public static final String FORMAT_JSON = "json";

View File

@ -32,6 +32,7 @@ import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntryStatusEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.Destroy;
import ca.uhn.fhir.rest.annotation.IdParam;
@ -426,7 +427,7 @@ public class RestfulServer extends HttpServlet {
NarrativeModeEnum narrativeMode = determineNarrativeMode(theRequest);
boolean respondGzip = theRequest.isRespondGzip();
Bundle bundle = createBundleFromBundleProvider(this, theResponse, resultList, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, start, count, thePagingAction);
Bundle bundle = createBundleFromBundleProvider(this, theResponse, resultList, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, start, count, thePagingAction, null);
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = getInterceptors().get(i);
@ -1031,7 +1032,7 @@ public class RestfulServer extends HttpServlet {
}
public static Bundle createBundleFromBundleProvider(RestfulServer theServer, HttpServletResponse theHttpResponse, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, boolean theRequestIsBrowser,
NarrativeModeEnum theNarrativeMode, int theOffset, Integer theLimit, String theSearchId) {
NarrativeModeEnum theNarrativeMode, int theOffset, Integer theLimit, String theSearchId, BundleTypeEnum theBundleType) {
theHttpResponse.setStatus(200);
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
@ -1093,7 +1094,7 @@ public class RestfulServer extends HttpServlet {
}
}
Bundle bundle = createBundleFromResourceList(theServer.getFhirContext(), theServer.getServerName(), resourceList, theServerBase, theCompleteUrl, theResult.size());
Bundle bundle = createBundleFromResourceList(theServer.getFhirContext(), theServer.getServerName(), resourceList, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
bundle.setPublished(theResult.getPublished());
@ -1115,16 +1116,24 @@ public class RestfulServer extends HttpServlet {
return bundle;
}
public static Bundle createBundleFromResourceList(FhirContext theContext, String theAuthor, List<IResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults) {
public static Bundle createBundleFromResourceList(FhirContext theContext, String theAuthor, List<IResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
Bundle bundle = new Bundle();
bundle.getAuthorName().setValue(theAuthor);
bundle.getBundleId().setValue(UUID.randomUUID().toString());
bundle.getPublished().setToCurrentTimeInLocalTimeZone();
bundle.getLinkBase().setValue(theServerBase);
bundle.getLinkSelf().setValue(theCompleteUrl);
bundle.getType().setValueAsEnum(theBundleType);
List<IResource> includedResources = new ArrayList<IResource>();
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
for (IResource next : theResult) {
if (next.getId().isEmpty() == false) {
addedResourceIds.add(next.getId());
}
}
for (IResource next : theResult) {
Set<String> containedIds = new HashSet<String>();

View File

@ -40,6 +40,7 @@ import ca.uhn.fhir.model.dev.valueset.EncounterStateEnum;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleEntryStatusEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.IGenericClient;
@ -111,6 +112,7 @@ public class CompleteResourceProviderTest {
{
Bundle returned = ourClient.search().forResource(Patient.class).encodedXml().execute();
assertThat(returned.size(), greaterThan(1));
assertEquals(BundleTypeEnum.SEARCHSET, returned.getType().getValueAsEnum());
}
{
Bundle returned = ourClient.search().forResource(Patient.class).encodedJson().execute();
@ -141,8 +143,8 @@ public class CompleteResourceProviderTest {
assertEquals(2, found.size());
assertEquals(Patient.class, found.getEntries().get(0).getResource().getClass());
assertEquals(null, found.getEntries().get(0).getStatus().getValueAsEnum());
assertEquals(null, found.getEntries().get(0).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_STATUS));
assertEquals(BundleEntryStatusEnum.MATCH, found.getEntries().get(0).getStatus().getValueAsEnum());
assertEquals(BundleEntryStatusEnum.MATCH, found.getEntries().get(0).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_STATUS));
assertEquals(Organization.class, found.getEntries().get(1).getResource().getClass());
assertEquals(BundleEntryStatusEnum.INCLUDE, found.getEntries().get(1).getStatus().getValueAsEnum());
assertEquals(BundleEntryStatusEnum.INCLUDE, found.getEntries().get(1).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_STATUS));

View File

@ -0,0 +1,78 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dev.resource.Patient;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.server.Constants;
public class BundleTypeTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BundleTypeTest.class);
private FhirContext ourCtx;
private HttpClient ourHttpClient;
private HttpResponse ourHttpResponse;
@Before
public void before() {
ourCtx = FhirContext.forDstu2();
ourHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
ourCtx.getRestfulClientFactory().setHttpClient(ourHttpClient);
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
}
@Test
public void testTransaction() throws Exception {
String retVal = ourCtx.newXmlParser().encodeBundleToString(new Bundle());
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
when(ourHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8")));
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("value");
IGenericClient client = ourCtx.newRestfulGenericClient("http://foo");
client.transaction().withResources(Arrays.asList((IResource) p1)).execute();
HttpUriRequest value = capt.getValue();
assertTrue("Expected request of type POST on long params list", value instanceof HttpPost);
HttpPost post = (HttpPost) value;
String body = IOUtils.toString(post.getEntity().getContent());
ourLog.info(body);
assertThat(body, Matchers.containsString("<type value=\"" + BundleTypeEnum.TRANSACTION.getCode()));
}
}

View File

@ -0,0 +1,128 @@
package ca.uhn.fhir.rest.server;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
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.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dev.composite.CodingDt;
import ca.uhn.fhir.model.dev.resource.Observation;
import ca.uhn.fhir.model.dev.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
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.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.ReferenceParam;
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.util.PortUtil;
import com.google.common.net.UrlEscapers;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class BundleTypeInResponseTest {
private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = new FhirContext();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BundleTypeInResponseTest.class);
private static int ourPort;
private static Server ourServer;
@Test
public void testSearch() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
assertEquals(BundleTypeEnum.SEARCHSET, bundle.getType().getValueAsEnum());
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer();
servlet.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
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 DummyPatientResourceProvider implements IResourceProvider {
@Search
public List<Patient> findPatient() {
ArrayList<Patient> retVal = new ArrayList<Patient>();
Patient patient = new Patient();
patient.setId("1");
patient.addIdentifier().setSystem("system").setValue("identifier123");
retVal.add(patient);
return retVal;
}
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
}
}

View File

@ -196,7 +196,7 @@ public class ContainedResourceEncodingTest {
List<IResource> list = new ArrayList<IResource>();
list.add(dr);
Bundle bundle = RestfulServer.createBundleFromResourceList(new FhirContext(), null, list, null, null, 0);
Bundle bundle = RestfulServer.createBundleFromResourceList(new FhirContext(), null, list, null, null, 0, null);
IParser parser = this.ctx.newXmlParser().setPrettyPrint(true);
String xml = parser.encodeBundleToString(bundle);
@ -235,7 +235,7 @@ public class ContainedResourceEncodingTest {
List<IResource> list = new ArrayList<IResource>();
list.add(dr);
Bundle bundle = RestfulServer.createBundleFromResourceList(new FhirContext(), null, list, null, null, 0);
Bundle bundle = RestfulServer.createBundleFromResourceList(new FhirContext(), null, list, null, null, 0, null);
IParser parser = this.ctx.newXmlParser().setPrettyPrint(true);
String xml = parser.encodeBundleToString(bundle);

View File

@ -1,6 +1,8 @@
package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@ -30,7 +32,6 @@ import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Matchers;
import org.xml.sax.SAXException;
import ca.uhn.fhir.context.ConfigurationException;
@ -277,6 +278,7 @@ public class XmlParserTest {
}
@Test
public void testEncodeContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,7 @@ 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.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.annotations.ResourceDef;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@ -70,6 +71,7 @@ public class CreateTest {
assertEquals(201, status.getStatusLine().getStatusCode());
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("location").getValue());
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), StringContains.containsString("UTF-8"));
}

View File

@ -89,6 +89,25 @@ public class RestfulServerMethodTest {
private static Server ourServer;
private static RestfulServer ourRestfulServer;
@Test
public void testCreateBundleDoesntCreateDoubleEntries() {
List<IResource> resources = new ArrayList<IResource>();
Patient p = new Patient();
p.setId("Patient/1");
resources.add(p);
Organization o = new Organization();
o.setId("Organization/2");
resources.add(o);
p.getManagingOrganization().setResource(o);
Bundle bundle = RestfulServer.createBundleFromResourceList(ourCtx, "", resources, "http://foo", "http://foo", 2, null);
assertEquals(2, bundle.getEntries().size());
}
@Test
public void test404IsPropagatedCorrectly() throws Exception {