More work on tester
This commit is contained in:
parent
63c9fb466c
commit
862b1bd79d
|
@ -125,7 +125,11 @@ public abstract class BaseClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return binding.invokeClient(mimeType, reader, response.getStatusLine().getStatusCode(), headers);
|
try {
|
||||||
|
return binding.invokeClient(mimeType, reader, response.getStatusLine().getStatusCode(), headers);
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
throw new FhirClientConnectionException(e);
|
throw new FhirClientConnectionException(e);
|
||||||
|
|
|
@ -69,7 +69,14 @@ public abstract class BaseClientInvocationWithContents extends BaseClientInvocat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpRequestBase asHttpRequest(String theUrlBase) throws DataFormatException, IOException {
|
public HttpRequestBase asHttpRequest(String theUrlBase) throws DataFormatException, IOException {
|
||||||
String url = theUrlBase + StringUtils.defaultString(myUrlExtension);
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(theUrlBase);
|
||||||
|
if (!theUrlBase.endsWith("/")) {
|
||||||
|
b.append('/');
|
||||||
|
}
|
||||||
|
b.append(StringUtils.defaultString(myUrlExtension));
|
||||||
|
|
||||||
|
String url = b.toString();
|
||||||
String contents = myContext.newXmlParser().encodeResourceToString(myResource);
|
String contents = myContext.newXmlParser().encodeResourceToString(myResource);
|
||||||
StringEntity entity = new StringEntity(contents, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"));
|
StringEntity entity = new StringEntity(contents, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"));
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@ public class DeleteClientInvocation extends BaseClientInvocation {
|
||||||
public HttpRequestBase asHttpRequest(String theUrlBase) throws DataFormatException, IOException {
|
public HttpRequestBase asHttpRequest(String theUrlBase) throws DataFormatException, IOException {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
b.append(theUrlBase);
|
b.append(theUrlBase);
|
||||||
|
if (!theUrlBase.endsWith("/")) {
|
||||||
|
b.append('/');
|
||||||
|
}
|
||||||
b.append(myUrlPath);
|
b.append(myUrlPath);
|
||||||
|
|
||||||
HttpDelete retVal = new HttpDelete(b.toString());
|
HttpDelete retVal = new HttpDelete(b.toString());
|
||||||
|
|
|
@ -22,18 +22,24 @@ package ca.uhn.fhir.rest.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpRequestBase;
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.method.IClientResponseHandler;
|
import ca.uhn.fhir.rest.method.IClientResponseHandler;
|
||||||
import ca.uhn.fhir.rest.method.ReadMethodBinding;
|
import ca.uhn.fhir.rest.method.ReadMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
import ca.uhn.fhir.rest.server.EncodingUtil;
|
import ca.uhn.fhir.rest.server.EncodingUtil;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
|
||||||
|
@ -109,4 +115,36 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
T resp = (T) invokeClient(binding, invocation);
|
T resp = (T) invokeClient(binding, invocation);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends IResource> Bundle search(final Class<T> theType, Map<String, List<IQueryParameterType>> theParams) {
|
||||||
|
LinkedHashMap<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
||||||
|
for (Entry<String, List<IQueryParameterType>> nextEntry : theParams.entrySet()) {
|
||||||
|
ArrayList<String> valueList = new ArrayList<String>();
|
||||||
|
params.put(nextEntry.getKey(), valueList);
|
||||||
|
for (IQueryParameterType nextValue : nextEntry.getValue()) {
|
||||||
|
valueList.add(nextValue.getValueAsQueryToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetClientInvocation invocation = SearchMethodBinding.createSearchInvocation(toResourceName(theType), params);
|
||||||
|
if (isKeepResponses()) {
|
||||||
|
myLastRequest = invocation.asHttpRequest(getServerBase());
|
||||||
|
}
|
||||||
|
|
||||||
|
IClientResponseHandler binding = new IClientResponseHandler() {
|
||||||
|
@Override
|
||||||
|
public Object invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||||
|
BaseServerResponseException {
|
||||||
|
EncodingUtil respType = EncodingUtil.forContentType(theResponseMimeType);
|
||||||
|
IParser parser = respType.newParser(myContext);
|
||||||
|
return parser.parseBundle(theType, theResponseReader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Bundle resp = (Bundle) invokeClient(binding, invocation);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,9 @@ public class GetClientInvocation extends BaseClientInvocation {
|
||||||
public HttpRequestBase asHttpRequest(String theUrlBase) {
|
public HttpRequestBase asHttpRequest(String theUrlBase) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
b.append(theUrlBase);
|
b.append(theUrlBase);
|
||||||
|
if (!theUrlBase.endsWith("/")) {
|
||||||
|
b.append('/');
|
||||||
|
}
|
||||||
b.append(myUrlPath);
|
b.append(myUrlPath);
|
||||||
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
|
@ -20,13 +20,18 @@ package ca.uhn.fhir.rest.client;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
|
||||||
public interface IGenericClient {
|
public interface IGenericClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the "read" method.
|
* Implementation of the "instance read" method.
|
||||||
*
|
*
|
||||||
* @param theType The type of resource to load
|
* @param theType The type of resource to load
|
||||||
* @param theId The ID to load
|
* @param theId The ID to load
|
||||||
|
@ -35,7 +40,7 @@ public interface IGenericClient {
|
||||||
<T extends IResource> T read(Class<T> theType, IdDt theId);
|
<T extends IResource> T read(Class<T> theType, IdDt theId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the "vread" method.
|
* Implementation of the "instance vread" method.
|
||||||
*
|
*
|
||||||
* @param theType The type of resource to load
|
* @param theType The type of resource to load
|
||||||
* @param theId The ID to load
|
* @param theId The ID to load
|
||||||
|
@ -44,4 +49,12 @@ public interface IGenericClient {
|
||||||
*/
|
*/
|
||||||
<T extends IResource> T vread(Class<T> theType, IdDt theId, IdDt theVersionId);
|
<T extends IResource> T vread(Class<T> theType, IdDt theId, IdDt theVersionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the "instance search" method.
|
||||||
|
* @param theType The type of resource to load
|
||||||
|
* @param theParams
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
<T extends IResource> Bundle search(Class<T> theType, Map<String, List<IQueryParameterType>> theParams);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,12 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetClientInvocation(queryStringArgs, getResourceName());
|
String resourceName = getResourceName();
|
||||||
|
return createSearchInvocation(resourceName, queryStringArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GetClientInvocation createSearchInvocation(String theResourceName, Map<String, List<String>> theParameters) {
|
||||||
|
return new GetClientInvocation(theParameters, theResourceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,8 @@ package ca.uhn.fhir.rest.param;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -40,6 +42,7 @@ import org.apache.commons.lang3.time.DateUtils;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.PathSpecification;
|
import ca.uhn.fhir.model.api.PathSpecification;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Count;
|
import ca.uhn.fhir.rest.annotation.Count;
|
||||||
|
@ -93,12 +96,14 @@ public class ParameterUtil {
|
||||||
parameter.setName(((RequiredParam) nextAnnotation).name());
|
parameter.setName(((RequiredParam) nextAnnotation).name());
|
||||||
parameter.setRequired(true);
|
parameter.setRequired(true);
|
||||||
parameter.setType(parameterType, innerCollectionType, outerCollectionType);
|
parameter.setType(parameterType, innerCollectionType, outerCollectionType);
|
||||||
|
extractDescription(parameter, annotations);
|
||||||
param = parameter;
|
param = parameter;
|
||||||
} else if (nextAnnotation instanceof OptionalParam) {
|
} else if (nextAnnotation instanceof OptionalParam) {
|
||||||
SearchParameter parameter = new SearchParameter();
|
SearchParameter parameter = new SearchParameter();
|
||||||
parameter.setName(((OptionalParam) nextAnnotation).name());
|
parameter.setName(((OptionalParam) nextAnnotation).name());
|
||||||
parameter.setRequired(false);
|
parameter.setRequired(false);
|
||||||
parameter.setType(parameterType, innerCollectionType, outerCollectionType);
|
parameter.setType(parameterType, innerCollectionType, outerCollectionType);
|
||||||
|
extractDescription(parameter, annotations);
|
||||||
param = parameter;
|
param = parameter;
|
||||||
} else if (nextAnnotation instanceof IncludeParam) {
|
} else if (nextAnnotation instanceof IncludeParam) {
|
||||||
if (parameterType != PathSpecification.class || innerCollectionType == null || outerCollectionType != null) {
|
if (parameterType != PathSpecification.class || innerCollectionType == null || outerCollectionType != null) {
|
||||||
|
@ -141,6 +146,19 @@ public class ParameterUtil {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void extractDescription(SearchParameter theParameter, Annotation[] theAnnotations) {
|
||||||
|
for (Annotation annotation : theAnnotations) {
|
||||||
|
if (annotation instanceof Description) {
|
||||||
|
Description desc = (Description) annotation;
|
||||||
|
if (isNotBlank(desc.formalDefinition())) {
|
||||||
|
theParameter.setDescription(desc.formalDefinition());
|
||||||
|
} else {
|
||||||
|
theParameter.setDescription(desc.shortDefinition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static InstantDt toInstant(Object theArgument) {
|
public static InstantDt toInstant(Object theArgument) {
|
||||||
if (theArgument instanceof InstantDt) {
|
if (theArgument instanceof InstantDt) {
|
||||||
return (InstantDt) theArgument;
|
return (InstantDt) theArgument;
|
||||||
|
|
|
@ -38,18 +38,19 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
*/
|
*/
|
||||||
public class SearchParameter extends BaseQueryParameter {
|
public class SearchParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
private String name;
|
private String myDescription;
|
||||||
|
private String myName;
|
||||||
private IParamBinder myParamBinder;
|
private IParamBinder myParamBinder;
|
||||||
private boolean required;
|
|
||||||
private Class<?> type;
|
|
||||||
private SearchParamTypeEnum myParamType;
|
private SearchParamTypeEnum myParamType;
|
||||||
|
private boolean myRequired;
|
||||||
|
private Class<?> myType;
|
||||||
|
|
||||||
public SearchParameter() {
|
public SearchParameter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchParameter(String name, boolean required) {
|
public SearchParameter(String name, boolean required) {
|
||||||
this.name = name;
|
this.myName = name;
|
||||||
this.required = required;
|
this.myRequired = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -60,21 +61,35 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
return myParamBinder.encode(theObject);
|
return myParamBinder.encode(theObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return myDescription;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see ca.uhn.fhir.rest.param.IParameter#getName()
|
* @see ca.uhn.fhir.rest.param.IParameter#getName()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return myName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchParamTypeEnum getParamType() {
|
||||||
|
return myParamType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?> getType() {
|
public Class<?> getType() {
|
||||||
return type;
|
return myType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlesMissing() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRequired() {
|
public boolean isRequired() {
|
||||||
return required;
|
return myRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -85,17 +100,21 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
return myParamBinder.parse(theString);
|
return myParamBinder.parse(theString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDescription(String theDescription) {
|
||||||
|
myDescription = theDescription;
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.myName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRequired(boolean required) {
|
public void setRequired(boolean required) {
|
||||||
this.required = required;
|
this.myRequired = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void setType(final Class<?> type, Class<? extends Collection<?>> theInnerCollectionType, Class<? extends Collection<?>> theOuterCollectionType) {
|
public void setType(final Class<?> type, Class<? extends Collection<?>> theInnerCollectionType, Class<? extends Collection<?>> theOuterCollectionType) {
|
||||||
this.type = type;
|
this.myType = type;
|
||||||
if (IQueryParameterType.class.isAssignableFrom(type)) {
|
if (IQueryParameterType.class.isAssignableFrom(type)) {
|
||||||
this.myParamBinder = new QueryParameterTypeBinder((Class<? extends IQueryParameterType>) type);
|
this.myParamBinder = new QueryParameterTypeBinder((Class<? extends IQueryParameterType>) type);
|
||||||
} else if (IQueryParameterOr.class.isAssignableFrom(type)) {
|
} else if (IQueryParameterOr.class.isAssignableFrom(type)) {
|
||||||
|
@ -132,14 +151,4 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SearchParamTypeEnum getParamType() {
|
|
||||||
return myParamType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handlesMissing() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import ca.uhn.fhir.rest.method.ReadMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
import ca.uhn.fhir.rest.param.IParameter;
|
import ca.uhn.fhir.rest.param.IParameter;
|
||||||
import ca.uhn.fhir.rest.param.BaseQueryParameter;
|
import ca.uhn.fhir.rest.param.BaseQueryParameter;
|
||||||
|
import ca.uhn.fhir.rest.param.SearchParameter;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.ResourceBinding;
|
import ca.uhn.fhir.rest.server.ResourceBinding;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
@ -110,19 +111,18 @@ public class ServerConformanceProvider {
|
||||||
RestResourceSearchParam searchParam = null;
|
RestResourceSearchParam searchParam = null;
|
||||||
StringDt searchParamChain = null;
|
StringDt searchParamChain = null;
|
||||||
for (IParameter nextParameterObj : params) {
|
for (IParameter nextParameterObj : params) {
|
||||||
if (!(nextParameterObj instanceof BaseQueryParameter)) {
|
if (!(nextParameterObj instanceof SearchParameter)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseQueryParameter nextParameter = (BaseQueryParameter)nextParameterObj;
|
SearchParameter nextParameter = (SearchParameter)nextParameterObj;
|
||||||
if (nextParameter.getName().startsWith("_")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchParam == null) {
|
if (searchParam == null) {
|
||||||
if (!nameToSearchParam.containsKey(nextParameter.getName())) {
|
if (!nameToSearchParam.containsKey(nextParameter.getName())) {
|
||||||
RestResourceSearchParam param = resource.addSearchParam();
|
RestResourceSearchParam param = resource.addSearchParam();
|
||||||
param.setName(nextParameter.getName());
|
param.setName(nextParameter.getName());
|
||||||
|
param.setDocumentation(nextParameter.getDescription());
|
||||||
|
param.setType(nextParameter.getParamType());
|
||||||
searchParam = param;
|
searchParam = param;
|
||||||
} else {
|
} else {
|
||||||
searchParam = nameToSearchParam.get(nextParameter.getName());
|
searchParam = nameToSearchParam.get(nextParameter.getName());
|
||||||
|
|
|
@ -22,7 +22,11 @@ package ca.uhn.fhir.rest.server.tester;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -44,14 +48,17 @@ import org.thymeleaf.templateresolver.TemplateResolver;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||||
import ca.uhn.fhir.rest.client.GenericClient;
|
import ca.uhn.fhir.rest.client.GenericClient;
|
||||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.EncodingUtil;
|
import ca.uhn.fhir.rest.server.EncodingUtil;
|
||||||
|
import ca.uhn.fhir.testmodel.IdentifierDt;
|
||||||
|
|
||||||
public class PublicTesterServlet extends HttpServlet {
|
public class PublicTesterServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@ -74,23 +81,22 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
myStaticResources.put("PublicTester.css", "text/css");
|
myStaticResources.put("PublicTester.css", "text/css");
|
||||||
myStaticResources.put("hapi_fhir_banner.png", "image/png");
|
myStaticResources.put("hapi_fhir_banner.png", "image/png");
|
||||||
myStaticResources.put("hapi_fhir_banner_right.png", "image/png");
|
myStaticResources.put("hapi_fhir_banner_right.png", "image/png");
|
||||||
myStaticResources.put("shCore.js","text/javascript");
|
myStaticResources.put("shCore.js", "text/javascript");
|
||||||
myStaticResources.put("shBrushJScript.js" ,"text/javascript");
|
myStaticResources.put("shBrushJScript.js", "text/javascript");
|
||||||
myStaticResources.put("shBrushXml.js" ,"text/javascript");
|
myStaticResources.put("shBrushXml.js", "text/javascript");
|
||||||
myStaticResources.put("shBrushPlain.js" ,"text/javascript");
|
myStaticResources.put("shBrushPlain.js", "text/javascript");
|
||||||
myStaticResources.put("shCore.css", "text/css");
|
myStaticResources.put("shCore.css", "text/css");
|
||||||
myStaticResources.put("shThemeDefault.css", "text/css");
|
myStaticResources.put("shThemeDefault.css", "text/css");
|
||||||
|
|
||||||
|
|
||||||
myCtx = new FhirContext();
|
myCtx = new FhirContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
||||||
if (DEBUGMODE) {
|
if (DEBUGMODE) {
|
||||||
myTemplateEngine.getCacheManager().clearAllCaches();
|
myTemplateEngine.getCacheManager().clearAllCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GenericClient client = (GenericClient) myCtx.newRestfulGenericClient(myServerBase);
|
GenericClient client = (GenericClient) myCtx.newRestfulGenericClient(myServerBase);
|
||||||
client.setKeepResponses(true);
|
client.setKeepResponses(true);
|
||||||
|
@ -103,25 +109,16 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
String resultSyntaxHighlighterClass;
|
String resultSyntaxHighlighterClass;
|
||||||
|
|
||||||
if ("read".equals(method)) {
|
if ("read".equals(method)) {
|
||||||
String resourceName = StringUtils.defaultString(theReq.getParameter("resourceName"));
|
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||||
RuntimeResourceDefinition def = myCtx.getResourceDefinition(resourceName);
|
|
||||||
if (def == null) {
|
|
||||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid resourceName: " + resourceName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||||
if (StringUtils.isBlank(id)) {
|
if (StringUtils.isBlank(id)) {
|
||||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||||
}
|
}
|
||||||
client.read(def.getImplementingClass(), new IdDt(id));
|
client.read(def.getImplementingClass(), new IdDt(id));
|
||||||
|
|
||||||
} if ("vread".equals(method)) {
|
}
|
||||||
String resourceName = StringUtils.defaultString(theReq.getParameter("resourceName"));
|
if ("vread".equals(method)) {
|
||||||
RuntimeResourceDefinition def = myCtx.getResourceDefinition(resourceName);
|
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||||
if (def == null) {
|
|
||||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid resourceName: " + resourceName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||||
if (StringUtils.isBlank(id)) {
|
if (StringUtils.isBlank(id)) {
|
||||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||||
|
@ -133,7 +130,48 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
client.vread(def.getImplementingClass(), new IdDt(id), new IdDt(versionId));
|
client.vread(def.getImplementingClass(), new IdDt(id), new IdDt(versionId));
|
||||||
|
|
||||||
|
} else if ("searchType".equals(method)) {
|
||||||
|
|
||||||
|
Map<String, List<IQueryParameterType>> params = new HashMap<String, List<IQueryParameterType>>();
|
||||||
|
|
||||||
|
HashSet<String> hashSet = new HashSet<String>(theReq.getParameterMap().keySet());
|
||||||
|
String paramName = null;
|
||||||
|
IQueryParameterType paramValue = null;
|
||||||
|
while (hashSet.isEmpty() == false) {
|
||||||
|
|
||||||
|
String nextKey = hashSet.iterator().next();
|
||||||
|
String nextValue = theReq.getParameter(nextKey);
|
||||||
|
paramName=null;
|
||||||
|
paramValue=null;
|
||||||
|
|
||||||
|
if (nextKey.startsWith("param.token.")) {
|
||||||
|
int prefixLength = "param.token.".length();
|
||||||
|
paramName = nextKey.substring(prefixLength + 2);
|
||||||
|
String systemKey = "param.token."+"1." + paramName;
|
||||||
|
String valueKey = "param.token."+"2." + paramName;
|
||||||
|
String system = theReq.getParameter(systemKey);
|
||||||
|
String value = theReq.getParameter(valueKey);
|
||||||
|
paramValue = new IdentifierDt(system, value);
|
||||||
|
hashSet.remove(systemKey);
|
||||||
|
hashSet.remove(valueKey);
|
||||||
|
} else if (nextKey.startsWith("param.string.")) {
|
||||||
|
paramName = nextKey.substring("param.string.".length());
|
||||||
|
paramValue = new StringDt(nextValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paramName != null) {
|
||||||
|
if (params.containsKey(paramName) == false) {
|
||||||
|
params.put(paramName, new ArrayList<IQueryParameterType>());
|
||||||
|
}
|
||||||
|
params.get(paramName).add(paramValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashSet.remove(nextKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||||
|
client.search(def.getImplementingClass(), params);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid method: " + method);
|
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid method: " + method);
|
||||||
return;
|
return;
|
||||||
|
@ -150,13 +188,13 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
EncodingUtil ctEnum = EncodingUtil.forContentType(mimeType);
|
EncodingUtil ctEnum = EncodingUtil.forContentType(mimeType);
|
||||||
switch (ctEnum) {
|
switch (ctEnum) {
|
||||||
case JSON:
|
case JSON:
|
||||||
resultSyntaxHighlighterClass="brush: jscript";
|
resultSyntaxHighlighterClass = "brush: jscript";
|
||||||
break;
|
break;
|
||||||
case XML:
|
case XML:
|
||||||
resultSyntaxHighlighterClass="brush: xml";
|
resultSyntaxHighlighterClass = "brush: xml";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
resultSyntaxHighlighterClass="brush: plain";
|
resultSyntaxHighlighterClass = "brush: plain";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +205,7 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
ctx.setVariable("resultStatus", resultStatus);
|
ctx.setVariable("resultStatus", resultStatus);
|
||||||
ctx.setVariable("resultBody", StringEscapeUtils.escapeHtml4(resultBody));
|
ctx.setVariable("resultBody", StringEscapeUtils.escapeHtml4(resultBody));
|
||||||
ctx.setVariable("resultSyntaxHighlighterClass", resultSyntaxHighlighterClass);
|
ctx.setVariable("resultSyntaxHighlighterClass", resultSyntaxHighlighterClass);
|
||||||
|
|
||||||
myTemplateEngine.process(PUBLIC_TESTER_RESULT_HTML, ctx, theResp.getWriter());
|
myTemplateEngine.process(PUBLIC_TESTER_RESULT_HTML, ctx, theResp.getWriter());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ourLog.error("Failure during processing", e);
|
ourLog.error("Failure during processing", e);
|
||||||
|
@ -175,12 +213,21 @@ public class PublicTesterServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RuntimeResourceDefinition getResourceType(HttpServletRequest theReq) throws ServletException {
|
||||||
|
String resourceName = StringUtils.defaultString(theReq.getParameter("resourceName"));
|
||||||
|
RuntimeResourceDefinition def = myCtx.getResourceDefinition(resourceName);
|
||||||
|
if (def == null) {
|
||||||
|
throw new ServletException("Invalid resourceName: " + resourceName);
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
||||||
if (DEBUGMODE) {
|
if (DEBUGMODE) {
|
||||||
myTemplateEngine.getCacheManager().clearAllCaches();
|
myTemplateEngine.getCacheManager().clearAllCaches();
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("RequestURI: {}", theReq.getPathInfo());
|
ourLog.info("RequestURI: {}", theReq.getPathInfo());
|
||||||
|
|
||||||
String resName = theReq.getPathInfo().substring(1);
|
String resName = theReq.getPathInfo().substring(1);
|
||||||
|
|
|
@ -46,11 +46,24 @@ function displaySearchType(expandoTr, resourceName) {
|
||||||
$('<input />', { name: 'method', value: 'searchType', type: 'hidden' }),
|
$('<input />', { name: 'method', value: 'searchType', type: 'hidden' }),
|
||||||
$('<input />', { name: 'resourceName', value: resourceName, type: 'hidden' })
|
$('<input />', { name: 'resourceName', value: resourceName, type: 'hidden' })
|
||||||
)
|
)
|
||||||
|
if (searchParam.documentation && searchParam.documentation.length > 0) {
|
||||||
|
formElement.append(
|
||||||
|
$('<span>' + searchParam.documentation + '<br /></span>')
|
||||||
|
);
|
||||||
|
}
|
||||||
var inputId = newUniqueId();
|
var inputId = newUniqueId();
|
||||||
formElement.append(
|
if (searchParam.type && searchParam.type == 'token') {
|
||||||
$('<input />', { name: 'param.' + searchParam.name, placeholder: searchParam.name, type: 'text', id: inputId }),
|
formElement.append(
|
||||||
$('<label for="' + inputId + '">' + searchParam.name + '</input>')
|
$('<input />', { name: 'param.token.1.' + searchParam.name, placeholder: 'system/namespace', type: 'text', id: inputId }),
|
||||||
);
|
$('<input />', { name: 'param.token.2.' + searchParam.name, placeholder: 'value', type: 'text', id: inputId }),
|
||||||
|
$('<label for="' + inputId + '">' + searchParam.name + '</input>')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
formElement.append(
|
||||||
|
$('<input />', { name: 'param.string.' + searchParam.name, placeholder: searchParam.name, type: 'text', id: inputId }),
|
||||||
|
$('<label for="' + inputId + '">' + searchParam.name + '</input>')
|
||||||
|
);
|
||||||
|
}
|
||||||
formElement.append(
|
formElement.append(
|
||||||
$('<br />'),
|
$('<br />'),
|
||||||
$('<input />', { type: 'submit', value: 'Submit' })
|
$('<input />', { type: 'submit', value: 'Submit' })
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hamcrest.core.StringContains;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -11,9 +14,11 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Search;
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.param.SearchParameter;
|
||||||
import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider;
|
import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider;
|
||||||
|
|
||||||
public class DocumentationTest {
|
public class DocumentationTest {
|
||||||
|
@ -30,11 +35,25 @@ public class DocumentationTest {
|
||||||
rs.setServerConformanceProvider(sc);
|
rs.setServerConformanceProvider(sc);
|
||||||
|
|
||||||
rs.init(null);
|
rs.init(null);
|
||||||
|
|
||||||
|
boolean found=false;
|
||||||
|
Collection<ResourceBinding> resourceBindings = rs.getResourceBindings();
|
||||||
|
for (ResourceBinding resourceBinding : resourceBindings) {
|
||||||
|
if (resourceBinding.getResourceName().equals("Patient")) {
|
||||||
|
List<BaseMethodBinding> methodBindings = resourceBinding.getMethodBindings();
|
||||||
|
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
|
||||||
|
SearchParameter param = (SearchParameter) binding.getParameters().iterator().next();
|
||||||
|
assertEquals("The patient's identifier (MRN or other card number)", param.getDescription());
|
||||||
|
found=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
Conformance conformance = sc.getServerConformance();
|
Conformance conformance = sc.getServerConformance();
|
||||||
String conf = new FhirContext().newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
|
String conf = new FhirContext().newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
|
||||||
ourLog.info(conf);
|
ourLog.info(conf);
|
||||||
|
|
||||||
|
assertThat(conf, containsString("<documentation value=\"The patient's identifier (MRN or other card number)\"/>"));
|
||||||
|
assertThat(conf, containsString("<type value=\"token\"/>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +62,9 @@ public class DocumentationTest {
|
||||||
public static class SearchProvider {
|
public static class SearchProvider {
|
||||||
|
|
||||||
@Search(type = Patient.class)
|
@Search(type = Patient.class)
|
||||||
public Patient findPatient(@Description(shortDefinition = "The patient's identifier (MRN or other card number)") @RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier) {
|
public Patient findPatient(
|
||||||
|
@Description(shortDefinition = "The patient's identifier (MRN or other card number)")
|
||||||
|
@RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class TesterTest {
|
||||||
|
|
||||||
@Search(type = Patient.class)
|
@Search(type = Patient.class)
|
||||||
public Patient findPatient(
|
public Patient findPatient(
|
||||||
@Description(shortDefinition="The patient's identifier (MRN or other card number)")
|
@Description(shortDefinition="The patient's identifier (MRN or other card number). Example system 'urn:hapitest:mrns', example MRN '00002'")
|
||||||
@RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier
|
@RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier
|
||||||
) {
|
) {
|
||||||
for (Patient next : getIdToPatient().values()) {
|
for (Patient next : getIdToPatient().values()) {
|
||||||
|
|
Loading…
Reference in New Issue