Lots of tester work

This commit is contained in:
jamesagnew 2014-06-27 18:28:27 -04:00
parent 50d68d6090
commit f87c50b4b4
24 changed files with 1046 additions and 3989 deletions

View File

@ -217,14 +217,6 @@ public class Bundle extends BaseBundle /* implements IElement */{
entry.setResource(theResource);
entry.setResource(theResource);
TagList list = (TagList) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
if (list != null) {
for (Tag tag : list) {
if (StringUtils.isNotBlank(tag.getTerm())) {
entry.addCategory().setTerm(tag.getTerm()).setLabel(tag.getLabel()).setScheme(tag.getScheme());
}
}
}
RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);

View File

@ -404,8 +404,7 @@ public class IdDt extends BasePrimitive<String> {
* @deprecated Use {@link #getIdPartAsBigDecimal()} instead
*/
public BigDecimal asBigDecimal() {
// TODO Auto-generated method stub
return null;
return getIdPartAsBigDecimal();
}
}

View File

@ -177,7 +177,7 @@ public abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding
}
invokeServerMethod(params);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
theResponse.setContentType(responseEncoding.getResourceContentType());
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);

View File

@ -102,7 +102,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
public Set<String> getIncludes() {
Set<String> retVal =new TreeSet<String>();
Set<String> retVal = new TreeSet<String>();
for (IParameter next : myParameters) {
if (next instanceof IncludeParameter) {
retVal.addAll(((IncludeParameter) next).getAllow());
@ -110,7 +110,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
return retVal;
}
public FhirContext getContext() {
return myContext;
}
@ -128,8 +128,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
/**
* Returns the name of the resource this method handles, or <code>null</code> if this method is not resource
* specific
* Returns the name of the resource this method handles, or <code>null</code> if this method is not resource specific
*/
public abstract String getResourceName();
@ -265,14 +264,16 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
if (theProvider instanceof IResourceProvider) {
returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType();
if (!verifyIsValidResourceReturnType(returnTypeFromRp)) {
throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned " + toLogString(returnTypeFromRp) + " - Must return a resource type");
throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned "
+ toLogString(returnTypeFromRp) + " - Must return a resource type");
}
}
Class<?> returnTypeFromMethod = theMethod.getReturnType();
if (getTags != null) {
if (!TagList.class.equals(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from type " + theMethod.getDeclaringClass().getCanonicalName() + " is annotated with @" + GetTags.class.getSimpleName() + " but does not return type " + TagList.class.getName());
throw new ConfigurationException("Method '" + theMethod.getName() + "' from type " + theMethod.getDeclaringClass().getCanonicalName() + " is annotated with @"
+ GetTags.class.getSimpleName() + " but does not return type " + TagList.class.getName());
}
} else if (MethodOutcome.class.equals(returnTypeFromMethod)) {
// returns a method outcome
@ -285,13 +286,15 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !IResource.class.equals(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns a collection with generic type " + toLogString(returnTypeFromMethod)
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
+ " returns a collection with generic type " + toLogString(returnTypeFromMethod)
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> )");
}
} else {
if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromMethod)
+ " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
+ " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", "
+ IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
}
}
@ -321,12 +324,13 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
if (returnTypeFromRp != null) {
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName()
+ " (or a subclass of it) per IResourceProvider contract");
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type "
+ returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract");
}
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type " + returnTypeFromAnnotation.getCanonicalName() + " per method annotation - Must return "
+ returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract");
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type "
+ returnTypeFromAnnotation.getCanonicalName() + " per method annotation - Must return " + returnTypeFromRp.getCanonicalName()
+ " (or a subclass of it) per IResourceProvider contract");
}
returnType = returnTypeFromAnnotation;
} else {
@ -335,8 +339,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
} else {
if (returnTypeFromAnnotation != IResource.class) {
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation)
+ " according to annotation - Must return a resource type");
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type "
+ theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type");
}
returnType = returnTypeFromAnnotation;
} else {
@ -402,8 +406,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
if (obj1 == null) {
obj1 = object;
} else {
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @" + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName()
+ ". Can not have both.");
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @"
+ obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName() + ". Can not have both.");
}
}

View File

@ -118,8 +118,7 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
TagList tagList = new TagList();
for (Enumeration<String> enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) {
String nextTagComplete = enumeration.nextElement();
StringBuilder next = new StringBuilder(nextTagComplete);
parseTagValue(tagList, nextTagComplete, next);
parseTagValue(tagList, nextTagComplete);
}
if (tagList.isEmpty() == false) {
resource.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
@ -136,12 +135,12 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
response = (MethodOutcome) invokeServerMethod(params);
} catch (InternalErrorException e) {
ourLog.error("Internal error during method invocation", e);
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
streamOperationOutcome(e, theServer, encoding, theResponse, theRequest);
return;
} catch (BaseServerResponseException e) {
ourLog.info("Exception during method invocation: " + e.getMessage());
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
streamOperationOutcome(e, theServer, encoding, theResponse, theRequest);
return;
}
@ -172,7 +171,7 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
theServer.addHeadersToResponse(theResponse);
if (response != null && response.getOperationOutcome() != null) {
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
theResponse.setContentType(encoding.getResourceContentType());
Writer writer = theResponse.getWriter();
IParser parser = encoding.newParser(getContext());
@ -191,6 +190,11 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
// getMethod().in
}
static void parseTagValue(TagList tagList, String nextTagComplete) {
StringBuilder next = new StringBuilder(nextTagComplete);
parseTagValue(tagList, nextTagComplete, next);
}
/**
* @throws IOException
*/
@ -264,7 +268,7 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
theResponse.addHeader("Location", b.toString());
}
private void parseTagValue(TagList theTagList, String theCompleteHeaderValue, StringBuilder theBuffer) {
private static void parseTagValue(TagList theTagList, String theCompleteHeaderValue, StringBuilder theBuffer) {
int firstSemicolon = theBuffer.indexOf(";");
int deleteTo;
if (firstSemicolon == -1) {

View File

@ -196,7 +196,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
NarrativeModeEnum narrativeMode = RestfulServer.determineNarrativeMode(theRequest);
// Determine response encoding
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
// Is this request coming from a browser
String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
@ -229,69 +229,11 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
} else if (result.size() > 1) {
throw new InternalErrorException("Method returned multiple resources");
}
streamResponseAsResource(theServer, theResponse, result.getResources(0, 1).get(0), responseEncoding, prettyPrint, requestIsBrowser, narrativeMode);
RestfulServer.streamResponseAsResource(theServer, theResponse, result.getResources(0, 1).get(0), responseEncoding, prettyPrint, requestIsBrowser, narrativeMode);
break;
}
}
private void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode) throws IOException {
theHttpResponse.setStatus(200);
if (theResource instanceof Binary) {
Binary bin = (Binary) theResource;
if (isNotBlank(bin.getContentType())) {
theHttpResponse.setContentType(bin.getContentType());
} else {
theHttpResponse.setContentType(Constants.CT_OCTET_STREAM);
}
if (bin.getContent() == null || bin.getContent().length == 0) {
return;
}
theHttpResponse.setContentLength(bin.getContent().length);
ServletOutputStream oos = theHttpResponse.getOutputStream();
oos.write(bin.getContent());
oos.close();
return;
}
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
theHttpResponse.setContentType(theResponseEncoding.getBrowserFriendlyBundleContentType());
} else if (theNarrativeMode == NarrativeModeEnum.ONLY) {
theHttpResponse.setContentType(Constants.CT_HTML);
} else {
theHttpResponse.setContentType(theResponseEncoding.getResourceContentType());
}
theHttpResponse.setCharacterEncoding(Constants.CHARSET_UTF_8);
theServer.addHeadersToResponse(theHttpResponse);
InstantDt lastUpdated = ResourceMetadataKeyEnum.UPDATED.get(theResource);
if (lastUpdated != null) {
theHttpResponse.addHeader(Constants.HEADER_LAST_MODIFIED, lastUpdated.getValueAsString());
}
TagList list = (TagList) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
if (list != null) {
for (Tag tag : list) {
if (StringUtils.isNotBlank(tag.getTerm())) {
theHttpResponse.addHeader(Constants.HEADER_CATEGORY, tag.toHeaderValue());
}
}
}
PrintWriter writer = theHttpResponse.getWriter();
try {
if (theNarrativeMode == NarrativeModeEnum.ONLY) {
writer.append(theResource.getText().getDiv().getValueAsString());
} else {
RestfulServer.getNewParser(theServer.getFhirContext(), theResponseEncoding, thePrettyPrint, theNarrativeMode).encodeResourceToWriter(theResource, writer);
}
} finally {
writer.close();
}
}
/**
* Subclasses may override

View File

@ -157,7 +157,7 @@ public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
TagList resp = (TagList) invokeServerMethod(params);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
theResponse.setContentType(responseEncoding.getResourceContentType());
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);

View File

@ -130,7 +130,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
@Override
protected Object parseRequestObject(Request theRequest) throws IOException {
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
IParser parser = encoding.newParser(getContext());
Bundle bundle = parser.parseBundle(theRequest.getServletRequest().getReader());
return bundle;

View File

@ -22,8 +22,10 @@ package ca.uhn.fhir.rest.param;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import ca.uhn.fhir.context.ConfigurationException;
@ -38,12 +40,8 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class IncludeParameter extends BaseQueryParameter {
private Set<String> myAllow;
private Class<? extends Collection<Include>> myInstantiableCollectionType;
private HashSet<String> myAllow;
public HashSet<String> getAllow() {
return myAllow;
}
private Class<?> mySpecType;
public IncludeParameter(IncludeParam theAnnotation, Class<? extends Collection<Include>> theInstantiableCollectionType, Class<?> theSpecType) {
@ -51,8 +49,12 @@ public class IncludeParameter extends BaseQueryParameter {
if (theAnnotation.allow().length > 0) {
myAllow = new HashSet<String>();
for (String next : theAnnotation.allow()) {
myAllow.add(next);
if (next != null) {
myAllow.add(next);
}
}
} else {
myAllow = Collections.emptySet();
}
mySpecType = theSpecType;
@ -70,7 +72,7 @@ public class IncludeParameter extends BaseQueryParameter {
if (myInstantiableCollectionType == null) {
if (mySpecType == Include.class) {
retVal.add(QualifiedParamList.singleton(((Include) theObject).getValue()));
}else if (mySpecType == PathSpecification.class) {
} else if (mySpecType == PathSpecification.class) {
retVal.add(QualifiedParamList.singleton(((PathSpecification) theObject).getValue()));
} else {
retVal.add(QualifiedParamList.singleton(((String) theObject)));
@ -85,11 +87,30 @@ public class IncludeParameter extends BaseQueryParameter {
return retVal;
}
public Set<String> getAllow() {
return myAllow;
}
@Override
public String getName() {
return "_include";
}
@Override
public SearchParamTypeEnum getParamType() {
return null;
}
@Override
public boolean handlesMissing() {
return true;
}
@Override
public boolean isRequired() {
return false;
}
@Override
public Object parse(List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
Collection<Include> retValCollection = null;
@ -135,19 +156,4 @@ public class IncludeParameter extends BaseQueryParameter {
return retValCollection;
}
@Override
public boolean isRequired() {
return false;
}
@Override
public SearchParamTypeEnum getParamType() {
return null;
}
@Override
public boolean handlesMissing() {
return true;
}
}

View File

@ -74,6 +74,8 @@ public class ServerConformanceProvider {
}
Conformance retVal = new Conformance();
retVal.getImplementation().setDescription(myRestfulServer.getImplementationDescription());
retVal.getSoftware().setName(myRestfulServer.getServerName());
retVal.getSoftware().setVersion(myRestfulServer.getServerVersion());
retVal.addFormat(Constants.CT_FHIR_XML);

View File

@ -204,7 +204,6 @@ public class RestfulTesterServlet extends HttpServlet {
myIdToServerName.put(theId, theDisplayName);
}
private RuntimeResourceDefinition getResourceType(HttpServletRequest theReq) throws ServletException {
String resourceName = StringUtils.defaultString(theReq.getParameter(PARAM_RESOURCE));
RuntimeResourceDefinition def = myCtx.getResourceDefinition(resourceName);
@ -469,7 +468,7 @@ public class RestfulTesterServlet extends HttpServlet {
requestBody = IOUtils.toString(entity.getContent());
}
}
HttpResponse lastResponse = client.getLastResponse();
ContentType ct = lastResponse != null ? ContentType.get(lastResponse.getEntity()) : null;
String mimeType = ct != null ? ct.getMimeType() : null;
@ -537,7 +536,7 @@ public class RestfulTesterServlet extends HttpServlet {
if (isBlank(nextName)) {
return false;
}
String nextQualifier = StringUtils.defaultString(theReq.getParameter("param." + paramIdxString + ".qualifier"));
String nextType = theReq.getParameter("param." + paramIdxString + ".type");
@ -565,11 +564,11 @@ public class RestfulTesterServlet extends HttpServlet {
// }
theQuery.where(new StringParam(nextName + nextQualifier).matches().value(paramValue));
if (StringUtils.isNotBlank(theReq.getParameter("param." + paramIdxString + ".0.name"))) {
handleSearchParam(paramIdxString+".0", theReq, theQuery);
handleSearchParam(paramIdxString + ".0", theReq, theQuery);
}
return true;
}
@ -717,16 +716,24 @@ public class RestfulTesterServlet extends HttpServlet {
if (isBlank(serverId) && !myIdToServerBase.containsKey(serverId)) {
serverBase = myIdToServerBase.entrySet().iterator().next().getValue();
serverName = myIdToServerName.entrySet().iterator().next().getValue();
}else {
} else {
serverBase = myIdToServerBase.get(serverId);
serverName = myIdToServerName.get(serverId);
}
IGenericClient client = myCtx.newRestfulGenericClient(serverBase);
Conformance conformance = client.conformance();
WebContext ctx = new WebContext(theReq, theResp, theReq.getServletContext(), theReq.getLocale());
Conformance conformance;
try {
conformance = client.conformance();
} catch (Exception e) {
ourLog.warn("Failed to load conformance statement", e);
ctx.getVariables().put("errorMsg", "Failed to load conformance statement, error was: " + e.toString());
conformance = new Conformance();
}
Map<String, Number> resourceCounts = new HashMap<String, Number>();
long total = 0;
for (Rest nextRest : conformance.getRest()) {

View File

@ -135,12 +135,17 @@
function doAction(source, action, resourceName) {
var abtn = $('<input />', { type: 'hidden', name: 'action', value: action });
$(source).append(abtn);
var resource = $('#resource');
if (resourceName != null) {
var rbtn = $('<input />', { type: 'hidden', name: 'resource', value: resourceName });
$(source).append(rbtn);
var input = $('#resource');
if (resource.length) {
resource.val(resourceName);
} else {
var rbtn = $('<input />', { type: 'hidden', name: 'resource', value: resourceName });
$(source).append(rbtn);
}
} else {
var resource = $('#resource');
if (resource) {
if (resource.length) {
resource.val('');
}
}
@ -199,23 +204,30 @@
<div class="well">
This is a RESTful server tester, which can be used to send
requests to, and receive responses from the server at the
following URL: <a href="http://foo.com/fhir" th:href="${base}"
th:text="${base}">http://foo.com/fhir</a>
following URL:
</div>
<table class="table table-bordered table-striped">
<table class="table table-bordered table-striped" th:if="${resourceName.empty}">
<colgroup>
<col class="col-xs-1" />
<col class="col-xs-7" />
</colgroup>
<tbody>
<tr>
<td>Software</td>
<td th:text="${conf.software.name}">HAPI Restful Server</td>
<tr th:if="#{!string.isEmpty(conf.implementation.description)}">
<td>Server</td>
<td th:utext="${conf.implementation.description}">HAPI Restful Server</td>
</tr>
<tr>
<td>Version</td>
<td th:text="${conf.software.version}">1.1.1</td>
<td>FHIR Base</td>
<td>
<a th:href="${base}" th:text="${base}"></a>
</td>
</tr>
<tr th:if="#{!string.isEmpty(conf.software.name)} and #{!string.isEmpty(conf.software.version)}">
<td>Software</td>
<td>
<th:block th:utext="${conf.software.name}"/> - <th:block th:utext="${conf.software.version}"/>
</td>
</tr>
</tbody>
</table>
@ -838,7 +850,8 @@
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
<i id="collapseOneIcon" class="fa fa-minus-square-o"></i>
<span th:text="'Bundle contains ' + ${bundle.totalResults.value} + ' entries'"/>
<span th:if="${bundle.totalResults.empty}" th:text="'Bundle contains ' + ${bundle.entries.size} + ' entries'"/>
<span th:unless="${bundle.totalResults.empty}" th:text="'Bundle contains ' + ${bundle.entries.size} + ' / ' + ${bundle.totalResults.value} + ' entries'"/>
</a>
<!-- Prev/Next Page Buttons -->
@ -887,8 +900,8 @@
<tbody>
<tr th:each="entry : ${bundle.entries}">
<td>
<button class="btn btn-primary btn-xs" th:onclick="'readFromEntriesTable(this, \'' + ${entry.resource.id.resourceType} + '\', \'' + ${entry.resource.id.idPart} + '\', \'' + ${entry.resource.id.versionIdPart} + '\');'" type="submit" name="action" value="read">Read</button>
<button class="btn btn-primary btn-xs" th:onclick="'updateFromEntriesTable(this, \'' + ${entry.resource.id.resourceType} + '\', \'' + ${entry.resource.id.idPart} + '\', \'' + ${entry.resource.id.versionIdPart} + '\');'" type="submit" name="action" value="home">Update</button>
<button class="btn btn-primary btn-xs" th:onclick="'readFromEntriesTable(this, \'' + ${entry.resource.id.resourceType} + '\', \'' + ${entry.resource.id.idPart} + '\', \'' + ${#strings.defaultString(entry.resource.id.versionIdPart,'')} + '\');'" type="submit" name="action" value="read">Read</button>
<button class="btn btn-primary btn-xs" th:onclick="'updateFromEntriesTable(this, \'' + ${entry.resource.id.resourceType} + '\', \'' + ${entry.resource.id.idPart} + '\', \'' + ${#strings.defaultString(entry.resource.id.versionIdPart, '')} + '\');'" type="submit" name="action" value="home">Update</button>
</td>
<td th:text="${entry.title}">
</td>
@ -898,28 +911,6 @@
</tr>
</tbody>
</table>
<script type="text/javascript">
function readFromEntriesTable(source, type, id, vid) {
var btn = $(source);
var resId = source.resourceid;
btn.append($('<input />', { type: 'hidden', name: 'id', value: id }));
var resVid = source.resourcevid;
if (resVid != '') {
btn.append($('<input />', { type: 'hidden', name: 'vid', value: vid }));
}
btn.append($('<input />', { type: 'hidden', name: 'resource', value: type }));
}
function updateFromEntriesTable(source, type, id, vid) {
var btn = $(source);
var resId = source.resourceid;
btn.append($('<input />', { type: 'hidden', name: 'update-id', value: id }));
var resVid = source.resourcevid;
if (resVid != '') {
btn.append($('<input />', { type: 'hidden', name: 'update-vid', value: vid }));
}
btn.append($('<input />', { type: 'hidden', name: 'resource', value: type }));
}
</script>
</div>
</div>
<script type="text/javascript">

View File

@ -232,8 +232,16 @@ PRE.resultBodyPlaceholder {
DIV.searchParamDescription {
font-size: 0.8em;
text-align: justify;
color: #668;
text-align: right;
color: #668;
min-height: 34px;
display: table;
width: 100%;
}
DIV.searchParamDescription DIV {
display: table-cell;
vertical-align: middle;
}
DIV.searchParamSeparator {

View File

@ -45,9 +45,10 @@ function addSearchParamRow() {
if (restResource.searchParam) {
for (var i = 0; i < restResource.searchParam.length; i++) {
var searchParam = restResource.searchParam[i];
params['_' + searchParam.name] = searchParam;
var nextName = searchParam.name + '_' + i;
params[nextName] = searchParam;
select.append(
$('<option />', { value: searchParam.name }).text(searchParam.name + ' - ' + searchParam.documentation)
$('<option />', { value: nextName }).text(searchParam.name + ' - ' + searchParam.documentation)
);
if (restResource._searchParam && restResource._searchParam[i] != null) {
@ -84,7 +85,11 @@ function addSearchControls(searchParam, searchParamName, containerRowNum, rowNum
$('#search-param-rowopts-' + containerRowNum).append(
$('<br clear="all"/>'),
$('<div class="searchParamSeparator"/>'),
$('<div />', { 'class': 'col-sm-6 searchParamDescription' }).text(searchParam.documentation)
$('<div />', { 'class': 'col-sm-6' }).append(
$('<div class="searchParamDescription"/>').append(
$('<div />').text(searchParam.documentation)
)
)
);
}
@ -180,7 +185,7 @@ function handleSearchParamTypeChange(select, params, rowNum) {
return;
}
$('#search-param-rowopts-' + rowNum).empty();
var searchParam = params['_' + newVal];
var searchParam = params[newVal];
$('#search-param-rowopts-' + rowNum).append(
$('<input />', { name: 'param.' + rowNum + '.type', type: 'hidden', value: searchParam.type })
);
@ -190,6 +195,37 @@ function handleSearchParamTypeChange(select, params, rowNum) {
select.prevVal = newVal;
}
/*
* Handler for "read" button which appears on each entry in the
* summary at the top of a Bundle response view
*/
function readFromEntriesTable(source, type, id, vid) {
var btn = $(source);
var resId = source.resourceid;
btn.append($('<input />', { type: 'hidden', name: 'id', value: id }));
var resVid = source.resourcevid;
if (resVid != '') {
btn.append($('<input />', { type: 'hidden', name: 'vid', value: vid }));
}
btn.append($('<input />', { type: 'hidden', name: 'resource', value: type }));
}
/*
* Handler for "update" button which appears on each entry in the
* summary at the top of a Bundle response view
*/
function updateFromEntriesTable(source, type, id, vid) {
var btn = $(source);
var resId = source.resourceid;
btn.append($('<input />', { type: 'hidden', name: 'update-id', value: id }));
var resVid = source.resourcevid;
if (resVid != '') {
btn.append($('<input />', { type: 'hidden', name: 'update-vid', value: vid }));
}
btn.append($('<input />', { type: 'hidden', name: 'resource', value: type }));
}
function selectServer(serverId) {
$('#server-id').val(serverId);
$('#outerForm').append(

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.model.primitive;
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import org.junit.BeforeClass;
import org.junit.Test;
@ -29,6 +31,15 @@ public class IdDtTest {
}
@Test
public void testBigDecimalIds() {
IdDt id = new IdDt(new BigDecimal("123"));
assertEquals(id.asBigDecimal(), new BigDecimal("123"));
assertEquals(id.getIdPartAsBigDecimal(), new BigDecimal("123"));
}
@Test
public void testParseValueAbsoluteWithVersion() {
Patient patient = new Patient();

View File

@ -0,0 +1,196 @@
package ca.uhn.fhir.rest.method;
import static org.junit.Assert.*;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.TagList;
public class BaseOutcomeReturningMethodBindingTest {
@Test
public void testParseTagHeader() {
String headerString = "http://britsystems.com/fhir/tag/4567; scheme=\"http://britsystems.com/fhir\"; label=\"Tag-4567\",http://client/scheme/tag/123; scheme=\"http://client/scheme\"; label=\"tag 123\",http://client/scheme/tag/456; scheme=\"http://client/scheme\"; label=\"tag 456\",http://fhir.healthintersections.com.au/open/Patient/1; scheme=\"http://hl7.org/fhir/tag\"; label=\"GET <host>/<resourceType>/<id>\",http://hl7.fhir/example; scheme=\"http://hl7.org/fhir/tag\"; label=\"FHIR example\",http://hl7.org/fhir/sid/us-ssn; scheme=\"http://hl7.org/fhir/tag\"; label=\"POST <host>/<resourceType>\",http://hl7.org/fhir/tools/tag/test; scheme=\"http://hl7.org/fhir/tag\"; label=\"Test Tag\",http://hl7.org/implement/standards/fhir/v3/ActCode/InformationSensitivityPolicy#GDIS; scheme=\"http://hl7.org/fhir/tag\"; label=\"GDIS\",http://hl7.org/implement/standards/fhir/v3/Confidentiality#N; scheme=\"http://hl7.org/fhir/tag\"; label=\"N (Normal)\",http://hl7.org/implement/standards/fhir/v3/Confidentiality#R; scheme=\"http://hl7.org/fhir/tag\"; label=\"restricted\",http://nu.nl/testname; scheme=\"http://hl7.org/fhir/tag\"; label=\"TestCreateEditDelete\",http://readtag.nu.nl; scheme=\"http://hl7.org/fhir/tag\"; label=\"readTagTest\",http://spark.furore.com/fhir; scheme=\"http://hl7.org/fhir/tag\"; label=\"GET <host>/<resourceType>/<id>\",http://www.healthintersections.com.au/fhir/tags/invalid; scheme=\"http://hl7.org/fhir/tag\"; label=\"Non-conformant Resource\",urn:happytag; scheme=\"http://hl7.org/fhir/tag\"; label=\"This is a happy resource\",condition; scheme=\"http://hl7.org/fhir/tag/profile\"; label=\"Profile condition\",device; scheme=\"http://hl7.org/fhir/tag/profile\"; label=\"Profile device\",http://fhir.healthintersections.com.au/open/Profile/condition; scheme=\"http://hl7.org/fhir/tag/profile\"; label=\"Profile condition\",http://fhir.healthintersections.com.au/open/Profile/device; scheme=\"http://hl7.org/fhir/tag/profile\"; label=\"Profile device\",http://hl7.org/fhir/v3/ActCode#CEL; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Celebrity / VIP\",http://hl7.org/fhir/v3/ActCode#DEMO; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Contact/Employment Confidential\",http://hl7.org/fhir/v3/ActCode#DIA; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Diagnosis is/would be Confidential\",http://hl7.org/fhir/v3/ActCode#EMP; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Employee / Staff member\",http://hl7.org/fhir/v3/ActCode#ORCON; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Author only\",http://hl7.org/fhir/v3/ActCode#TABOO; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Patient/Carer Only\",http://hl7.org/fhir/v3/Confidentiality#L; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = Low\",http://hl7.org/fhir/v3/Confidentiality#M; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = Moderate\",http://hl7.org/fhir/v3/Confidentiality#N; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = Normal\",http://hl7.org/fhir/v3/Confidentiality#R; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = Restricted\",http://hl7.org/fhir/v3/Confidentiality#U; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = none\",http://hl7.org/fhir/v3/Confidentiality#V; scheme=\"http://hl7.org/fhir/tag/security\"; label=\"Confidentiality = Very Restricted\",http://term.com; scheme=\"http://scheme.com\"; label=\"Some good ole term\"";
TagList parsedFromHeader = new TagList();
BaseOutcomeReturningMethodBinding.parseTagValue(parsedFromHeader, headerString);
//@formatter:off
String resourceString = "{\n" +
" \"resourceType\" : \"TagList\",\n" +
" \"category\" : [\n" +
" {\n" +
" \"scheme\" : \"http://britsystems.com/fhir\",\n" +
" \"term\" : \"http://britsystems.com/fhir/tag/4567\",\n" +
" \"label\" : \"Tag-4567\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://client/scheme\",\n" +
" \"term\" : \"http://client/scheme/tag/123\",\n" +
" \"label\" : \"tag 123\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://client/scheme\",\n" +
" \"term\" : \"http://client/scheme/tag/456\",\n" +
" \"label\" : \"tag 456\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://fhir.healthintersections.com.au/open/Patient/1\",\n" +
" \"label\" : \"GET <host>/<resourceType>/<id>\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.fhir/example\",\n" +
" \"label\" : \"FHIR example\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.org/fhir/sid/us-ssn\",\n" +
" \"label\" : \"POST <host>/<resourceType>\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.org/fhir/tools/tag/test\",\n" +
" \"label\" : \"Test Tag\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.org/implement/standards/fhir/v3/ActCode/InformationSensitivityPolicy#GDIS\",\n" +
" \"label\" : \"GDIS\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.org/implement/standards/fhir/v3/Confidentiality#N\",\n" +
" \"label\" : \"N (Normal)\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://hl7.org/implement/standards/fhir/v3/Confidentiality#R\",\n" +
" \"label\" : \"restricted\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://nu.nl/testname\",\n" +
" \"label\" : \"TestCreateEditDelete\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://readtag.nu.nl\",\n" +
" \"label\" : \"readTagTest\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://spark.furore.com/fhir\",\n" +
" \"label\" : \"GET <host>/<resourceType>/<id>\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"http://www.healthintersections.com.au/fhir/tags/invalid\",\n" +
" \"label\" : \"Non-conformant Resource\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag\",\n" +
" \"term\" : \"urn:happytag\",\n" +
" \"label\" : \"This is a happy resource\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/profile\",\n" +
" \"term\" : \"condition\",\n" +
" \"label\" : \"Profile condition\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/profile\",\n" +
" \"term\" : \"device\",\n" +
" \"label\" : \"Profile device\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/profile\",\n" +
" \"term\" : \"http://fhir.healthintersections.com.au/open/Profile/condition\",\n" +
" \"label\" : \"Profile condition\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/profile\",\n" +
" \"term\" : \"http://fhir.healthintersections.com.au/open/Profile/device\",\n" +
" \"label\" : \"Profile device\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#CEL\",\n" +
" \"label\" : \"Celebrity / VIP\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#DEMO\",\n" +
" \"label\" : \"Contact/Employment Confidential\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#DIA\",\n" +
" \"label\" : \"Diagnosis is/would be Confidential\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#EMP\",\n" +
" \"label\" : \"Employee / Staff member\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#ORCON\",\n" +
" \"label\" : \"Author only\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/ActCode#TABOO\",\n" +
" \"label\" : \"Patient/Carer Only\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#L\",\n" +
" \"label\" : \"Confidentiality = Low\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#M\",\n" +
" \"label\" : \"Confidentiality = Moderate\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#N\",\n" +
" \"label\" : \"Confidentiality = Normal\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#R\",\n" +
" \"label\" : \"Confidentiality = Restricted\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#U\",\n" +
" \"label\" : \"Confidentiality = none\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://hl7.org/fhir/tag/security\",\n" +
" \"term\" : \"http://hl7.org/fhir/v3/Confidentiality#V\",\n" +
" \"label\" : \"Confidentiality = Very Restricted\"\n" +
" },\n" +
" {\n" +
" \"scheme\" : \"http://scheme.com\",\n" +
" \"term\" : \"http://term.com\",\n" +
" \"label\" : \"Some good ole term\"\n" +
" }\n" +
" ]\n" +
"}";
//@formatter:on
TagList parsedFromResource = new FhirContext().newJsonParser().parseTagList(resourceString);
assertEquals(parsedFromHeader.size(), parsedFromResource.size());
for (int i = 0; i < parsedFromHeader.size(); i++) {
assertEquals(parsedFromHeader.get(i), parsedFromResource.get(i));
}
}
}

View File

@ -0,0 +1,114 @@
package ca.uhn.fhir.rest.server;
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.client.methods.HttpGet;
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.hamcrest.core.StringContains;
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.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class ExceptionTest {
private static CloseableHttpClient ourClient;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionTest.class);
private static int ourPort;
private static Server ourServer;
private static RestfulServer servlet;
@Test
public void testSearchNormalMatch() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?throwInternalError=aaa");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
OperationOutcome oo = (OperationOutcome) servlet.getFhirContext().newXmlParser().parseResource(responseContent);
assertThat(oo.getIssueFirstRep().getDetails().getValue(), StringContains.containsString("InternalErrorException: Exception Text"));
}
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?throwInternalError=aaa&_format=json");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
OperationOutcome oo = (OperationOutcome) servlet.getFhirContext().newJsonParser().parseResource(responseContent);
assertThat(oo.getIssueFirstRep().getDetails().getValue(), StringContains.containsString("InternalErrorException: Exception Text"));
}
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
ServletHandler proxyHandler = new ServletHandler();
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();
}
/**
* Created by dsotnikov on 2/25/2014.
*/
public static class DummyPatientResourceProvider implements IResourceProvider {
@Search
public List<Patient> findPatient(@RequiredParam(name = "throwInternalError") StringParam theParam) {
throw new InternalErrorException("Exception Text");
}
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
}
}

View File

@ -37,6 +37,17 @@ public class StringParameterTest {
private static int ourPort;
private static Server ourServer;
@Test
public void testSearchWithFormatAndPretty() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=aaa&_format=xml&_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(1, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
}
}
@Test
public void testSearchNormalMatch() throws Exception {
{

File diff suppressed because it is too large Load Diff

View File

@ -776,9 +776,10 @@ public abstract class BaseFhirDao {
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.VERSION_ID, theEntity.getVersion());
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, theEntity.getPublished());
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.UPDATED, theEntity.getUpdated());
if (theEntity.getTags().size() > 0) {
Collection<? extends BaseTag> tags = theEntity.getTags();
if (tags.size() > 0) {
TagList tagList = new TagList();
for (BaseTag next : theEntity.getTags()) {
for (BaseTag next : tags) {
tagList.add(new Tag(next.getTag().getScheme(), next.getTag().getTerm(), next.getTag().getLabel()));
}
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);

View File

@ -75,6 +75,7 @@ public class JpaTestApp {
restServer.setResourceProviders(rp,patientRp, questionnaireRp, organizationRp);
restServer.setProviders(systemProvider);
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
restServer.setImplementationDescription("This is a great server!!!!");
JpaConformanceProvider confProvider = new JpaConformanceProvider(restServer, systemDao);
restServer.setServerConformanceProvider(confProvider);
@ -157,6 +158,16 @@ public class JpaTestApp {
return null;
}
@Search
public List<DiagnosticReport> findDiagnosticReportsByPatientIssued (
@RequiredParam(name=DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) IdentifierDt thePatientId,
@OptionalParam(name=DiagnosticReport.SP_NAME) CodingListParam theNames,
@OptionalParam(name=DiagnosticReport.SP_ISSUED) DateRangeParam theDateRange,
@IncludeParam(allow= {"DiagnosticReport.result"}) Set<Include> theIncludes
) throws Exception {
return null;
}
@Override
public Class<? extends IResource> getResourceType() {
return DiagnosticReport.class;

View File

@ -8,7 +8,11 @@ public class TesterServlet extends RestfulTesterServlet {
public TesterServlet() {
String baseUrl = System.getProperty("fhir.baseurl");
setServerBase(baseUrl);
addServerBase("fhirtest", "UHN/HAPI Test Server", baseUrl);
addServerBase("hi", "Health Intersections Ref Server", "http://fhir.healthintersections.com.au/open");
addServerBase("furore", "Spark - Furore Ref Server", "http://spark.furore.com/fhir");
addServerBase("blaze", "Blaze (Orion Health)", "https://his-medicomp-gateway.orionhealth.com/blaze/fhir");
}
}

View File

@ -19,6 +19,10 @@
<servlet-name>fhirServlet</servlet-name>
<url-pattern>/base/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>fhirServlet</servlet-name>
<url-pattern>/base</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>testerServlet</servlet-name>