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);
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); RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);

View File

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

View File

@ -177,7 +177,7 @@ public abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding
} }
invokeServerMethod(params); invokeServerMethod(params);
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest); EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
theResponse.setContentType(responseEncoding.getResourceContentType()); theResponse.setContentType(responseEncoding.getResourceContentType());
theResponse.setStatus(Constants.STATUS_HTTP_200_OK); 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() { public Set<String> getIncludes() {
Set<String> retVal =new TreeSet<String>(); Set<String> retVal = new TreeSet<String>();
for (IParameter next : myParameters) { for (IParameter next : myParameters) {
if (next instanceof IncludeParameter) { if (next instanceof IncludeParameter) {
retVal.addAll(((IncludeParameter) next).getAllow()); retVal.addAll(((IncludeParameter) next).getAllow());
@ -110,7 +110,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
} }
return retVal; return retVal;
} }
public FhirContext getContext() { public FhirContext getContext() {
return myContext; 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 * Returns the name of the resource this method handles, or <code>null</code> if this method is not resource specific
* specific
*/ */
public abstract String getResourceName(); public abstract String getResourceName();
@ -265,14 +264,16 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
if (theProvider instanceof IResourceProvider) { if (theProvider instanceof IResourceProvider) {
returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType(); returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType();
if (!verifyIsValidResourceReturnType(returnTypeFromRp)) { 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(); Class<?> returnTypeFromMethod = theMethod.getReturnType();
if (getTags != null) { if (getTags != null) {
if (!TagList.class.equals(returnTypeFromMethod)) { 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)) { } else if (MethodOutcome.class.equals(returnTypeFromMethod)) {
// returns a method outcome // returns a method outcome
@ -285,13 +286,15 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) { } else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod); returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !IResource.class.equals(returnTypeFromMethod)) { 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> )"); + " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> )");
} }
} else { } else {
if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) { if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromMethod) throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
+ " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)"); + " 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 (returnTypeFromRp != null) {
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) { if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) { if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type "
+ " (or a subclass of it) per IResourceProvider contract"); + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract");
} }
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) { 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 " throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type "
+ returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract"); + returnTypeFromAnnotation.getCanonicalName() + " per method annotation - Must return " + returnTypeFromRp.getCanonicalName()
+ " (or a subclass of it) per IResourceProvider contract");
} }
returnType = returnTypeFromAnnotation; returnType = returnTypeFromAnnotation;
} else { } else {
@ -335,8 +339,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
} else { } else {
if (returnTypeFromAnnotation != IResource.class) { if (returnTypeFromAnnotation != IResource.class) {
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) { if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation) throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type "
+ " according to annotation - Must return a resource type"); + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type");
} }
returnType = returnTypeFromAnnotation; returnType = returnTypeFromAnnotation;
} else { } else {
@ -402,8 +406,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
if (obj1 == null) { if (obj1 == null) {
obj1 = object; obj1 = object;
} else { } else {
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @" + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName() throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @"
+ ". Can not have both."); + 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(); TagList tagList = new TagList();
for (Enumeration<String> enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) { for (Enumeration<String> enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) {
String nextTagComplete = enumeration.nextElement(); String nextTagComplete = enumeration.nextElement();
StringBuilder next = new StringBuilder(nextTagComplete); parseTagValue(tagList, nextTagComplete);
parseTagValue(tagList, nextTagComplete, next);
} }
if (tagList.isEmpty() == false) { if (tagList.isEmpty() == false) {
resource.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); resource.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
@ -136,12 +135,12 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
response = (MethodOutcome) invokeServerMethod(params); response = (MethodOutcome) invokeServerMethod(params);
} catch (InternalErrorException e) { } catch (InternalErrorException e) {
ourLog.error("Internal error during method invocation", 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); streamOperationOutcome(e, theServer, encoding, theResponse, theRequest);
return; return;
} catch (BaseServerResponseException e) { } catch (BaseServerResponseException e) {
ourLog.info("Exception during method invocation: " + e.getMessage()); 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); streamOperationOutcome(e, theServer, encoding, theResponse, theRequest);
return; return;
} }
@ -172,7 +171,7 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
theServer.addHeadersToResponse(theResponse); theServer.addHeadersToResponse(theResponse);
if (response != null && response.getOperationOutcome() != null) { if (response != null && response.getOperationOutcome() != null) {
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest); EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
theResponse.setContentType(encoding.getResourceContentType()); theResponse.setContentType(encoding.getResourceContentType());
Writer writer = theResponse.getWriter(); Writer writer = theResponse.getWriter();
IParser parser = encoding.newParser(getContext()); IParser parser = encoding.newParser(getContext());
@ -191,6 +190,11 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
// getMethod().in // getMethod().in
} }
static void parseTagValue(TagList tagList, String nextTagComplete) {
StringBuilder next = new StringBuilder(nextTagComplete);
parseTagValue(tagList, nextTagComplete, next);
}
/** /**
* @throws IOException * @throws IOException
*/ */
@ -264,7 +268,7 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
theResponse.addHeader("Location", b.toString()); 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 firstSemicolon = theBuffer.indexOf(";");
int deleteTo; int deleteTo;
if (firstSemicolon == -1) { if (firstSemicolon == -1) {

View File

@ -196,7 +196,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
NarrativeModeEnum narrativeMode = RestfulServer.determineNarrativeMode(theRequest); NarrativeModeEnum narrativeMode = RestfulServer.determineNarrativeMode(theRequest);
// Determine response encoding // Determine response encoding
EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest); EncodingEnum responseEncoding = RestfulServer.determineResponseEncoding(theRequest.getServletRequest());
// Is this request coming from a browser // Is this request coming from a browser
String uaHeader = theRequest.getServletRequest().getHeader("user-agent"); String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
@ -229,69 +229,11 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
} else if (result.size() > 1) { } else if (result.size() > 1) {
throw new InternalErrorException("Method returned multiple resources"); 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; 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 * Subclasses may override

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -45,9 +45,10 @@ function addSearchParamRow() {
if (restResource.searchParam) { if (restResource.searchParam) {
for (var i = 0; i < restResource.searchParam.length; i++) { for (var i = 0; i < restResource.searchParam.length; i++) {
var searchParam = restResource.searchParam[i]; var searchParam = restResource.searchParam[i];
params['_' + searchParam.name] = searchParam; var nextName = searchParam.name + '_' + i;
params[nextName] = searchParam;
select.append( 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) { if (restResource._searchParam && restResource._searchParam[i] != null) {
@ -84,7 +85,11 @@ function addSearchControls(searchParam, searchParamName, containerRowNum, rowNum
$('#search-param-rowopts-' + containerRowNum).append( $('#search-param-rowopts-' + containerRowNum).append(
$('<br clear="all"/>'), $('<br clear="all"/>'),
$('<div class="searchParamSeparator"/>'), $('<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; return;
} }
$('#search-param-rowopts-' + rowNum).empty(); $('#search-param-rowopts-' + rowNum).empty();
var searchParam = params['_' + newVal]; var searchParam = params[newVal];
$('#search-param-rowopts-' + rowNum).append( $('#search-param-rowopts-' + rowNum).append(
$('<input />', { name: 'param.' + rowNum + '.type', type: 'hidden', value: searchParam.type }) $('<input />', { name: 'param.' + rowNum + '.type', type: 'hidden', value: searchParam.type })
); );
@ -190,6 +195,37 @@ function handleSearchParamTypeChange(select, params, rowNum) {
select.prevVal = newVal; 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) { function selectServer(serverId) {
$('#server-id').val(serverId); $('#server-id').val(serverId);
$('#outerForm').append( $('#outerForm').append(

View File

@ -2,6 +2,8 @@ package ca.uhn.fhir.model.primitive;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; 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 @Test
public void testParseValueAbsoluteWithVersion() { public void testParseValueAbsoluteWithVersion() {
Patient patient = new Patient(); 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 int ourPort;
private static Server ourServer; 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 @Test
public void testSearchNormalMatch() throws Exception { 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.VERSION_ID, theEntity.getVersion());
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, theEntity.getPublished()); retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, theEntity.getPublished());
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.UPDATED, theEntity.getUpdated()); 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(); 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())); tagList.add(new Tag(next.getTag().getScheme(), next.getTag().getTerm(), next.getTag().getLabel()));
} }
retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); retVal.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);

View File

@ -75,6 +75,7 @@ public class JpaTestApp {
restServer.setResourceProviders(rp,patientRp, questionnaireRp, organizationRp); restServer.setResourceProviders(rp,patientRp, questionnaireRp, organizationRp);
restServer.setProviders(systemProvider); restServer.setProviders(systemProvider);
restServer.setPagingProvider(new FifoMemoryPagingProvider(10)); restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
restServer.setImplementationDescription("This is a great server!!!!");
JpaConformanceProvider confProvider = new JpaConformanceProvider(restServer, systemDao); JpaConformanceProvider confProvider = new JpaConformanceProvider(restServer, systemDao);
restServer.setServerConformanceProvider(confProvider); restServer.setServerConformanceProvider(confProvider);
@ -157,6 +158,16 @@ public class JpaTestApp {
return null; 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 @Override
public Class<? extends IResource> getResourceType() { public Class<? extends IResource> getResourceType() {
return DiagnosticReport.class; return DiagnosticReport.class;

View File

@ -8,7 +8,11 @@ public class TesterServlet extends RestfulTesterServlet {
public TesterServlet() { public TesterServlet() {
String baseUrl = System.getProperty("fhir.baseurl"); 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> <servlet-name>fhirServlet</servlet-name>
<url-pattern>/base/*</url-pattern> <url-pattern>/base/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>fhirServlet</servlet-name>
<url-pattern>/base</url-pattern>
</servlet-mapping>
<servlet-mapping> <servlet-mapping>
<servlet-name>testerServlet</servlet-name> <servlet-name>testerServlet</servlet-name>