Fix broken unit tests and begin preparing for non-resource specific items
This commit is contained in:
parent
5da4698fab
commit
0b93dcc491
|
@ -3,6 +3,8 @@ package ca.uhn.fhir.rest.annotation;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
/**
|
||||
|
@ -14,5 +16,15 @@ import java.lang.annotation.RetentionPolicy;
|
|||
* </p>
|
||||
*/
|
||||
public @interface Create {
|
||||
// nothing
|
||||
|
||||
/**
|
||||
* The return type for this search method. This generally does not need
|
||||
* to be populated for a server implementation, since servers will return
|
||||
* only one resource per class, but generally does need to be populated
|
||||
* for client implementations.
|
||||
*/
|
||||
// NB: Read, Search (maybe others) share this annotation, so update the javadocs everywhere
|
||||
Class<? extends IResource> type() default IResource.class;
|
||||
|
||||
|
||||
}
|
|
@ -20,11 +20,12 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
@Target(value=ElementType.METHOD)
|
||||
public @interface Delete {
|
||||
|
||||
Class<? extends IResource> resourceType() default NotSpecified.class;
|
||||
|
||||
|
||||
interface NotSpecified extends IResource{
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* The return type for this search method. This generally does not need
|
||||
* to be populated for a server implementation, since servers will return
|
||||
* only one resource per class, but generally does need to be populated
|
||||
* for client implementations.
|
||||
*/
|
||||
// NB: Read, Search (maybe others) share this annotation, so update the javadocs everywhere
|
||||
Class<? extends IResource> type() default IResource.class;
|
||||
}
|
|
@ -57,11 +57,6 @@ public @interface History {
|
|||
* The resource type that this method applies to. See the {@link History History annotation type documentation}
|
||||
* for information on usage patterns.
|
||||
*/
|
||||
Class<? extends IResource> resourceType() default AllResources.class;
|
||||
|
||||
|
||||
interface AllResources extends IResource {
|
||||
// nothing
|
||||
}
|
||||
Class<? extends IResource> type() default IResource.class;
|
||||
|
||||
}
|
|
@ -5,6 +5,8 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
/**
|
||||
* RESTful method annotation to be used for the FHIR
|
||||
* <a href="http://hl7.org/implement/standards/fhir/http.html#update">update</a> method.
|
||||
|
@ -18,4 +20,13 @@ import java.lang.annotation.Target;
|
|||
@Target(value=ElementType.METHOD)
|
||||
public @interface Update {
|
||||
|
||||
/**
|
||||
* The return type for this search method. This generally does not need
|
||||
* to be populated for a server implementation, since servers will return
|
||||
* only one resource per class, but generally does need to be populated
|
||||
* for client implementations.
|
||||
*/
|
||||
// NB: Read, Search (maybe others) share this annotation, so update the javadocs everywhere
|
||||
Class<? extends IResource> type() default IResource.class;
|
||||
|
||||
}
|
|
@ -13,10 +13,8 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
public class RestfulClientFactory implements IRestfulClientFactory {
|
||||
|
||||
|
@ -51,7 +49,6 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
* @throws ConfigurationException
|
||||
* If the interface type is not an interface
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized <T extends IRestfulClient> T newClient(Class<T> theClientType, String theServerBase) {
|
||||
if (!theClientType.isInterface()) {
|
||||
|
@ -68,20 +65,8 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
ClientInvocationHandler invocationHandler = myInvocationHandlers.get(theClientType);
|
||||
if (invocationHandler == null) {
|
||||
invocationHandler = new ClientInvocationHandler(client, myContext, serverBase, theClientType);
|
||||
|
||||
for (Method nextMethod : theClientType.getMethods()) {
|
||||
Class<? extends IResource> resReturnType = null;
|
||||
Class<?> returnType = nextMethod.getReturnType();
|
||||
if (IResource.class.isAssignableFrom(returnType)) {
|
||||
resReturnType = (Class<? extends IResource>) returnType;
|
||||
} else if (java.util.Collection.class.isAssignableFrom(returnType)) {
|
||||
Class<?> returnTypeColl = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(nextMethod);
|
||||
if (!IResource.class.isAssignableFrom(returnTypeColl)) {
|
||||
throw new ConfigurationException("Generic type of collection for method '" + nextMethod + "' is not a subclass of IResource");
|
||||
}
|
||||
resReturnType = (Class<? extends IResource>) returnTypeColl;
|
||||
}
|
||||
BaseMethodBinding binding = BaseMethodBinding.bindMethod(resReturnType, nextMethod, myContext,null);
|
||||
BaseMethodBinding binding = BaseMethodBinding.bindMethod(nextMethod, myContext, null);
|
||||
invocationHandler.addBinding(nextMethod, binding);
|
||||
}
|
||||
myInvocationHandlers.put(theClientType, invocationHandler);
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.rest.method;
|
|||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -14,7 +15,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -30,6 +30,7 @@ import ca.uhn.fhir.rest.annotation.Metadata;
|
|||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.BaseClientInvocation;
|
||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -55,6 +56,13 @@ public abstract class BaseMethodBinding {
|
|||
myProvider = theProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the resource this method handles, or <code>null</code> if this
|
||||
* method is not resource specific
|
||||
*/
|
||||
public abstract String getResourceName();
|
||||
|
||||
|
||||
public Object getProvider() {
|
||||
return myProvider;
|
||||
}
|
||||
|
@ -87,6 +95,7 @@ public abstract class BaseMethodBinding {
|
|||
return parser;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static BaseMethodBinding bindMethod(Method theMethod, FhirContext theContext, Object theProvider) {
|
||||
Read read = theMethod.getAnnotation(Read.class);
|
||||
Search search = theMethod.getAnnotation(Search.class);
|
||||
|
@ -100,53 +109,84 @@ public abstract class BaseMethodBinding {
|
|||
return null;
|
||||
}
|
||||
|
||||
Class<? extends IResource> returnType;
|
||||
|
||||
Class<? extends IResource> returnTypeFromRp = null;
|
||||
if (theProvider instanceof IResourceProvider) {
|
||||
returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType();
|
||||
if (!verifyIsValidResourceReturnType(returnTypeFromRp)) {
|
||||
throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned " + toLogString(returnTypeFromRp) + " - Must return a resource type");
|
||||
throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned "
|
||||
+ toLogString(returnTypeFromRp) + " - Must return a resource type");
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> returnTypeFromMethod = theMethod.getReturnType();
|
||||
if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
|
||||
if (MethodOutcome.class.equals(returnTypeFromMethod)) {
|
||||
// returns a method outcome
|
||||
}else if (Bundle.class.equals(returnTypeFromMethod)) {
|
||||
// returns a bundle
|
||||
}else if (void.class.equals(returnTypeFromMethod)) {
|
||||
// returns a bundle
|
||||
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
|
||||
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
|
||||
if (!verifyIsValidResourceReturnType(returnTypeFromMethod)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
|
||||
+ " returns a collection with generic type " + toLogString(returnTypeFromMethod) + " - Must return a resource type or a collection (List, Set) of a resource type");
|
||||
}
|
||||
} else {
|
||||
if (!verifyIsValidResourceReturnType(returnTypeFromMethod)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
|
||||
+ " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Bundle.class.isAssignableFrom(returnTypeFromMethod)) {
|
||||
returnTypeFromMethod = returnTypeFromRp;
|
||||
}
|
||||
if (!IResource.class.isAssignableFrom(returnTypeFromMethod)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return a resource type");
|
||||
Class<? extends IResource> returnTypeFromAnnotation = IResource.class;
|
||||
if (read != null) {
|
||||
returnTypeFromAnnotation = read.type();
|
||||
} else if (search != null) {
|
||||
returnTypeFromAnnotation = search.type();
|
||||
} else if (history != null) {
|
||||
returnTypeFromAnnotation = history.type();
|
||||
} else if (delete != null) {
|
||||
returnTypeFromAnnotation = delete.type();
|
||||
} else if (create != null) {
|
||||
returnTypeFromAnnotation = create.type();
|
||||
} else if (update != null) {
|
||||
returnTypeFromAnnotation = update.type();
|
||||
}
|
||||
|
||||
if (returnTypeFromRp != null) {
|
||||
if (returnTypeFromRp.equals(returnTypeFromMethod) == false) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " but must return " + returnTypeFromRp.getCanonicalName());
|
||||
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
|
||||
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type "
|
||||
+ returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract");
|
||||
}
|
||||
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type "
|
||||
+ returnTypeFromAnnotation.getCanonicalName() + " per method annotation - Must return " + returnTypeFromRp.getCanonicalName()
|
||||
+ " (or a subclass of it) per IResourceProvider contract");
|
||||
}
|
||||
returnType = returnTypeFromAnnotation;
|
||||
} else {
|
||||
returnType = returnTypeFromRp;
|
||||
}
|
||||
} else {
|
||||
if (returnTypeFromAnnotation != IResource.class) {
|
||||
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
|
||||
throw new ConfigurationException("Method '"+theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns "
|
||||
+ toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type");
|
||||
}
|
||||
returnType=returnTypeFromAnnotation;
|
||||
} else {
|
||||
returnType = (Class<? extends IResource>) returnTypeFromMethod;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnTypeFromMethod == null) {
|
||||
if (read != null) {
|
||||
returnTypeFromMethod = read.type();
|
||||
} else if (search != null) {
|
||||
returnTypeFromMethod = search.type();
|
||||
}
|
||||
|
||||
if (returnTypeFromMethod == IResource.class) {
|
||||
throw new ConfigurationException("Could not determine return type for method '" + theMethod.getName() + "'. Try explicitly specifying one in the operation annotation.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends IResource> retType = (Class<? extends IResource>) returnTypeFromMethod;
|
||||
|
||||
if (read != null) {
|
||||
return new ReadMethodBinding(retType, theMethod, theContext, theProvider);
|
||||
return new ReadMethodBinding(returnType, theMethod, theContext, theProvider);
|
||||
} else if (search != null) {
|
||||
String queryName = search.queryName();
|
||||
return new SearchMethodBinding(retType, theMethod, queryName, theContext, theProvider);
|
||||
return new SearchMethodBinding(returnType, theMethod, queryName, theContext, theProvider);
|
||||
} else if (conformance != null) {
|
||||
return new ConformanceMethodBinding(theMethod, theContext, theProvider);
|
||||
} else if (create != null) {
|
||||
|
@ -184,16 +224,18 @@ public abstract class BaseMethodBinding {
|
|||
}
|
||||
|
||||
private static boolean verifyIsValidResourceReturnType(Class<?> theReturnType) {
|
||||
if (theReturnType==null) {
|
||||
if (theReturnType == null) {
|
||||
return false;
|
||||
}
|
||||
if (!IResource.class.isAssignableFrom(theReturnType)) {
|
||||
return false;
|
||||
}
|
||||
boolean retVal = Modifier.isAbstract(theReturnType.getModifiers()) == false;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static String toLogString(Class<? extends IResource> theType) {
|
||||
if (theType==null) {
|
||||
private static String toLogString(Class<?> theType) {
|
||||
if (theType == null) {
|
||||
return null;
|
||||
}
|
||||
return theType.getCanonicalName();
|
||||
|
@ -206,8 +248,8 @@ public abstract class BaseMethodBinding {
|
|||
if (obj1 == null) {
|
||||
obj1 = object;
|
||||
} else {
|
||||
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @" + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName()
|
||||
+ ". Can not have both.");
|
||||
throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @"
|
||||
+ obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName() + ". Can not have both.");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -263,11 +305,7 @@ public abstract class BaseMethodBinding {
|
|||
|
||||
public abstract void invokeServer(RestfulServer theServer, Request theRequest, HttpServletResponse theResponse) throws BaseServerResponseException, IOException;
|
||||
|
||||
public abstract Object invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException;
|
||||
|
||||
public static BaseMethodBinding bindSystemMethod(Method theMethod, FhirContext theContext) {
|
||||
return bindMethod(null, theMethod, theContext, null);
|
||||
}
|
||||
|
||||
public abstract Object invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException;
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
|||
theProvider);
|
||||
|
||||
Delete deleteAnnotation = theMethod.getAnnotation(Delete.class);
|
||||
Class<? extends IResource> resourceType = deleteAnnotation.resourceType();
|
||||
if (resourceType != Delete.NotSpecified.class) {
|
||||
Class<? extends IResource> resourceType = deleteAnnotation.type();
|
||||
if (resourceType != IResource.class) {
|
||||
RuntimeResourceDefinition def = theContext.getResourceDefinition(resourceType);
|
||||
myResourceName = def.getName();
|
||||
} else {
|
||||
|
|
|
@ -43,8 +43,8 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
myCountParamIndex = Util.findCountParameterIndex(theMethod);
|
||||
|
||||
History historyAnnotation = theMethod.getAnnotation(History.class);
|
||||
Class<? extends IResource> type = historyAnnotation.resourceType();
|
||||
if (type == History.AllResources.class) {
|
||||
Class<? extends IResource> type = historyAnnotation.type();
|
||||
if (type == IResource.class) {
|
||||
if (theProvider instanceof IResourceProvider) {
|
||||
type = ((IResourceProvider) theProvider).getResourceType();
|
||||
if (myIdParamIndex != null) {
|
||||
|
@ -66,7 +66,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
mySystemOperationType = null;
|
||||
}
|
||||
|
||||
if (type != History.AllResources.class) {
|
||||
if (type != IResource.class) {
|
||||
myResourceName = theConetxt.getResourceDefinition(type).getName();
|
||||
} else {
|
||||
myResourceName = null;
|
||||
|
@ -79,8 +79,8 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
return ((IResourceProvider) theProvider).getResourceType();
|
||||
}
|
||||
History historyAnnotation = theMethod.getAnnotation(History.class);
|
||||
Class<? extends IResource> type = historyAnnotation.resourceType();
|
||||
if (type != History.AllResources.class) {
|
||||
Class<? extends IResource> type = historyAnnotation.type();
|
||||
if (type != IResource.class) {
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
|
@ -26,7 +27,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
private int myParameterCount;
|
||||
|
||||
public ReadMethodBinding(Class<? extends IResource> theAnnotatedResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
||||
super( theAnnotatedResourceType, theMethod, theContext, theProvider);
|
||||
super(theAnnotatedResourceType, theMethod, theContext, theProvider);
|
||||
|
||||
Validate.notNull(theMethod, "Method must not be null");
|
||||
|
||||
|
@ -39,10 +40,10 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
Class<?>[] parameterTypes = theMethod.getParameterTypes();
|
||||
if (!IdDt.class.equals(parameterTypes[myIdIndex])) {
|
||||
throw new ConfigurationException("ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: "+parameterTypes[myIdIndex]);
|
||||
throw new ConfigurationException("ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myIdIndex]);
|
||||
}
|
||||
if (myVersionIdIndex != null && !IdDt.class.equals(parameterTypes[myVersionIdIndex])) {
|
||||
throw new ConfigurationException("Version ID parameter must be of type: " + IdDt.class.getCanonicalName()+ " - Found: "+parameterTypes[myVersionIdIndex]);
|
||||
throw new ConfigurationException("Version ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myVersionIdIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,6 +72,13 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
ourLog.trace("Method {} doesn't match because request type is not GET: {}", theRequest.getId(), theRequest.getRequestType());
|
||||
return false;
|
||||
}
|
||||
if (Constants.PARAM_HISTORY.equals(theRequest.getOperation())) {
|
||||
if (myVersionIdIndex == null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!StringUtils.isBlank(theRequest.getOperation())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -80,8 +88,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> invokeServer(Object theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> theParameterValues) throws InvalidRequestException,
|
||||
InternalErrorException {
|
||||
public List<IResource> invokeServer(Object theResourceProvider, IdDt theId, IdDt theVersionId, Map<String, String[]> theParameterValues) throws InvalidRequestException, InternalErrorException {
|
||||
Object[] params = new Object[myParameterCount];
|
||||
params[myIdIndex] = theId;
|
||||
if (myVersionIdIndex != null) {
|
||||
|
@ -92,7 +99,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
try {
|
||||
response = getMethod().invoke(theResourceProvider, params);
|
||||
} catch (Exception e) {
|
||||
throw new InternalErrorException("Failed to call access method",e);
|
||||
throw new InternalErrorException("Failed to call access method", e);
|
||||
}
|
||||
|
||||
return toResourceList(response);
|
||||
|
@ -100,11 +107,11 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
@Override
|
||||
public GetClientInvocation invokeClient(Object[] theArgs) {
|
||||
String id = ((IdDt)theArgs[myIdIndex]).getValue();
|
||||
String id = ((IdDt) theArgs[myIdIndex]).getValue();
|
||||
if (myVersionIdIndex == null) {
|
||||
return new GetClientInvocation(getResourceName(), id);
|
||||
}else {
|
||||
String vid = ((IdDt)theArgs[myVersionIdIndex]).getValue();
|
||||
} else {
|
||||
String vid = ((IdDt) theArgs[myVersionIdIndex]).getValue();
|
||||
return new GetClientInvocation(getResourceName(), id, Constants.URL_TOKEN_HISTORY, vid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,11 +129,11 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
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) {
|
||||
if (theRequest.getRequestType() == RequestType.GET && theRequest.getOperation() != null && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) {
|
||||
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())) {
|
||||
if (theRequest.getRequestType() == RequestType.POST && !Constants.PARAM_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;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ public class Constants {
|
|||
public static final int STATUS_HTTP_204_NO_CONTENT = 204;
|
||||
public static final String PARAM_COUNT = "_count";
|
||||
public static final String PARAM_SINCE = "_since";
|
||||
public static final String PARAM_SEARCH = "_search";
|
||||
|
||||
static {
|
||||
Map<String, EncodingUtil> valToEncoding = new HashMap<String, EncodingUtil>();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
@ -292,7 +293,7 @@ public class RestfulServer extends HttpServlet {
|
|||
BaseMethodBinding foundMethodBinding = BaseMethodBinding.bindMethod(m, myFhirContext, theProvider);
|
||||
if (foundMethodBinding != null) {
|
||||
|
||||
RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(retType);
|
||||
RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(foundMethodBinding.getResourceName());
|
||||
ResourceBinding resourceBinding;
|
||||
if (myResourceNameToProvider.containsKey(definition.getName())) {
|
||||
resourceBinding = myResourceNameToProvider.get(definition.getName());
|
||||
|
@ -318,7 +319,7 @@ public class RestfulServer extends HttpServlet {
|
|||
if (Modifier.isPublic(m.getModifiers())) {
|
||||
ourLog.debug("Scanning public method: {}#{}", theSystemProvider.getClass(), m.getName());
|
||||
|
||||
BaseMethodBinding foundMethodBinding = BaseMethodBinding.bindSystemMethod(m, myFhirContext);
|
||||
BaseMethodBinding foundMethodBinding = BaseMethodBinding.bindMethod(m, myFhirContext, theSystemProvider);
|
||||
if (foundMethodBinding != null) {
|
||||
if (foundMethodBinding instanceof ConformanceMethodBinding) {
|
||||
myServerConformanceMethod = foundMethodBinding;
|
||||
|
@ -476,7 +477,11 @@ public class RestfulServer extends HttpServlet {
|
|||
r.setOperation(operation);
|
||||
r.setParameters(params);
|
||||
r.setRequestType(requestType);
|
||||
if ("application/x-www-form-urlencoded".equals(request.getContentType())) {
|
||||
r.setInputReader(new StringReader(""));
|
||||
} else {
|
||||
r.setInputReader(request.getReader());
|
||||
}
|
||||
r.setFhirServerBase(fhirServerBase);
|
||||
r.setCompleteUrl(completeUrl);
|
||||
r.setServletRequest(request);
|
||||
|
|
|
@ -375,11 +375,11 @@ public interface HistoryClient {
|
|||
Bundle getHistoryServer();
|
||||
|
||||
// Type level (history of all resources of a given type)
|
||||
@History(resourceType=Patient.class)
|
||||
@History(type=Patient.class)
|
||||
Bundle getHistoryPatientType();
|
||||
|
||||
// Instance level (history of a specific resource instance by type and ID)
|
||||
@History(resourceType=Patient.class)
|
||||
@History(type=Patient.class)
|
||||
Bundle getHistoryPatientInstance(@IdParam IdDt theId);
|
||||
//END SNIPPET: historyClient
|
||||
|
||||
|
|
|
@ -56,10 +56,10 @@ public interface ITestClient extends IBasicClient {
|
|||
@Update
|
||||
public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient thePatient);
|
||||
|
||||
@Delete(resourceType=DiagnosticReport.class)
|
||||
@Delete(type=DiagnosticReport.class)
|
||||
void deleteDiagnosticReport(@IdParam IdDt theId);
|
||||
|
||||
@Delete(resourceType=Patient.class)
|
||||
@Delete(type=Patient.class)
|
||||
MethodOutcome deletePatient(@IdParam IdDt theId);
|
||||
|
||||
@Search(type=Patient.class)
|
||||
|
@ -68,10 +68,10 @@ public interface ITestClient extends IBasicClient {
|
|||
@Search(type=Patient.class)
|
||||
Bundle findPatientByName(@RequiredParam(name = Patient.SP_FAMILY) StringDt theId, @OptionalParam(name=Patient.SP_GIVEN) StringDt theGiven);
|
||||
|
||||
@History(resourceType=Patient.class)
|
||||
@History(type=Patient.class)
|
||||
Bundle getHistoryPatientInstance(@IdParam IdDt theId);
|
||||
|
||||
@History(resourceType=Patient.class)
|
||||
@History(type=Patient.class)
|
||||
Bundle getHistoryPatientType();
|
||||
|
||||
@History
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,11 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.api.BaseResource;
|
||||
|
@ -10,15 +14,20 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ConfigurationException;
|
||||
|
||||
public class ServerInvalidDefinitionTest {
|
||||
|
||||
@Test(expected=ConfigurationException.class)
|
||||
public void testNonInstantiableTypeForResourceProvider() throws ServletException {
|
||||
@Test
|
||||
public void testNonInstantiableTypeForResourceProvider() {
|
||||
RestfulServer srv = new RestfulServer();
|
||||
srv.setResourceProviders(new NonInstantiableTypeForResourceProvider());
|
||||
|
||||
try {
|
||||
srv.init();
|
||||
fail();
|
||||
} catch (ServletException e) {
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("ConfigurationException"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue