Refactor method outcomes abit
This commit is contained in:
parent
e69464f34d
commit
2287011601
|
@ -0,0 +1,61 @@
|
||||||
|
@Override
|
||||||
|
public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException {
|
||||||
|
Object[] params = new Object[getParameters().size()];
|
||||||
|
for (int i = 0; i < getParameters().size(); i++) {
|
||||||
|
IParameter param = getParameters().get(i);
|
||||||
|
if (param != null) {
|
||||||
|
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addParametersForServerRequest(theRequest, params);
|
||||||
|
|
||||||
|
MethodOutcome response = (MethodOutcome) invokeServerMethod(getProvider(), params);
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
if (myReturnVoid == false) {
|
||||||
|
throw new ConfigurationException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null");
|
||||||
|
} else {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
||||||
|
}
|
||||||
|
} else if (!myReturnVoid) {
|
||||||
|
if (response.isCreated()) {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(theRequest.getFhirServerBase());
|
||||||
|
b.append('/');
|
||||||
|
b.append(getResourceName());
|
||||||
|
b.append('/');
|
||||||
|
b.append(response.getId().getValue());
|
||||||
|
if (response.getVersionId() != null && response.getVersionId().isEmpty() == false) {
|
||||||
|
b.append("/_history/");
|
||||||
|
b.append(response.getVersionId().getValue());
|
||||||
|
}
|
||||||
|
theResponse.addHeader("Location", b.toString());
|
||||||
|
} else {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
theServer.addHeadersToResponse(theResponse);
|
||||||
|
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
|
try {
|
||||||
|
if (response != null) {
|
||||||
|
OperationOutcome outcome = new OperationOutcome();
|
||||||
|
if (response.getOperationOutcome() != null && response.getOperationOutcome().getIssue() != null) {
|
||||||
|
outcome.getIssue().addAll(response.getOperationOutcome().getIssue());
|
||||||
|
}
|
||||||
|
EncodingUtil encoding = BaseMethodBinding.determineResponseEncoding(theRequest.getServletRequest(), theRequest.getParameters());
|
||||||
|
theResponse.setContentType(encoding.getResourceContentType());
|
||||||
|
IParser parser = encoding.newParser(getContext());
|
||||||
|
parser.encodeResourceToWriter(outcome, writer);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
// getMethod().in
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
@Override
|
||||||
|
public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException {
|
||||||
|
EncodingUtil encoding = BaseMethodBinding.determineResponseEncoding(theRequest.getServletRequest(), theRequest.getParameters());
|
||||||
|
IParser parser = encoding.newParser(getContext());
|
||||||
|
IResource resource = parser.parseResource(theRequest.getInputReader());
|
||||||
|
|
||||||
|
Object[] params = new Object[getParameters().size()];
|
||||||
|
for (int i = 0; i < getParameters().size(); i++) {
|
||||||
|
IParameter param = getParameters().get(i);
|
||||||
|
if (param == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
addParametersForServerRequest(theRequest, params);
|
||||||
|
|
||||||
|
MethodOutcome response;
|
||||||
|
try {
|
||||||
|
response = (MethodOutcome) invokeServerMethod(getProvider(), params);
|
||||||
|
} catch (BaseServerResponseException e) {
|
||||||
|
streamOperationOutcome(e, theServer, encoding, theResponse);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
if (isReturnVoid() == false) {
|
||||||
|
throw new ConfigurationException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null");
|
||||||
|
}
|
||||||
|
} else if (!isReturnVoid()) {
|
||||||
|
if (response.isCreated()) {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(theRequest.getFhirServerBase());
|
||||||
|
b.append('/');
|
||||||
|
b.append(getResourceName());
|
||||||
|
b.append('/');
|
||||||
|
b.append(response.getId().getValue());
|
||||||
|
if (response.getVersionId() != null && response.getVersionId().isEmpty() == false) {
|
||||||
|
b.append("/_history/");
|
||||||
|
b.append(response.getVersionId().getValue());
|
||||||
|
}
|
||||||
|
theResponse.addHeader("Location", b.toString());
|
||||||
|
} else {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
theServer.addHeadersToResponse(theResponse);
|
||||||
|
|
||||||
|
if (response != null && response.getOperationOutcome() != null) {
|
||||||
|
theResponse.setContentType(encoding.getResourceContentType());
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
|
try {
|
||||||
|
parser.encodeResourceToWriter(response.getOperationOutcome(), writer);
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theResponse.setContentType(Constants.CT_TEXT);
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// getMethod().in
|
||||||
|
}
|
|
@ -26,28 +26,35 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
public class MethodOutcome {
|
public class MethodOutcome {
|
||||||
|
|
||||||
private IdDt myId;
|
private IdDt myId;
|
||||||
private IdDt myVersionId;
|
|
||||||
private boolean myCreated;
|
|
||||||
private OperationOutcome myOperationOutcome;
|
private OperationOutcome myOperationOutcome;
|
||||||
|
private IdDt myVersionId;
|
||||||
|
|
||||||
public MethodOutcome() {
|
public MethodOutcome() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodOutcome(IdDt theId) {
|
public MethodOutcome(IdDt theId) {
|
||||||
myId=theId;
|
myId = theId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodOutcome(boolean theCreated, IdDt theId, IdDt theVersionId) {
|
public MethodOutcome(IdDt theId, IdDt theVersionId) {
|
||||||
super();
|
|
||||||
myId = theId;
|
myId = theId;
|
||||||
myVersionId = theVersionId;
|
myVersionId = theVersionId;
|
||||||
myCreated=theCreated;
|
}
|
||||||
|
|
||||||
|
public MethodOutcome(IdDt theId, IdDt theVersionId, OperationOutcome theOperationOutcome) {
|
||||||
|
myId = theId;
|
||||||
|
myVersionId = theVersionId;
|
||||||
|
myOperationOutcome = theOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdDt getId() {
|
public IdDt getId() {
|
||||||
return myId;
|
return myId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OperationOutcome getOperationOutcome() {
|
||||||
|
return myOperationOutcome;
|
||||||
|
}
|
||||||
|
|
||||||
public IdDt getVersionId() {
|
public IdDt getVersionId() {
|
||||||
return myVersionId;
|
return myVersionId;
|
||||||
}
|
}
|
||||||
|
@ -56,32 +63,12 @@ public class MethodOutcome {
|
||||||
myId = theId;
|
myId = theId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOperationOutcome(OperationOutcome theOperationOutcome) {
|
||||||
|
myOperationOutcome = theOperationOutcome;
|
||||||
|
}
|
||||||
|
|
||||||
public void setVersionId(IdDt theVersionId) {
|
public void setVersionId(IdDt theVersionId) {
|
||||||
myVersionId = theVersionId;
|
myVersionId = theVersionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set to <code>true</code> if the method resulted in the creation of a new resource. Set to
|
|
||||||
* <code>false</code> if the method resulted in an update/modification/removal to an existing resource.
|
|
||||||
*/
|
|
||||||
public boolean isCreated() {
|
|
||||||
return myCreated;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set to <code>true</code> if the method resulted in the creation of a new resource. Set to
|
|
||||||
* <code>false</code> if the method resulted in an update/modification/removal to an existing resource.
|
|
||||||
*/
|
|
||||||
public void setCreated(boolean theCreated) {
|
|
||||||
myCreated=theCreated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOperationOutcome(OperationOutcome theOperationOutcome) {
|
|
||||||
myOperationOutcome=theOperationOutcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationOutcome getOperationOutcome() {
|
|
||||||
return myOperationOutcome;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,8 @@ public abstract class BaseMethodBinding {
|
||||||
|
|
||||||
protected Object invokeServerMethod(Object theResourceProvider, Object[] theMethodParams) {
|
protected Object invokeServerMethod(Object theResourceProvider, Object[] theMethodParams) {
|
||||||
try {
|
try {
|
||||||
return getMethod().invoke(theResourceProvider, theMethodParams);
|
Method method = getMethod();
|
||||||
|
return method.invoke(theResourceProvider, theMethodParams);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
if (e.getCause() instanceof BaseServerResponseException) {
|
if (e.getCause() instanceof BaseServerResponseException) {
|
||||||
throw (BaseServerResponseException) e.getCause();
|
throw (BaseServerResponseException) e.getCause();
|
||||||
|
|
|
@ -38,6 +38,7 @@ import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||||
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||||
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.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
@ -48,6 +49,7 @@ 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.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
@ -65,13 +67,11 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding {
|
||||||
|
|
||||||
if (!theMethod.getReturnType().equals(MethodOutcome.class)) {
|
if (!theMethod.getReturnType().equals(MethodOutcome.class)) {
|
||||||
if (!allowVoidReturnType()) {
|
if (!allowVoidReturnType()) {
|
||||||
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " is a @" + theMethodAnnotation.getSimpleName()
|
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " is a @" + theMethodAnnotation.getSimpleName() + " method but it does not return " + MethodOutcome.class);
|
||||||
+ " method but it does not return " + MethodOutcome.class);
|
|
||||||
} else if (theMethod.getReturnType() == void.class) {
|
} else if (theMethod.getReturnType() == void.class) {
|
||||||
myReturnVoid = true;
|
myReturnVoid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,67 +138,176 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingUtil theEncoding, HttpServletResponse theResponse) throws IOException {
|
||||||
|
theResponse.setStatus(theE.getStatusCode());
|
||||||
|
|
||||||
|
theServer.addHeadersToResponse(theResponse);
|
||||||
|
|
||||||
|
if (theE.getOperationOutcome() != null) {
|
||||||
|
theResponse.setContentType(theEncoding.getResourceContentType());
|
||||||
|
IParser parser = theEncoding.newParser(theServer.getFhirContext());
|
||||||
|
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
|
try {
|
||||||
|
parser.encodeResourceToWriter(theE.getOperationOutcome(), writer);
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theResponse.setContentType(Constants.CT_TEXT);
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
|
try {
|
||||||
|
writer.append(theE.getMessage());
|
||||||
|
} finally {
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @Override public void invokeServer(RestfulServer theServer, Request
|
||||||
|
* theRequest, HttpServletResponse theResponse) throws
|
||||||
|
* BaseServerResponseException, IOException { Object[] params = new
|
||||||
|
* Object[getParameters().size()]; for (int i = 0; i <
|
||||||
|
* getParameters().size(); i++) { IParameter param = getParameters().get(i);
|
||||||
|
* if (param != null) { params[i] =
|
||||||
|
* param.translateQueryParametersIntoServerArgument(theRequest, null); } }
|
||||||
|
*
|
||||||
|
* addParametersForServerRequest(theRequest, params);
|
||||||
|
*
|
||||||
|
* MethodOutcome response = (MethodOutcome)
|
||||||
|
* invokeServerMethod(getProvider(), params);
|
||||||
|
*
|
||||||
|
* if (response == null) { if (myReturnVoid == false) { throw new
|
||||||
|
* ConfigurationException("Method " + getMethod().getName() + " in type " +
|
||||||
|
* getMethod().getDeclaringClass().getCanonicalName() + " returned null"); }
|
||||||
|
* else { theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT); } }
|
||||||
|
* else if (!myReturnVoid) { if (response.isCreated()) {
|
||||||
|
* theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED); StringBuilder b
|
||||||
|
* = new StringBuilder(); b.append(theRequest.getFhirServerBase());
|
||||||
|
* b.append('/'); b.append(getResourceName()); b.append('/');
|
||||||
|
* b.append(response.getId().getValue()); if (response.getVersionId() !=
|
||||||
|
* null && response.getVersionId().isEmpty() == false) {
|
||||||
|
* b.append("/_history/"); b.append(response.getVersionId().getValue()); }
|
||||||
|
* theResponse.addHeader("Location", b.toString()); } else {
|
||||||
|
* theResponse.setStatus(Constants.STATUS_HTTP_200_OK); } } else {
|
||||||
|
* theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT); }
|
||||||
|
*
|
||||||
|
* theServer.addHeadersToResponse(theResponse);
|
||||||
|
*
|
||||||
|
* Writer writer = theResponse.getWriter(); try { if (response != null) {
|
||||||
|
* OperationOutcome outcome = new OperationOutcome(); if
|
||||||
|
* (response.getOperationOutcome() != null &&
|
||||||
|
* response.getOperationOutcome().getIssue() != null) {
|
||||||
|
* outcome.getIssue().addAll(response.getOperationOutcome().getIssue()); }
|
||||||
|
* EncodingUtil encoding =
|
||||||
|
* BaseMethodBinding.determineResponseEncoding(theRequest
|
||||||
|
* .getServletRequest(), theRequest.getParameters());
|
||||||
|
* theResponse.setContentType(encoding.getResourceContentType()); IParser
|
||||||
|
* parser = encoding.newParser(getContext());
|
||||||
|
* parser.encodeResourceToWriter(outcome, writer); } } finally {
|
||||||
|
* writer.close(); } // getMethod().in }
|
||||||
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException {
|
public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException {
|
||||||
|
EncodingUtil encoding = BaseMethodBinding.determineResponseEncoding(theRequest.getServletRequest(), theRequest.getParameters());
|
||||||
|
IParser parser = encoding.newParser(getContext());
|
||||||
|
IResource resource;
|
||||||
|
if (requestContainsResource()) {
|
||||||
|
resource = parser.parseResource(theRequest.getInputReader());
|
||||||
|
} else {
|
||||||
|
resource = null;
|
||||||
|
}
|
||||||
|
|
||||||
Object[] params = new Object[getParameters().size()];
|
Object[] params = new Object[getParameters().size()];
|
||||||
for (int i = 0; i < getParameters().size(); i++) {
|
for (int i = 0; i < getParameters().size(); i++) {
|
||||||
IParameter param = getParameters().get(i);
|
IParameter param = getParameters().get(i);
|
||||||
if (param != null) {
|
if (param == null) {
|
||||||
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, null);
|
continue;
|
||||||
}
|
}
|
||||||
|
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
addParametersForServerRequest(theRequest, params);
|
addParametersForServerRequest(theRequest, params);
|
||||||
|
|
||||||
MethodOutcome response = (MethodOutcome) invokeServerMethod(getProvider(), params);
|
MethodOutcome response;
|
||||||
|
try {
|
||||||
|
response = (MethodOutcome) invokeServerMethod(getProvider(), params);
|
||||||
|
} catch (InternalErrorException e) {
|
||||||
|
ourLog.error("Internal error during method invocation", e);
|
||||||
|
streamOperationOutcome(e, theServer, encoding, theResponse);
|
||||||
|
return;
|
||||||
|
} catch (BaseServerResponseException e) {
|
||||||
|
ourLog.info("Exception during method invocation: "+e.getMessage());
|
||||||
|
streamOperationOutcome(e, theServer, encoding, theResponse);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (getResourceOperationType() == RestfulOperationTypeEnum.CREATE) {
|
||||||
if (myReturnVoid == false) {
|
if (response == null) {
|
||||||
throw new ConfigurationException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null");
|
throw new InternalErrorException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null, which is not allowed for create operation");
|
||||||
} else {
|
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
|
||||||
}
|
}
|
||||||
} else if (!myReturnVoid) {
|
theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||||
if (response.isCreated()) {
|
addLocationHeader(theRequest, theResponse, response);
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
} else if (response == null) {
|
||||||
StringBuilder b = new StringBuilder();
|
if (isReturnVoid() == false) {
|
||||||
b.append(theRequest.getFhirServerBase());
|
throw new InternalErrorException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null");
|
||||||
b.append('/');
|
}
|
||||||
b.append(getResourceName());
|
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
||||||
b.append('/');
|
} else {
|
||||||
b.append(response.getId().getValue());
|
if (response.getOperationOutcome() == null) {
|
||||||
if (response.getVersionId() != null && response.getVersionId().isEmpty() == false) {
|
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
||||||
b.append("/_history/");
|
|
||||||
b.append(response.getVersionId().getValue());
|
|
||||||
}
|
|
||||||
theResponse.addHeader("Location", b.toString());
|
|
||||||
} else {
|
} else {
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||||
}
|
}
|
||||||
} else {
|
if (getResourceOperationType() == RestfulOperationTypeEnum.UPDATE) {
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
addLocationHeader(theRequest, theResponse, response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
theServer.addHeadersToResponse(theResponse);
|
theServer.addHeadersToResponse(theResponse);
|
||||||
|
|
||||||
Writer writer = theResponse.getWriter();
|
if (response != null && response.getOperationOutcome() != null) {
|
||||||
try {
|
theResponse.setContentType(encoding.getResourceContentType());
|
||||||
if (response != null) {
|
Writer writer = theResponse.getWriter();
|
||||||
OperationOutcome outcome = new OperationOutcome();
|
try {
|
||||||
if (response.getOperationOutcome() != null && response.getOperationOutcome().getIssue() != null) {
|
parser.encodeResourceToWriter(response.getOperationOutcome(), writer);
|
||||||
outcome.getIssue().addAll(response.getOperationOutcome().getIssue());
|
} finally {
|
||||||
}
|
writer.close();
|
||||||
EncodingUtil encoding = BaseMethodBinding.determineResponseEncoding(theRequest.getServletRequest(), theRequest.getParameters());
|
|
||||||
theResponse.setContentType(encoding.getResourceContentType());
|
|
||||||
IParser parser = encoding.newParser(getContext());
|
|
||||||
parser.encodeResourceToWriter(outcome, writer);
|
|
||||||
}
|
}
|
||||||
} finally {
|
} else {
|
||||||
|
theResponse.setContentType(Constants.CT_TEXT);
|
||||||
|
Writer writer = theResponse.getWriter();
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMethod().in
|
// getMethod().in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addLocationHeader(Request theRequest, HttpServletResponse theResponse, MethodOutcome response) {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(theRequest.getFhirServerBase());
|
||||||
|
b.append('/');
|
||||||
|
b.append(getResourceName());
|
||||||
|
b.append('/');
|
||||||
|
b.append(response.getId().getValue());
|
||||||
|
if (response.getVersionId() != null && response.getVersionId().isEmpty() == false) {
|
||||||
|
b.append("/_history/");
|
||||||
|
b.append(response.getVersionId().getValue());
|
||||||
|
}
|
||||||
|
theResponse.addHeader("Location", b.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses may override if the incoming request should not contain a
|
||||||
|
* resource
|
||||||
|
*/
|
||||||
|
protected boolean requestContainsResource() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void addParametersForServerRequest(Request theRequest, Object[] theParams);
|
protected abstract void addParametersForServerRequest(Request theRequest, Object[] theParams);
|
||||||
|
|
||||||
public boolean isReturnVoid() {
|
public boolean isReturnVoid() {
|
||||||
|
@ -225,14 +334,15 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For servers, this method will match only incoming requests
|
* For servers, this method will match only incoming requests that match the
|
||||||
* that match the given operation, or which have no operation in the
|
* given operation, or which have no operation in the URL if this method
|
||||||
* URL if this method returns null.
|
* returns null.
|
||||||
*/
|
*/
|
||||||
protected abstract String getMatchingOperation();
|
protected abstract String getMatchingOperation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclasses may override to allow a void method return type, which is allowable for some methods (e.g. delete)
|
* Subclasses may override to allow a void method return type, which is
|
||||||
|
* allowable for some methods (e.g. delete)
|
||||||
*/
|
*/
|
||||||
protected boolean allowVoidReturnType() {
|
protected boolean allowVoidReturnType() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -75,100 +75,9 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException {
|
|
||||||
EncodingUtil encoding = BaseMethodBinding.determineResponseEncoding(theRequest.getServletRequest(), theRequest.getParameters());
|
|
||||||
IParser parser = encoding.newParser(getContext());
|
|
||||||
IResource resource = parser.parseResource(theRequest.getInputReader());
|
|
||||||
|
|
||||||
Object[] params = new Object[getParameters().size()];
|
|
||||||
for (int i = 0; i < getParameters().size(); i++) {
|
|
||||||
IParameter param = getParameters().get(i);
|
|
||||||
if (param == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
addParametersForServerRequest(theRequest, params);
|
|
||||||
|
|
||||||
MethodOutcome response;
|
|
||||||
try {
|
|
||||||
response = (MethodOutcome) invokeServerMethod(getProvider(), params);
|
|
||||||
} catch (BaseServerResponseException e) {
|
|
||||||
streamOperationOutcome(e, theServer, encoding, theResponse);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response == null) {
|
|
||||||
if (isReturnVoid() == false) {
|
|
||||||
throw new ConfigurationException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null");
|
|
||||||
}
|
|
||||||
} else if (!isReturnVoid()) {
|
|
||||||
if (response.isCreated()) {
|
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
|
||||||
StringBuilder b = new StringBuilder();
|
|
||||||
b.append(theRequest.getFhirServerBase());
|
|
||||||
b.append('/');
|
|
||||||
b.append(getResourceName());
|
|
||||||
b.append('/');
|
|
||||||
b.append(response.getId().getValue());
|
|
||||||
if (response.getVersionId() != null && response.getVersionId().isEmpty() == false) {
|
|
||||||
b.append("/_history/");
|
|
||||||
b.append(response.getVersionId().getValue());
|
|
||||||
}
|
|
||||||
theResponse.addHeader("Location", b.toString());
|
|
||||||
} else {
|
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
theResponse.setStatus(Constants.STATUS_HTTP_204_NO_CONTENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
theServer.addHeadersToResponse(theResponse);
|
|
||||||
|
|
||||||
if (response != null && response.getOperationOutcome() != null) {
|
|
||||||
theResponse.setContentType(encoding.getResourceContentType());
|
|
||||||
Writer writer = theResponse.getWriter();
|
|
||||||
try {
|
|
||||||
parser.encodeResourceToWriter(response.getOperationOutcome(), writer);
|
|
||||||
} finally {
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
theResponse.setContentType(Constants.CT_TEXT);
|
|
||||||
Writer writer = theResponse.getWriter();
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// getMethod().in
|
|
||||||
}
|
|
||||||
|
|
||||||
private void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingUtil theEncoding, HttpServletResponse theResponse) throws IOException {
|
|
||||||
theResponse.setStatus(theE.getStatusCode());
|
|
||||||
|
|
||||||
theServer.addHeadersToResponse(theResponse);
|
|
||||||
|
|
||||||
if (theE.getOperationOutcome() != null) {
|
|
||||||
theResponse.setContentType(theEncoding.getResourceContentType());
|
|
||||||
IParser parser = theEncoding.newParser(theServer.getFhirContext());
|
|
||||||
|
|
||||||
Writer writer = theResponse.getWriter();
|
|
||||||
try {
|
|
||||||
parser.encodeResourceToWriter(theE.getOperationOutcome(), writer);
|
|
||||||
} finally {
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
theResponse.setContentType(Constants.CT_TEXT);
|
|
||||||
Writer writer = theResponse.getWriter();
|
|
||||||
try {
|
|
||||||
writer.append(theE.getMessage());
|
|
||||||
} finally {
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getResourceName() {
|
public String getResourceName() {
|
||||||
|
|
|
@ -35,8 +35,6 @@ import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
|
||||||
|
|
||||||
public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam {
|
public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public CreateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
|
public CreateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
|
||||||
super(theMethod, theContext, Create.class, theProvider);
|
super(theMethod, theContext, Create.class, theProvider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,11 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean requestContainsResource() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean allowVoidReturnType() {
|
protected boolean allowVoidReturnType() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -298,7 +298,6 @@ public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||||
// This method returns a MethodOutcome object which contains
|
// This method returns a MethodOutcome object which contains
|
||||||
// the ID and Version ID for the newly saved resource
|
// the ID and Version ID for the newly saved resource
|
||||||
MethodOutcome retVal = new MethodOutcome();
|
MethodOutcome retVal = new MethodOutcome();
|
||||||
retVal.setCreated(true);
|
|
||||||
retVal.setId(new IdDt("3746"));
|
retVal.setId(new IdDt("3746"));
|
||||||
retVal.setVersionId(new IdDt("1"));
|
retVal.setVersionId(new IdDt("1"));
|
||||||
|
|
||||||
|
@ -341,7 +340,6 @@ public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient t
|
||||||
// This method returns a MethodOutcome object which contains
|
// This method returns a MethodOutcome object which contains
|
||||||
// the ID and Version ID for the newly saved resource
|
// the ID and Version ID for the newly saved resource
|
||||||
MethodOutcome retVal = new MethodOutcome();
|
MethodOutcome retVal = new MethodOutcome();
|
||||||
retVal.setCreated(true);
|
|
||||||
retVal.setId(theId);
|
retVal.setId(theId);
|
||||||
retVal.setVersionId(new IdDt("2")); // Leave this blank if the server doesn't version
|
retVal.setVersionId(new IdDt("2")); // Leave this blank if the server doesn't version
|
||||||
|
|
||||||
|
|
|
@ -124,8 +124,7 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("Location").getValue());
|
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("Location").getValue());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithUnprocessableEntity() throws Exception {
|
public void testCreateWithUnprocessableEntity() throws Exception {
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ public class ResfulServerMethodTest {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
assertEquals(422, status.getStatusLine().getStatusCode());
|
assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
OperationOutcome outcome = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, new StringReader(responseContent));
|
OperationOutcome outcome = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, new StringReader(responseContent));
|
||||||
assertEquals("FOOBAR", outcome.getIssueFirstRep().getDetails().getValue());
|
assertEquals("FOOBAR", outcome.getIssueFirstRep().getDetails().getValue());
|
||||||
|
|
||||||
|
@ -244,7 +243,8 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
Patient patient = (Patient) ourCtx.newJsonParser().parseResource(responseContent);
|
Patient patient = (Patient) ourCtx.newJsonParser().parseResource(responseContent);
|
||||||
// assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
// assertEquals("PatientOne",
|
||||||
|
// patient.getName().get(0).getGiven().get(0).getValue());
|
||||||
|
|
||||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
|
||||||
|
|
||||||
|
@ -371,10 +371,12 @@ public class ResfulServerMethodTest {
|
||||||
// @Test
|
// @Test
|
||||||
// public void testSearchByComplex() throws Exception {
|
// public void testSearchByComplex() throws Exception {
|
||||||
//
|
//
|
||||||
// HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?Patient.identifier=urn:oid:2.16.840.1.113883.3.239.18.148%7C7000135&name=urn:oid:1.3.6.1.4.1.12201.102.5%7C522&date=");
|
// HttpGet httpGet = new HttpGet("http://localhost:" + ourPort +
|
||||||
|
// "/Patient?Patient.identifier=urn:oid:2.16.840.1.113883.3.239.18.148%7C7000135&name=urn:oid:1.3.6.1.4.1.12201.102.5%7C522&date=");
|
||||||
// HttpResponse status = ourClient.execute(httpGet);
|
// HttpResponse status = ourClient.execute(httpGet);
|
||||||
//
|
//
|
||||||
// String responseContent = IOUtils.toString(status.getEntity().getContent());
|
// String responseContent =
|
||||||
|
// IOUtils.toString(status.getEntity().getContent());
|
||||||
// ourLog.info("Response was:\n{}", responseContent);
|
// ourLog.info("Response was:\n{}", responseContent);
|
||||||
//
|
//
|
||||||
// assertEquals(200, status.getStatusLine().getStatusCode());
|
// assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
@ -586,7 +588,6 @@ public class ResfulServerMethodTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByDobWithSearchActionAndPost() throws Exception {
|
public void testSearchByDobWithSearchActionAndPost() throws Exception {
|
||||||
|
|
||||||
|
@ -605,8 +606,8 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
||||||
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
||||||
|
|
||||||
// POST
|
// POST
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search?dob=2011-01-02");
|
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search?dob=2011-01-02");
|
||||||
status = ourClient.execute(httpPost);
|
status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
@ -622,8 +623,8 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
||||||
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
||||||
|
|
||||||
// POST with form encoded
|
// POST with form encoded
|
||||||
|
|
||||||
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
||||||
List<BasicNameValuePair> urlParameters = new ArrayList<BasicNameValuePair>();
|
List<BasicNameValuePair> urlParameters = new ArrayList<BasicNameValuePair>();
|
||||||
urlParameters.add(new BasicNameValuePair("dob", "2011-01-02"));
|
urlParameters.add(new BasicNameValuePair("dob", "2011-01-02"));
|
||||||
|
@ -642,9 +643,8 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
assertEquals("NONE", patient.getIdentifier().get(1).getValue().getValue());
|
||||||
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
assertEquals("2011-01-02", patient.getIdentifier().get(2).getValue().getValue());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByMultipleIdentifiers() throws Exception {
|
public void testSearchByMultipleIdentifiers() throws Exception {
|
||||||
|
|
||||||
|
@ -851,64 +851,50 @@ public class ResfulServerMethodTest {
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
OperationOutcome oo =new FhirContext().newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
||||||
|
assertEquals("OODETAILS", oo.getIssueFirstRep().getDetails().getValue());
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("Location").getValue());
|
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("Location").getValue());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidate() throws Exception {
|
public void testUpdateWrongResourceType() throws Exception {
|
||||||
|
|
||||||
|
// TODO: this method sends in the wrong resource type vs. the URL so it should
|
||||||
|
// give a useful error message
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addFamily("FOO");
|
patient.addIdentifier().setValue("002");
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
HttpResponse status = ourClient.execute(httpPost);
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
assertEquals("http://localhost:" + ourPort + "/DiagnosticReport/001/_history/002", status.getFirstHeader("Location").getValue());
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
|
||||||
OperationOutcome oo = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
|
||||||
assertEquals("it passed", oo.getIssueFirstRep().getDetails().getValue());
|
|
||||||
|
|
||||||
// Now should fail
|
|
||||||
|
|
||||||
patient = new Patient();
|
|
||||||
patient.addName().addFamily("BAR");
|
|
||||||
|
|
||||||
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
|
||||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
|
||||||
|
|
||||||
status = ourClient.execute(httpPost);
|
|
||||||
|
|
||||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(422, status.getStatusLine().getStatusCode());
|
|
||||||
oo = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
|
||||||
assertEquals("it failed", oo.getIssueFirstRep().getDetails().getValue());
|
|
||||||
|
|
||||||
// Should fail with outcome
|
|
||||||
|
|
||||||
patient = new Patient();
|
|
||||||
patient.addName().addFamily("BAZ");
|
|
||||||
|
|
||||||
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
|
||||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
|
||||||
|
|
||||||
status = ourClient.execute(httpPost);
|
|
||||||
|
|
||||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
|
||||||
assertEquals("", responseContent);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNoResponse() throws Exception {
|
||||||
|
|
||||||
|
DiagnosticReport dr = new DiagnosticReport();
|
||||||
|
dr.addCodedDiagnosis().addCoding().setCode("AAA");
|
||||||
|
|
||||||
|
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||||
|
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(dr), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
assertEquals(204, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals("http://localhost:" + ourPort + "/DiagnosticReport/001/_history/002", status.getFirstHeader("Location").getValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateWithVersion() throws Exception {
|
public void testUpdateWithVersion() throws Exception {
|
||||||
|
|
||||||
|
@ -946,6 +932,59 @@ public class ResfulServerMethodTest {
|
||||||
assertEquals(400, results.getStatusLine().getStatusCode());
|
assertEquals(400, results.getStatusLine().getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidate() throws Exception {
|
||||||
|
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addName().addFamily("FOO");
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
||||||
|
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
OperationOutcome oo = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
||||||
|
assertEquals("it passed", oo.getIssueFirstRep().getDetails().getValue());
|
||||||
|
|
||||||
|
// Now should fail
|
||||||
|
|
||||||
|
patient = new Patient();
|
||||||
|
patient.addName().addFamily("BAR");
|
||||||
|
|
||||||
|
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
||||||
|
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
|
status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(422, status.getStatusLine().getStatusCode());
|
||||||
|
oo = new FhirContext().newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
||||||
|
assertEquals("it failed", oo.getIssueFirstRep().getDetails().getValue());
|
||||||
|
|
||||||
|
// Should fail with outcome
|
||||||
|
|
||||||
|
patient = new Patient();
|
||||||
|
patient.addName().addFamily("BAZ");
|
||||||
|
|
||||||
|
httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate");
|
||||||
|
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
|
status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals("", responseContent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClass() throws Exception {
|
public static void afterClass() throws Exception {
|
||||||
ourServer.stop();
|
ourServer.stop();
|
||||||
|
@ -985,6 +1024,14 @@ public class ResfulServerMethodTest {
|
||||||
throw new ResourceNotFoundException("AAAABBBB");
|
throw new ResourceNotFoundException("AAAABBBB");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Create()
|
||||||
|
public MethodOutcome createDiagnosticReport(@ResourceParam DiagnosticReport thePatient) {
|
||||||
|
OperationOutcome outcome = new OperationOutcome();
|
||||||
|
outcome.addIssue().setDetails("FOOBAR");
|
||||||
|
throw new UnprocessableEntityException(outcome);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Delete()
|
@Delete()
|
||||||
public void deleteDiagnosticReport(@IdParam IdDt theId) {
|
public void deleteDiagnosticReport(@IdParam IdDt theId) {
|
||||||
|
@ -998,21 +1045,12 @@ public class ResfulServerMethodTest {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Update()
|
@Update()
|
||||||
public MethodOutcome updateDiagnosticReportWithVersion(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam DiagnosticReport thePatient) {
|
public MethodOutcome updateDiagnosticReportWithVersionAndNoResponse(@IdParam IdDt theId, @ResourceParam DiagnosticReport thePatient) {
|
||||||
IdDt id = theId;
|
IdDt id = theId;
|
||||||
IdDt version = theVersionId;
|
IdDt version = new IdDt("002");
|
||||||
return new MethodOutcome(true, id, version);
|
return new MethodOutcome(id, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Create()
|
|
||||||
public MethodOutcome createDiagnosticReport(@ResourceParam DiagnosticReport thePatient) {
|
|
||||||
OperationOutcome outcome = new OperationOutcome();
|
|
||||||
outcome.addIssue().setDetails("FOOBAR");
|
|
||||||
throw new UnprocessableEntityException(outcome);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1024,37 +1062,7 @@ public class ResfulServerMethodTest {
|
||||||
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||||
IdDt id = new IdDt(thePatient.getIdentifier().get(0).getValue().getValue());
|
IdDt id = new IdDt(thePatient.getIdentifier().get(0).getValue().getValue());
|
||||||
IdDt version = new IdDt(thePatient.getIdentifier().get(1).getValue().getValue());
|
IdDt version = new IdDt(thePatient.getIdentifier().get(1).getValue().getValue());
|
||||||
return new MethodOutcome(true, id, version);
|
return new MethodOutcome(id, version);
|
||||||
}
|
|
||||||
|
|
||||||
@Validate()
|
|
||||||
public MethodOutcome validatePatient(@ResourceParam Patient thePatient) {
|
|
||||||
if (thePatient.getNameFirstRep().getFamilyFirstRep().getValueNotNull().equals("FOO")) {
|
|
||||||
MethodOutcome methodOutcome = new MethodOutcome();
|
|
||||||
OperationOutcome oo = new OperationOutcome();
|
|
||||||
oo.addIssue().setDetails("it passed");
|
|
||||||
methodOutcome.setOperationOutcome(oo);
|
|
||||||
return methodOutcome;
|
|
||||||
}
|
|
||||||
if (thePatient.getNameFirstRep().getFamilyFirstRep().getValueNotNull().equals("BAR")) {
|
|
||||||
throw new UnprocessableEntityException("it failed");
|
|
||||||
}
|
|
||||||
return new MethodOutcome();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Patient createPatient1() {
|
|
||||||
Patient patient = new Patient();
|
|
||||||
patient.addIdentifier();
|
|
||||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
|
||||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
|
||||||
patient.getIdentifier().get(0).setValue("00001");
|
|
||||||
patient.addName();
|
|
||||||
patient.getName().get(0).addFamily("Test");
|
|
||||||
patient.getName().get(0).addGiven("PatientOne");
|
|
||||||
patient.getGender().setText("M");
|
|
||||||
patient.getId().setValue("1");
|
|
||||||
return patient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete()
|
@Delete()
|
||||||
|
@ -1066,8 +1074,8 @@ public class ResfulServerMethodTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public List<Patient> findDiagnosticReportsByPatient(@RequiredParam(name = "Patient.identifier") IdentifierDt thePatientId,
|
public List<Patient> findDiagnosticReportsByPatient(@RequiredParam(name = "Patient.identifier") IdentifierDt thePatientId, @RequiredParam(name = DiagnosticReport.SP_NAME) CodingListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange)
|
||||||
@RequiredParam(name = DiagnosticReport.SP_NAME) CodingListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange) throws Exception {
|
throws Exception {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1201,8 +1209,7 @@ public class ResfulServerMethodTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Search()
|
@Search()
|
||||||
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString,
|
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString, @IncludeParam(allow = { "include1", "include2", "include3" }) List<PathSpecification> theIncludes) {
|
||||||
@IncludeParam(allow = { "include1", "include2", "include3" }) List<PathSpecification> theIncludes) {
|
|
||||||
Patient next = getIdToPatient().get("1");
|
Patient next = getIdToPatient().get("1");
|
||||||
|
|
||||||
next.addCommunication().setText(theString.getValue());
|
next.addCommunication().setText(theString.getValue());
|
||||||
|
@ -1276,19 +1283,52 @@ public class ResfulServerMethodTest {
|
||||||
@Update()
|
@Update()
|
||||||
public MethodOutcome updateDiagnosticReportWithVersion(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam DiagnosticReport thePatient) {
|
public MethodOutcome updateDiagnosticReportWithVersion(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam DiagnosticReport thePatient) {
|
||||||
/*
|
/*
|
||||||
* TODO: THIS METHOD IS NOT USED. It's the wrong type (DiagnosticReport), so it should cause an exception on startup. Also we should detect if there are multiple resource params on an
|
* TODO: THIS METHOD IS NOT USED. It's the wrong type
|
||||||
|
* (DiagnosticReport), so it should cause an exception on startup.
|
||||||
|
* Also we should detect if there are multiple resource params on an
|
||||||
* update/create/etc method
|
* update/create/etc method
|
||||||
*/
|
*/
|
||||||
IdDt id = theId;
|
IdDt id = theId;
|
||||||
IdDt version = theVersionId;
|
IdDt version = theVersionId;
|
||||||
return new MethodOutcome(true, id, version);
|
return new MethodOutcome(id, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Update()
|
@Update()
|
||||||
public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient thePatient) {
|
public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient thePatient) {
|
||||||
IdDt id = theId;
|
IdDt id = theId;
|
||||||
IdDt version = new IdDt(thePatient.getIdentifierFirstRep().getValue().getValue());
|
IdDt version = new IdDt(thePatient.getIdentifierFirstRep().getValue().getValue());
|
||||||
return new MethodOutcome(true, id, version);
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
oo.addIssue().setDetails("OODETAILS");
|
||||||
|
return new MethodOutcome(id, version, oo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validate()
|
||||||
|
public MethodOutcome validatePatient(@ResourceParam Patient thePatient) {
|
||||||
|
if (thePatient.getNameFirstRep().getFamilyFirstRep().getValueNotNull().equals("FOO")) {
|
||||||
|
MethodOutcome methodOutcome = new MethodOutcome();
|
||||||
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
oo.addIssue().setDetails("it passed");
|
||||||
|
methodOutcome.setOperationOutcome(oo);
|
||||||
|
return methodOutcome;
|
||||||
|
}
|
||||||
|
if (thePatient.getNameFirstRep().getFamilyFirstRep().getValueNotNull().equals("BAR")) {
|
||||||
|
throw new UnprocessableEntityException("it failed");
|
||||||
|
}
|
||||||
|
return new MethodOutcome();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Patient createPatient1() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addIdentifier();
|
||||||
|
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||||
|
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||||
|
patient.getIdentifier().get(0).setValue("00001");
|
||||||
|
patient.addName();
|
||||||
|
patient.getName().get(0).addFamily("Test");
|
||||||
|
patient.getName().get(0).addGiven("PatientOne");
|
||||||
|
patient.getGender().setText("M");
|
||||||
|
patient.getId().setValue("1");
|
||||||
|
return patient;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class RestfulPatientResourceProvider implements IResourceProvider {
|
||||||
* @return Returns a resource matching this identifier, or null if none exists.
|
* @return Returns a resource matching this identifier, or null if none exists.
|
||||||
*/
|
*/
|
||||||
@Read()
|
@Read()
|
||||||
public Patient getResourceById(@IdParam IdDt theId) {
|
public Patient getPatientById(@IdParam IdDt theId) {
|
||||||
Patient retVal;
|
Patient retVal;
|
||||||
try {
|
try {
|
||||||
retVal = myIdToPatientMap.get(theId.asLong());
|
retVal = myIdToPatientMap.get(theId.asLong());
|
||||||
|
@ -80,17 +80,17 @@ public class RestfulPatientResourceProvider implements IResourceProvider {
|
||||||
* The "@Search" annotation indicates that this method supports the search operation. You may have many different method annotated with this annotation, to support many different search criteria.
|
* The "@Search" annotation indicates that this method supports the search operation. You may have many different method annotated with this annotation, to support many different search criteria.
|
||||||
* This example searches by family name.
|
* This example searches by family name.
|
||||||
*
|
*
|
||||||
* @param theIdentifier
|
* @param theFamilyName
|
||||||
* This operation takes one parameter which is the search criteria. It is annotated with the "@Required" annotation. This annotation takes one argument, a string containing the name of
|
* This operation takes one parameter which is the search criteria. It is annotated with the "@Required" annotation. This annotation takes one argument, a string containing the name of
|
||||||
* the search criteria. The datatype here is StringDt, but there are other possible parameter types depending on the specific search criteria.
|
* the search criteria. The datatype here is StringDt, but there are other possible parameter types depending on the specific search criteria.
|
||||||
* @return This method returns a list of Patients. This list may contain multiple matching resources, or it may also be empty.
|
* @return This method returns a list of Patients. This list may contain multiple matching resources, or it may also be empty.
|
||||||
*/
|
*/
|
||||||
@Search()
|
@Search()
|
||||||
public List<Patient> getPatient(@RequiredParam(name = Patient.SP_FAMILY) StringDt theFamilyName) {
|
public List<Patient> findPatientsByName(@RequiredParam(name = Patient.SP_FAMILY) StringDt theFamilyName) {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look for all patients matching this
|
* Look for all patients matching the name
|
||||||
*/
|
*/
|
||||||
for (Patient nextPatient : myIdToPatientMap.values()) {
|
for (Patient nextPatient : myIdToPatientMap.values()) {
|
||||||
NAMELOOP:
|
NAMELOOP:
|
||||||
|
@ -109,16 +109,13 @@ public class RestfulPatientResourceProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "@Search" annotation indicates that this method supports the search operation. You may have many different method annotated with this annotation, to support many different search criteria.
|
* The "@Create" annotation indicates that this method supports creating a new resource
|
||||||
* This example searches by family name.
|
|
||||||
*
|
*
|
||||||
* @param theIdentifier
|
* @param thePatient This is the actual resource to save
|
||||||
* This operation takes one parameter which is the search criteria. It is annotated with the "@Required" annotation. This annotation takes one argument, a string containing the name of
|
* @return This method returns a "MethodOutcome"
|
||||||
* the search criteria. The datatype here is StringDt, but there are other possible parameter types depending on the specific search criteria.
|
|
||||||
* @return This method returns a list of Patients. This list may contain multiple matching resources, or it may also be empty.
|
|
||||||
*/
|
*/
|
||||||
@Create()
|
@Create()
|
||||||
public MethodOutcome getPatient(@ResourceParam Patient thePatient) {
|
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||||
/*
|
/*
|
||||||
* Our server will have a rule that patients must
|
* Our server will have a rule that patients must
|
||||||
* have a family name or we will reject them
|
* have a family name or we will reject them
|
||||||
|
@ -128,6 +125,40 @@ public class RestfulPatientResourceProvider implements IResourceProvider {
|
||||||
outcome.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("No last name provided");
|
outcome.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("No last name provided");
|
||||||
throw new UnprocessableEntityException(outcome);
|
throw new UnprocessableEntityException(outcome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long id = myNextId++;
|
||||||
|
myIdToPatientMap.put(id, thePatient);
|
||||||
|
|
||||||
|
// Let the caller know the ID of the newly created resource
|
||||||
|
return new MethodOutcome(new IdDt(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "@Search" annotation indicates that this method supports the search operation. You may have many different method annotated with this annotation, to support many different search criteria.
|
||||||
|
* This example searches by family name.
|
||||||
|
*
|
||||||
|
* @param theIdentifier
|
||||||
|
* This operation takes one parameter which is the search criteria. It is annotated with the "@Required" annotation. This annotation takes one argument, a string containing the name of
|
||||||
|
* the search criteria. The datatype here is StringDt, but there are other possible parameter types depending on the specific search criteria.
|
||||||
|
* @return This method returns a list of Patients. This list may contain multiple matching resources, or it may also be empty.
|
||||||
|
*/
|
||||||
|
@Create()
|
||||||
|
public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
|
||||||
|
/*
|
||||||
|
* Our server will have a rule that patients must
|
||||||
|
* have a family name or we will reject them
|
||||||
|
*/
|
||||||
|
if (thePatient.getNameFirstRep().getFamilyFirstRep().isEmpty()) {
|
||||||
|
OperationOutcome outcome = new OperationOutcome();
|
||||||
|
outcome.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("No last name provided");
|
||||||
|
throw new UnprocessableEntityException(outcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
long id = myNextId++;
|
||||||
|
myIdToPatientMap.put(id, thePatient);
|
||||||
|
|
||||||
|
// Let the caller know the ID of the newly created resource
|
||||||
|
return new MethodOutcome(new IdDt(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue