More documentation
This commit is contained in:
parent
fefd0e9a57
commit
df2675867a
|
@ -152,7 +152,6 @@
|
|||
</plugin>
|
||||
<!--
|
||||
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
||||
|
@ -178,6 +177,7 @@
|
|||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
|
|
|
@ -391,6 +391,7 @@ public class XmlParser implements IParser {
|
|||
eventWriter = decorateStreamWriter(eventWriter);
|
||||
|
||||
encodeResourceToXmlStreamWriter(theResource, eventWriter);
|
||||
eventWriter.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new ConfigurationException("Failed to initialize STaX event factory", e);
|
||||
}
|
||||
|
@ -410,7 +411,6 @@ public class XmlParser implements IParser {
|
|||
encodeCompositeElementToStreamWriter(theResource, eventWriter, resDef);
|
||||
|
||||
eventWriter.writeEndElement();
|
||||
eventWriter.close();
|
||||
}
|
||||
|
||||
private void encodeXhtml(XhtmlDt theDt, XMLStreamWriter theEventWriter) throws XMLStreamException {
|
||||
|
|
|
@ -90,7 +90,7 @@ public class ClientInvocationHandler implements InvocationHandler {
|
|||
if (list.size() == 0) {
|
||||
return null;
|
||||
} else if (list.size() == 1) {
|
||||
return list.get(1);
|
||||
return list.get(0);
|
||||
} else {
|
||||
throw new InvalidResponseException("FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
|
||||
}
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.rest.common.BaseMethodBinding;
|
||||
|
||||
public class GetClientInvocation extends BaseClientInvocation {
|
||||
|
@ -24,7 +30,6 @@ public class GetClientInvocation extends BaseClientInvocation {
|
|||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> getParameters() {
|
||||
return myParameters;
|
||||
}
|
||||
|
@ -35,7 +40,28 @@ public class GetClientInvocation extends BaseClientInvocation {
|
|||
|
||||
@Override
|
||||
public HttpRequestBase asHttpRequest(String theUrlBase) {
|
||||
return new HttpGet(theUrlBase + myUrlPath);
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theUrlBase);
|
||||
b.append(myUrlPath);
|
||||
|
||||
boolean first = true;
|
||||
for (Entry<String, String> next : myParameters.entrySet()) {
|
||||
if (first) {
|
||||
b.append('?');
|
||||
first = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
try {
|
||||
b.append(URLEncoder.encode(next.getKey(), "UTF-8"));
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(next.getValue(), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ConfigurationException("Could not find UTF-8 encoding. This shouldn't happen.", e);
|
||||
}
|
||||
|
||||
}
|
||||
return new HttpGet(b.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class BaseMethodBinding {
|
|||
|
||||
public abstract List<IResource> invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> theParameterValues) throws InvalidRequestException, InternalErrorException;
|
||||
|
||||
public abstract boolean matches(String theResourceName, IdDt theId, IdDt theVersion, Set<String> theParameterNames);
|
||||
public abstract boolean matches(Request theRequest);
|
||||
|
||||
public String getResourceName() {
|
||||
return myResourceName;
|
||||
|
@ -56,7 +56,7 @@ public abstract class BaseMethodBinding {
|
|||
|
||||
Class<?> methodReturnType = theMethod.getReturnType();
|
||||
MethodReturnTypeEnum methodReturnTypeEnum;
|
||||
if (methodReturnType.equals(List.class)) {
|
||||
if (Collection.class.isAssignableFrom(methodReturnType)) {
|
||||
methodReturnTypeEnum = MethodReturnTypeEnum.LIST_OF_RESOURCES;
|
||||
} else if (IResource.class.isAssignableFrom(methodReturnType)) {
|
||||
methodReturnTypeEnum = MethodReturnTypeEnum.RESOURCE;
|
||||
|
|
|
@ -3,7 +3,6 @@ package ca.uhn.fhir.rest.common;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
|
@ -11,6 +10,7 @@ import ca.uhn.fhir.context.ConfigurationException;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.GetClientInvocation;
|
||||
import ca.uhn.fhir.rest.common.SearchMethodBinding.RequestType;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.Util;
|
||||
|
@ -18,7 +18,8 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class ReadMethodBinding extends BaseMethodBinding {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class);
|
||||
|
||||
private Method myMethod;
|
||||
private Integer myIdIndex;
|
||||
private Integer myVersionIdIndex;
|
||||
|
@ -48,17 +49,21 @@ public class ReadMethodBinding extends BaseMethodBinding {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String theResourceName, IdDt theId, IdDt theVersion, Set<String> theParameterNames) {
|
||||
if (!theResourceName.equals(getResourceName())) {
|
||||
public boolean matches(Request theRequest) {
|
||||
if (!theRequest.getResourceName().equals(getResourceName())) {
|
||||
return false;
|
||||
}
|
||||
if (theParameterNames.isEmpty() == false) {
|
||||
if (theRequest.getParameterNames().isEmpty() == false) {
|
||||
return false;
|
||||
}
|
||||
if ((theVersion == null) != (myVersionIdIndex == null)) {
|
||||
if ((theRequest.getVersion() == null) != (myVersionIdIndex == null)) {
|
||||
return false;
|
||||
}
|
||||
if (theId == null) {
|
||||
if (theRequest.getId() == null) {
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getRequestType() != RequestType.GET) {
|
||||
ourLog.trace("Method {} doesn't match because request type is not GET: {}", theRequest.getId(), theRequest.getRequestType());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package ca.uhn.fhir.rest.common;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.common.SearchMethodBinding.RequestType;
|
||||
|
||||
public class Request {
|
||||
|
||||
private IdDt myId;
|
||||
private String myOperation;
|
||||
private Set<String> myParameterNames;
|
||||
private RequestType myRequestType;
|
||||
private String myResourceName;
|
||||
|
||||
private IdDt myVersion;
|
||||
|
||||
public IdDt getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return myOperation;
|
||||
}
|
||||
|
||||
public Set<String> getParameterNames() {
|
||||
return myParameterNames;
|
||||
}
|
||||
|
||||
public RequestType getRequestType() {
|
||||
return myRequestType;
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return myResourceName;
|
||||
}
|
||||
|
||||
public IdDt getVersion() {
|
||||
return myVersion;
|
||||
}
|
||||
|
||||
public void setId(IdDt theId) {
|
||||
myId = theId;
|
||||
}
|
||||
|
||||
public void setOperation(String theOperation) {
|
||||
myOperation = theOperation;
|
||||
}
|
||||
|
||||
public void setParameterNames(Set<String> theParameterNames) {
|
||||
myParameterNames = theParameterNames;
|
||||
}
|
||||
|
||||
public void setRequestType(RequestType theRequestType) {
|
||||
myRequestType = theRequestType;
|
||||
}
|
||||
|
||||
public void setResourceName(String theResourceName) {
|
||||
myResourceName = theResourceName;
|
||||
}
|
||||
|
||||
public void setVersion(IdDt theVersion) {
|
||||
myVersion = theVersion;
|
||||
}
|
||||
|
||||
public static Request withResourceAndParams(String theResourceName, RequestType theRequestType, Set<String> theParamNamess) {
|
||||
Request retVal = new Request();
|
||||
retVal.setResourceName(theResourceName);
|
||||
retVal.setParameterNames(theParamNamess);
|
||||
retVal.setRequestType(theRequestType);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
|
@ -27,9 +27,8 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
|
||||
private Method method;
|
||||
|
||||
private List<Parameter> myParameters;
|
||||
private RequestType requestType;
|
||||
private Class<?> myDeclaredResourceType;
|
||||
private List<Parameter> myParameters;
|
||||
|
||||
public SearchMethodBinding(MethodReturnTypeEnum theMethodReturnTypeEnum, Class<? extends IResource> theReturnResourceType, Method theMethod) {
|
||||
super(theMethodReturnTypeEnum, theReturnResourceType);
|
||||
|
@ -39,6 +38,10 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
this.myDeclaredResourceType = theMethod.getReturnType();
|
||||
}
|
||||
|
||||
public Class<?> getDeclaredResourceType() {
|
||||
return myDeclaredResourceType.getClass();
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
@ -47,19 +50,27 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
return myParameters;
|
||||
}
|
||||
|
||||
public RequestType getRequestType() {
|
||||
return requestType;
|
||||
}
|
||||
|
||||
public Class getDeclaredResourceType() {
|
||||
return myDeclaredResourceType.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnTypeEnum getReturnType() {
|
||||
return ReturnTypeEnum.BUNDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
||||
assert theArgs.length == myParameters.size() : "Wrong number of arguments: " + theArgs.length;
|
||||
|
||||
Map<String, String> args = new HashMap<String, String>();
|
||||
|
||||
for (int idx = 0; idx < theArgs.length; idx++) {
|
||||
Object object = theArgs[idx];
|
||||
Parameter nextParam = myParameters.get(idx);
|
||||
String value = nextParam.encode(object);
|
||||
args.put(nextParam.getName(), value);
|
||||
}
|
||||
|
||||
return new GetClientInvocation(args, getResourceName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> parameterValues) throws InvalidRequestException, InternalErrorException {
|
||||
assert theId == null;
|
||||
|
@ -94,26 +105,34 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String theResourceName, IdDt theId, IdDt theVersion, Set<String> theParameterNames) {
|
||||
if (!theResourceName.equals(getResourceName())) {
|
||||
ourLog.trace("Method {} doesn't match because resource name {} != {}", method.getName(), theResourceName, getResourceName());
|
||||
public boolean matches(Request theRequest) {
|
||||
if (!theRequest.getResourceName().equals(getResourceName())) {
|
||||
ourLog.trace("Method {} doesn't match because resource name {} != {}", method.getName(), theRequest.getResourceName(), getResourceName());
|
||||
return false;
|
||||
}
|
||||
if (theId != null || theVersion != null) {
|
||||
ourLog.trace("Method {} doesn't match because ID or Version are not null: {} - {}", theId, theVersion);
|
||||
if (theRequest.getId() != null || theRequest.getVersion() != null) {
|
||||
ourLog.trace("Method {} doesn't match because ID or Version are not null: {} - {}", theRequest.getId(), theRequest.getVersion());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (theRequest.getRequestType() == RequestType.GET && theRequest.getOperation() != null) {
|
||||
ourLog.trace("Method {} doesn't match because request type is GET but operation is not null: {}", theRequest.getId(), theRequest.getOperation());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getRequestType() == RequestType.POST && !"_search".equals(theRequest.getOperation())) {
|
||||
ourLog.trace("Method {} doesn't match because request type is POST but operation is not _search: {}", theRequest.getId(), theRequest.getOperation());
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> methodParamsTemp = new HashSet<String>();
|
||||
for (int i = 0; i < this.myParameters.size(); i++) {
|
||||
Parameter temp = this.myParameters.get(i);
|
||||
methodParamsTemp.add(temp.getName());
|
||||
if (temp.isRequired() && !theParameterNames.contains(temp.getName())) {
|
||||
if (temp.isRequired() && !theRequest.getParameterNames().contains(temp.getName())) {
|
||||
ourLog.trace("Method {} doesn't match param '{}' is not present", method.getName(), temp.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
boolean retVal = methodParamsTemp.containsAll(theParameterNames);
|
||||
boolean retVal = methodParamsTemp.containsAll(theRequest.getParameterNames());
|
||||
|
||||
ourLog.trace("Method {} matches: {}", method.getName(), retVal);
|
||||
|
||||
|
@ -128,10 +147,6 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
this.myParameters = parameters;
|
||||
}
|
||||
|
||||
public void setRequestType(RequestType requestType) {
|
||||
this.requestType = requestType;
|
||||
}
|
||||
|
||||
public void setResourceType(Class<?> resourceType) {
|
||||
this.myDeclaredResourceType = resourceType;
|
||||
}
|
||||
|
@ -140,20 +155,4 @@ public class SearchMethodBinding extends BaseMethodBinding {
|
|||
DELETE, GET, POST, PUT
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
||||
assert theArgs.length == myParameters.size() : "Wrong number of arguments: " + theArgs.length;
|
||||
|
||||
Map<String, String> args = new HashMap<String, String>();
|
||||
|
||||
for (int idx = 0; idx < theArgs.length; idx++) {
|
||||
Object object = theArgs[idx];
|
||||
Parameter nextParam = myParameters.get(idx);
|
||||
String value = nextParam.encode(object);
|
||||
args.put(nextParam.getName(), value);
|
||||
}
|
||||
|
||||
return new GetClientInvocation(args, getResourceName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Set;
|
|||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.common.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.common.Request;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -26,15 +27,15 @@ public class Resource {
|
|||
this.methods = methods;
|
||||
}
|
||||
|
||||
public BaseMethodBinding getMethod(String theResourceName, IdDt theId, IdDt theVersionId, Set<String> theParameters) throws Exception {
|
||||
public BaseMethodBinding getMethod(Request theRequest) throws Exception {
|
||||
if (null == methods) {
|
||||
ourLog.warn("No methods exist for resource provider: {}", resourceProvider.getClass());
|
||||
return null;
|
||||
}
|
||||
|
||||
ourLog.info("Looking for a handler for {} / {} / {} / {}", new Object[] {theResourceName,theId, theVersionId, theParameters});
|
||||
ourLog.debug("Looking for a handler for {}", theRequest);
|
||||
for (BaseMethodBinding rm : methods) {
|
||||
if (rm.matches(theResourceName, theId, theVersionId, theParameters)) {
|
||||
if (rm.matches(theRequest)) {
|
||||
ourLog.info("Handler {} matches", rm);
|
||||
return rm;
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.model.api.BundleEntry;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.common.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.common.Request;
|
||||
import ca.uhn.fhir.rest.common.SearchMethodBinding;
|
||||
|
||||
public abstract class RestfulServer extends HttpServlet {
|
||||
|
@ -120,8 +121,6 @@ public abstract class RestfulServer extends HttpServlet {
|
|||
}
|
||||
|
||||
String resourceName = null;
|
||||
Long identity = null;
|
||||
|
||||
String requestPath = StringUtils.defaultString(request.getRequestURI());
|
||||
String contextPath = StringUtils.defaultString(request.getContextPath());
|
||||
requestPath = requestPath.substring(contextPath.length());
|
||||
|
@ -147,11 +146,27 @@ public abstract class RestfulServer extends HttpServlet {
|
|||
|
||||
IdDt id = null;
|
||||
IdDt versionId = null;
|
||||
String operation = null;
|
||||
if (tok.hasMoreTokens()) {
|
||||
String identityString = tok.nextToken();
|
||||
id = new IdDt(identityString);
|
||||
String nextString = tok.nextToken();
|
||||
if (nextString.startsWith("_")) {
|
||||
operation = nextString;
|
||||
}else {
|
||||
id = new IdDt(nextString);
|
||||
}
|
||||
}
|
||||
|
||||
if (tok.hasMoreTokens()) {
|
||||
String nextString = tok.nextToken();
|
||||
if (nextString.startsWith("_history")) {
|
||||
if (tok.hasMoreTokens()) {
|
||||
versionId = new IdDt(tok.nextToken());
|
||||
}else {
|
||||
throw new InvalidRequestException("_history search specified but no version requested in URL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: look for more tokens for version, compartments, etc...
|
||||
|
||||
//
|
||||
|
@ -169,7 +184,15 @@ public abstract class RestfulServer extends HttpServlet {
|
|||
// }
|
||||
// }
|
||||
|
||||
BaseMethodBinding resourceMethod = resourceBinding.getMethod(resourceName, id, versionId, params.keySet());
|
||||
Request r = new Request();
|
||||
r.setResourceName(resourceName);
|
||||
r.setId(id);
|
||||
r.setVersion(versionId);
|
||||
r.setOperation(operation);
|
||||
r.setParameterNames(params.keySet());
|
||||
r.setRequestType(requestType);
|
||||
|
||||
BaseMethodBinding resourceMethod = resourceBinding.getMethod(r);
|
||||
if (null == resourceMethod) {
|
||||
throw new MethodNotFoundException("No resource method available for the supplied parameters " + params);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
|
|||
private XMLStreamWriter myTarget;
|
||||
private int depth = 0;
|
||||
private Map<Integer, Boolean> hasChildElement = new HashMap<Integer, Boolean>();
|
||||
private XMLEventFactory myXmlEventFactory;
|
||||
|
||||
private static final String INDENT_CHAR = " ";
|
||||
private static final String LINEFEED_CHAR = "\n";
|
||||
|
@ -135,7 +134,8 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
|
|||
|
||||
@Override
|
||||
public void writeEndDocument() throws XMLStreamException {
|
||||
decrementAndIndent();myTarget.writeEndDocument();
|
||||
decrementAndIndent();
|
||||
myTarget.writeEndDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -215,7 +215,7 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
|
|||
|
||||
@Override
|
||||
public void writeCharacters(char[] theText, int theStart, int theLen) throws XMLStreamException {
|
||||
myTarget.writeCharacters(theText,theStart,theLen);
|
||||
myTarget.writeCharacters(theText, theStart, theLen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,10 +4,18 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RestfulPatientResourceProviderMore implements IResourceProvider {
|
||||
|
||||
//START SNIPPET: searchAll
|
||||
|
@ -18,6 +26,59 @@ public List<Organization> getAllOrganizations() {
|
|||
}
|
||||
//END SNIPPET: searchAll
|
||||
|
||||
//START SNIPPET: read
|
||||
@Read()
|
||||
public Patient getResourceById(@Read.IdParam IdDt theId) {
|
||||
Patient retVal = new Patient();
|
||||
// ...populate...
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: read
|
||||
|
||||
//START SNIPPET: vread
|
||||
@Read()
|
||||
public Patient getResourceById(@Read.IdParam IdDt theId,
|
||||
@Read.VersionIdParam IdDt theVersionId) {
|
||||
Patient retVal = new Patient();
|
||||
// ...populate...
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: vread
|
||||
|
||||
//START SNIPPET: searchStringParam
|
||||
@Search()
|
||||
public List<Patient> searchByLastName(@Required(name=Patient.SP_FAMILY) StringDt theId) {
|
||||
List<Patient> retVal = new ArrayList<Patient>();
|
||||
// ...populate...
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: searchStringParam
|
||||
|
||||
//START SNIPPET: searchIdentifierParam
|
||||
@Search()
|
||||
public List<Patient> searchByIdentifier(@Required(name=Patient.SP_IDENTIFIER) IdentifierDt theId) {
|
||||
String identifierSystem = theId.getSystem().getValueAsString();
|
||||
String identifier = theId.getValue().getValue();
|
||||
|
||||
List<Patient> retVal = new ArrayList<Patient>();
|
||||
// ...populate...
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: searchIdentifierParam
|
||||
|
||||
//START SNIPPET: searchOptionalParam
|
||||
@Search()
|
||||
public List<Patient> searchByNames( @Required(name=Patient.SP_FAMILY) StringDt theFamilyName,
|
||||
@Optional(name=Patient.SP_GIVEN) StringDt theGivenName ) {
|
||||
String familyName = theFamilyName.getValue();
|
||||
String givenName = theGivenName != null ? theGivenName.getValue() : null;
|
||||
|
||||
List<Patient> retVal = new ArrayList<Patient>();
|
||||
// ...populate...
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: searchOptionalParam
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return null;
|
||||
|
|
|
@ -56,6 +56,14 @@
|
|||
padding-left: 25px;
|
||||
}
|
||||
|
||||
tt {
|
||||
margin-left: 20px;
|
||||
white-space: pre;
|
||||
color: #448;
|
||||
padding: 4px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5 {
|
||||
color: #E3701A;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<item name="Introduction" href="./doc_intro.html"/>
|
||||
<item name="The Data Model" href="./doc_fhirobjects.html"/>
|
||||
<item name="RESTful Server" href="./doc_rest_server.html"/>
|
||||
<item name="RESTful Operations" href="./doc_rest_operations.html"/>
|
||||
<item name="JavaDocs" href="./apidocs/index.html"/>
|
||||
</menu>
|
||||
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
|
||||
|
||||
<properties>
|
||||
<title>RESTful Operations - HAPI FHIR</title>
|
||||
<author email="jamesagnew@users.sourceforge.net">James Agnew</author>
|
||||
</properties>
|
||||
|
||||
<body>
|
||||
|
||||
<section name="Implementing Resource Provider Operations">
|
||||
|
||||
<p>
|
||||
RESTful Clients and Servers both share the same
|
||||
method pattern, with one key difference: A client
|
||||
is defined using annotated methods on an interface
|
||||
which are used to retrieve resources,
|
||||
whereas a server requires concrete method implementations
|
||||
to actually provide those resources.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Unless otherwise specified, the examples below show <b>server</b>
|
||||
implementations, but client methods will follow the same patterns.
|
||||
</p>
|
||||
|
||||
<macro name="toc">
|
||||
</macro>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Instance Level - read">
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="http://latest.fhir.me/http.html#read"><b>read</b></a>
|
||||
operation retrieves a resource by ID. It is annotated with the
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Read.html">@Read</a>
|
||||
annotation, and has a single parameter annotated with the
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Read.IdParam.html">@Read.IdParam</a>
|
||||
annotation.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="read" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URL to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient/111</code>
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Instance Level - vread">
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="http://latest.fhir.me/http.html#vread"><b>vread</b></a>
|
||||
operation retrieves a specific version of a resource with a given ID. It looks exactly
|
||||
like a "read" operation, but with a second
|
||||
parameter annotated with the
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Read.VersionIdParam.html">@VersionIdParam</a>
|
||||
annotation.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="vread" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URL to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient/111/_history/2</code>
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Type Level - search">
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="http://latest.fhir.me/http.html#search"><b>search</b></a> operation returns a bundle
|
||||
with zero-to-many resources of a given type, matching a given set of parameters.
|
||||
</p>
|
||||
|
||||
<subsection name="Search with No Parameters">
|
||||
|
||||
<p>
|
||||
The following example shows a search with no parameters. This operation
|
||||
should return all resources of a given type (this obviously doesn't make
|
||||
sense in all contexts, but does for some resource types).
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchAll" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URL to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient</code>
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
<subsection name="Search with a String Parameter">
|
||||
|
||||
<p>
|
||||
To allow a search using given search parameters, add one or more parameters
|
||||
to your search method and tag these parameters as either
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/server/parameters/Required.html">@Required</a>
|
||||
or
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/server/parameters/Optional.html">@Optional</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This annotation takes a "name" parameter which specifies the parameter's
|
||||
name (as it will appear in the search URL). FHIR defines standardized parameter
|
||||
names for each resource, and these are available as constants on the
|
||||
individual HAPI resource classes.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchStringParam" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URL to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient?family=SMITH</code>
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
<subsection name="Search By Identifier">
|
||||
|
||||
<p>
|
||||
Searches method parameters may be of any type that implements the
|
||||
<a href="./apidocs/ca/uhn/fhir/model/api/IQueryParameterType.html">IQueryParameterType</a>
|
||||
interface. For example, the search below can be used to search by
|
||||
identifier (e.g. search for an MRN).
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchIdentifierParam" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URL to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient?identifier=urn:foo|7000135</code>
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
<subsection name="Multiple and Optional Parameters">
|
||||
|
||||
<p>
|
||||
Search methods may take multiple parameters, and these parameters
|
||||
may be optional. To add a second required parameter, annotate the
|
||||
parameter with
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/server/parameters/Required.html">@Required</a>.
|
||||
To add an optional parameter (which will be pased in as <code>null</code> if no value
|
||||
is supplied), annotate the method with
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/server/parameters/Required.html">@Optional</a>.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchOptionalParam" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
Example URLs to invoke this method:<br/>
|
||||
<code>http://fhir.example.com/Patient?family=SMITH</code><br/>
|
||||
<code>http://fhir.example.com/Patient?family=SMITH&given=JOHN</code>
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</document>
|
|
@ -59,6 +59,13 @@
|
|||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProvider.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
You will probable wish to add more methods
|
||||
to your resource provider. See
|
||||
<a href="./doc_rest_operations.html">RESTful Operations</a> for
|
||||
lots more examples of how to add methods for various operations.
|
||||
</p>
|
||||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Create a Server">
|
||||
|
@ -94,25 +101,6 @@
|
|||
|
||||
</section>
|
||||
|
||||
<section name="Resource Providers">
|
||||
|
||||
<p>
|
||||
Resource providers can support a wide variety of operations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following example shows a search with no parameters. This operation
|
||||
should return all resources of a given type (this obviously doesn't make
|
||||
sense in all contexts, but does for some resource types).
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchAll" />
|
||||
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||
</macro>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
</document>
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.mockito.ArgumentCaptor;
|
|||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -73,5 +74,77 @@ public class ClientTest {
|
|||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testVRead() throws Exception {
|
||||
|
||||
//@formatter:off
|
||||
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
+ "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>"
|
||||
+ "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>"
|
||||
+ "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>"
|
||||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>";
|
||||
//@formatter:on
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
// Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
Patient response = client.getPatientByVersionId(new IdDt("111"), new IdDt("999"));
|
||||
|
||||
assertEquals("http://foo/Patient/111/_history/999", capt.getValue().getURI().toString());
|
||||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch() throws Exception {
|
||||
|
||||
//@formatter:off
|
||||
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" +
|
||||
"<title/>\n" +
|
||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
||||
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
|
||||
"<published>2014-03-11T16:35:07-04:00</published>\n" +
|
||||
"<author>\n" +
|
||||
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
|
||||
"</author>\n" +
|
||||
"<entry>\n" +
|
||||
"<content type=\"text/xml\">"
|
||||
+ "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
+ "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>"
|
||||
+ "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>"
|
||||
+ "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>"
|
||||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>"
|
||||
+ "</content>\n"
|
||||
+ " </entry>\n"
|
||||
+ "</feed>";
|
||||
//@formatter:on
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
|
||||
assertEquals("http://foo/Patient?identifier=urn%3Afoo%7C123", capt.getValue().getURI().toString());
|
||||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ public interface ITestClient extends IRestfulClient {
|
|||
@Read(type=Patient.class)
|
||||
Patient getPatientById(@Read.IdParam IdDt theId);
|
||||
|
||||
@Read(type=Patient.class)
|
||||
Patient getPatientByVersionId(@Read.IdParam IdDt theId, @Read.VersionIdParam IdDt theVersionId);
|
||||
|
||||
@Search(type=Patient.class)
|
||||
Patient findPatientByMrn(@Required(name = Patient.SP_IDENTIFIER) IdentifierDt theId);
|
||||
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
|
||||
/**
|
||||
|
@ -20,9 +23,8 @@ import ca.uhn.fhir.rest.server.parameters.Required;
|
|||
*/
|
||||
public class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
private Map<String, Patient> myIdToPatient = new HashMap<String, Patient>();
|
||||
|
||||
public DummyPatientResourceProvider() {
|
||||
public Map<String, Patient> getIdToPatient() {
|
||||
Map<String, Patient> idToPatient = new HashMap<String, Patient>();
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier();
|
||||
|
@ -33,7 +35,7 @@ public class DummyPatientResourceProvider implements IResourceProvider {
|
|||
patient.getName().get(0).addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.getGender().setText("M");
|
||||
myIdToPatient.put("1", patient);
|
||||
idToPatient.put("1", patient);
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
@ -45,13 +47,14 @@ public class DummyPatientResourceProvider implements IResourceProvider {
|
|||
patient.getName().get(0).addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientTwo");
|
||||
patient.getGender().setText("F");
|
||||
myIdToPatient.put("2", patient);
|
||||
idToPatient.put("2", patient);
|
||||
}
|
||||
return idToPatient;
|
||||
}
|
||||
|
||||
@Search()
|
||||
public Patient getPatient(@Required(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier) {
|
||||
for (Patient next : myIdToPatient.values()) {
|
||||
for (Patient next : getIdToPatient().values()) {
|
||||
for (IdentifierDt nextId : next.getIdentifier()) {
|
||||
if (nextId.matchesSystemAndValue(theIdentifier)) {
|
||||
return next;
|
||||
|
@ -61,9 +64,17 @@ public class DummyPatientResourceProvider implements IResourceProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
@Search()
|
||||
public List<Patient> getPatientWithOptionalName(@Required(name = "name1") StringDt theName1, @Optional(name = "name2") StringDt theName2) {
|
||||
List<Patient> retVal = new ArrayList<Patient>();
|
||||
Patient next = getIdToPatient().get("1");
|
||||
next.getName().get(0).getFamily().set(0, theName1);
|
||||
if (theName2 != null) {
|
||||
next.getName().get(0).getGiven().set(0, theName2);
|
||||
}
|
||||
retVal.add(next);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,6 +86,31 @@ public class DummyPatientResourceProvider implements IResourceProvider {
|
|||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@Read.IdParam IdDt theId) {
|
||||
return myIdToPatient.get(theId.getValue());
|
||||
return getIdToPatient().get(theId.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the resource by its identifier
|
||||
*
|
||||
* @param theId
|
||||
* The resource identity
|
||||
* @return The resource
|
||||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@Read.IdParam IdDt theId, @Read.VersionIdParam IdDt theVersionId) {
|
||||
Patient retVal = getIdToPatient().get(theId.getValue());
|
||||
retVal.getName().get(0).setText(theVersionId.getValue());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Search()
|
||||
public Collection<Patient> getResources() {
|
||||
return getIdToPatient().values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ 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.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
|
@ -52,14 +53,53 @@ public class ResfulServerTest {
|
|||
ourClient = builder.build();
|
||||
|
||||
ourCtx = new FhirContext(Patient.class);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchWithOptionalParam() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name1=AAA");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||
assertEquals("AAA", patient.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
||||
/*
|
||||
* Now with optional value populated
|
||||
*/
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name1=AAA&name2=BBB");
|
||||
status = ourClient.execute(httpGet);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||
assertEquals("AAA", patient.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("BBB", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByParamIdentifier() throws Exception {
|
||||
|
||||
|
@ -68,30 +108,84 @@ public class ResfulServerTest {
|
|||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
Patient patient = (Patient)bundle.getEntries().get(0).getResource();
|
||||
|
||||
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
||||
/**
|
||||
* Alternate form
|
||||
*/
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search?identifier=urn:hapitest:mrns%7C00001");
|
||||
status = ourClient.execute(httpPost);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
||||
/**
|
||||
* failing form
|
||||
*/
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/_search?identifier=urn:hapitest:mrns%7C00001");
|
||||
status = ourClient.execute(httpGet);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(404, status.getStatusLine().getStatusCode());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchAll() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
assertEquals(2, bundle.getEntries().size());
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
||||
status = ourClient.execute(httpPost);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
|
||||
assertEquals(2, bundle.getEntries().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetById() throws Exception {
|
||||
|
||||
// HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/1");
|
||||
// httpPost.setEntity(new StringEntity("test", ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
// HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/1");
|
||||
// httpPost.setEntity(new StringEntity("test", ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(responseContent);
|
||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
@ -99,13 +193,13 @@ public class ResfulServerTest {
|
|||
/*
|
||||
* Different ID
|
||||
*/
|
||||
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2");
|
||||
status = ourClient.execute(httpGet);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.debug("Response was:\n{}", responseContent);
|
||||
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
patient = (Patient) ourCtx.newXmlParser().parseResource(responseContent);
|
||||
assertEquals("PatientTwo", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
|
@ -113,17 +207,34 @@ public class ResfulServerTest {
|
|||
/*
|
||||
* Bad ID
|
||||
*/
|
||||
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/9999999");
|
||||
status = ourClient.execute(httpGet);
|
||||
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.debug("Response was:\n{}", responseContent);
|
||||
|
||||
|
||||
assertEquals(404, status.getStatusLine().getStatusCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByVersionId() throws Exception {
|
||||
|
||||
// HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/1");
|
||||
// httpPost.setEntity(new StringEntity("test", ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/_history/999");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(responseContent);
|
||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||
assertEquals("999", patient.getName().get(0).getText().getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.rest.common.Request;
|
||||
import ca.uhn.fhir.rest.common.SearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.common.BaseMethodBinding.MethodReturnTypeEnum;
|
||||
import ca.uhn.fhir.rest.common.SearchMethodBinding.RequestType;
|
||||
import ca.uhn.fhir.rest.server.Parameter;
|
||||
|
||||
public class ResourceMethodTest {
|
||||
|
@ -38,7 +40,7 @@ public class ResourceMethodTest {
|
|||
inputParams.add("firstName");
|
||||
inputParams.add("lastName");
|
||||
|
||||
assertEquals(false, rm.matches("Patient", null, null, inputParams)); // False
|
||||
assertEquals(false, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -53,7 +55,7 @@ public class ResourceMethodTest {
|
|||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("mrn");
|
||||
assertEquals(true, rm.matches("Patient", null, null, inputParams)); // True
|
||||
assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,7 +72,7 @@ public class ResourceMethodTest {
|
|||
inputParams.add("firstName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
assertEquals(true, rm.matches("Patient", null, null, inputParams)); // True
|
||||
assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -88,7 +90,7 @@ public class ResourceMethodTest {
|
|||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
assertEquals(true, rm.matches("Patient", null, null, inputParams)); // True
|
||||
assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -107,6 +109,6 @@ public class ResourceMethodTest {
|
|||
inputParams.add("mrn");
|
||||
inputParams.add("foo");
|
||||
|
||||
assertEquals(false, rm.matches("Patient", null, null, inputParams)); // False
|
||||
assertEquals(false, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue