diff --git a/hapi-fhir-base/.project b/hapi-fhir-base/.project
index 790dcdc0123..7afe06363c3 100644
--- a/hapi-fhir-base/.project
+++ b/hapi-fhir-base/.project
@@ -15,6 +15,11 @@
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
org.eclipse.jem.workbench.JavaEMFNature
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeDeclaredChildDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeDeclaredChildDefinition.java
index e80d020c3d7..ac628d13763 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeDeclaredChildDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeDeclaredChildDefinition.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.context;
+/*
+ * #%L
+ * HAPI FHIR - Core Library
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java
index c1fe60cc1f4..0931f84ef90 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java
@@ -67,7 +67,7 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.UrlUtil;
-abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding {
+public abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding {
protected static final Set ALLOWED_PARAMS;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReturningMethodBinding.class);
@@ -102,8 +102,8 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding collectionType = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
if (collectionType != null) {
if (!Object.class.equals(collectionType) && !IBaseResource.class.isAssignableFrom(collectionType)) {
- throw new ConfigurationException("Method " + theMethod.getDeclaringClass().getSimpleName() + "#" + theMethod.getName() + " returns an invalid collection generic type: "
- + collectionType);
+ throw new ConfigurationException(
+ "Method " + theMethod.getDeclaringClass().getSimpleName() + "#" + theMethod.getName() + " returns an invalid collection generic type: " + collectionType);
}
}
myResourceListCollectionType = collectionType;
@@ -121,8 +121,8 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
-
- // Determine response encoding
- EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest(), theServer.getDefaultResponseEncoding());
-
- // Is this request coming from a browser
- String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
- boolean requestIsBrowser = false;
- if (uaHeader != null && uaHeader.contains("Mozilla")) {
- requestIsBrowser = true;
- }
-
byte[] requestContents = loadRequestContents(theRequest);
-
+
+ final ResourceOrDstu1Bundle responseObject = invokeServer(theServer, theRequest, requestContents);
+
+ Set summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
+ if (responseObject.getResource() != null) {
+
+ for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
+ IServerInterceptor next = theServer.getInterceptors().get(i);
+ boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getResource(), theRequest.getServletRequest(), theRequest.getServletResponse());
+ if (!continueProcessing) {
+ return;
+ }
+ }
+
+ boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest);
+ HttpServletResponse response = theRequest.getServletResponse();
+ RestfulServerUtils.streamResponseAsResource(theServer, response, responseObject.getResource(), prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(),
+ isAddContentLocationHeader(), theRequest);
+ } else {
+ // Is this request coming from a browser
+ String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
+ boolean requestIsBrowser = false;
+ if (uaHeader != null && uaHeader.contains("Mozilla")) {
+ requestIsBrowser = true;
+ }
+
+ for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
+ IServerInterceptor next = theServer.getInterceptors().get(i);
+ boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getDstu1Bundle(), theRequest.getServletRequest(), theRequest.getServletResponse());
+ if (!continueProcessing) {
+ ourLog.debug("Interceptor {} returned false, not continuing processing");
+ return;
+ }
+ }
+
+ HttpServletResponse response = theRequest.getServletResponse();
+ RestfulServerUtils.streamResponseAsBundle(theServer, response, responseObject.getDstu1Bundle(), theRequest.getFhirServerBase(), summaryMode, theRequest.isRespondGzip(), requestIsBrowser,
+ theRequest);
+ }
+ }
+
+ public ResourceOrDstu1Bundle invokeServer(RestfulServer theServer, RequestDetails theRequest, byte[] requestContents) {
// Method params
Object[] params = new Object[getParameters().size()];
for (int i = 0; i < getParameters().size(); i++) {
@@ -267,9 +290,10 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding parameters = theRequest.getParameters();
@@ -323,17 +347,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding= 0; i--) {
- IServerInterceptor next = theServer.getInterceptors().get(i);
- boolean continueProcessing = next.outgoingResponse(theRequest, resource, theRequest.getServletRequest(), theRequest.getServletResponse());
- if (!continueProcessing) {
- ourLog.debug("Interceptor {} returned false, not continuing processing");
- return;
- }
- }
-
- RestfulServerUtils.streamResponseAsResource(theServer, response, resource, prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, respondGzip,
- isAddContentLocationHeader(), theRequest);
+ responseObject = new ResourceOrDstu1Bundle(resource);
break;
} else {
Set includes = getRequestIncludesFromParams(params);
@@ -344,32 +358,18 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding= 0; i--) {
- IServerInterceptor next = theServer.getInterceptors().get(i);
- boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(), theRequest.getServletResponse());
- if (!continueProcessing) {
- ourLog.debug("Interceptor {} returned false, not continuing processing");
- return;
- }
- }
- RestfulServerUtils.streamResponseAsBundle(theServer, response, bundle, theRequest.getFhirServerBase(), summaryMode, respondGzip, requestIsBrowser, theRequest);
+ responseObject = new ResourceOrDstu1Bundle(bundle);
} else {
IBaseResource resBundle = bundleFactory.getResourceBundle();
- for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
- IServerInterceptor next = theServer.getInterceptors().get(i);
- boolean continueProcessing = next.outgoingResponse(theRequest, resBundle, theRequest.getServletRequest(), theRequest.getServletResponse());
- if (!continueProcessing) {
- ourLog.debug("Interceptor {} returned false, not continuing processing");
- return;
- }
- }
- RestfulServerUtils.streamResponseAsResource(theServer, response, resBundle, prettyPrint, summaryMode,
- Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), isAddContentLocationHeader(), theRequest);
+ responseObject = new ResourceOrDstu1Bundle(resBundle);
}
break;
@@ -384,22 +384,17 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding= 0; i--) {
- IServerInterceptor next = theServer.getInterceptors().get(i);
- boolean continueProcessing = next.outgoingResponse(theRequest, resource, theRequest.getServletRequest(), theRequest.getServletResponse());
- if (!continueProcessing) {
- return;
- }
- }
-
- RestfulServerUtils.streamResponseAsResource(theServer, response, resource, prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, respondGzip,
- isAddContentLocationHeader(), theRequest);
+ responseObject = new ResourceOrDstu1Bundle(resource);
break;
}
+ default:
+ throw new IllegalStateException(); // should not happen
}
+ return responseObject;
}
+ public abstract Object invokeServer(RestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException;
+
/**
* Should the response include a Content-Location header. Search method bunding (and any others?) may override this to disable the content-location, since it doesn't make sense
*/
@@ -412,7 +407,32 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding responseResources = retVal.getResources(0, 1);
IBaseResource responseResource = responseResources.get(0);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
index c26ede12486..b4aa63017d7 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
@@ -37,6 +37,7 @@ import ca.uhn.fhir.rest.server.RestfulServer;
public class RequestDetails {
+ private Map> myHeaders = new HashMap>();
private String myCompartmentName;
private String myCompleteUrl;
private String myFhirServerBase;
@@ -230,4 +231,22 @@ public class RequestDetails {
return retVal;
}
+ public void addHeader(String theName, String theValue) {
+ String lowerCase = theName.toLowerCase();
+ ArrayList list = myHeaders.get(lowerCase);
+ if (list == null) {
+ list = new ArrayList();
+ myHeaders.put(lowerCase, list);
+ }
+ list.add(theValue);
+ }
+
+ public String getFirstHeader(String theName) {
+ ArrayList list = myHeaders.get(theName.toLowerCase());
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ return list.get(0);
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetailsParameter.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetailsParameter.java
new file mode 100644
index 00000000000..adab1dcb613
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetailsParameter.java
@@ -0,0 +1,55 @@
+package ca.uhn.fhir.rest.method;
+
+/*
+ * #%L
+ * HAPI FHIR - Core Library
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.hl7.fhir.instance.model.api.IBaseResource;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+
+class RequestDetailsParameter implements IParameter {
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RequestDetailsParameter.class);
+
+ @Override
+ public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
+ /*
+ * Does nothing, since we just ignore HttpServletRequest arguments
+ */
+ ourLog.trace("Ignoring RequestDetailsParameter argument: {}", theSourceClientArgument);
+ }
+
+ @Override
+ public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, byte[] theRequestContents, BaseMethodBinding> theMethodBinding) throws InternalErrorException, InvalidRequestException {
+ return theRequest;
+ }
+
+ @Override
+ public void initializeTypes(Method theMethod, Class extends Collection>> theOuterCollectionType, Class extends Collection>> theInnerCollectionType, Class> theParameterType) {
+ // ignore
+ }
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
index 3f4026bb9f1..73a936c60d1 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
@@ -52,9 +52,6 @@ import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
-/**
- * Created by dsotnikov on 2/25/2014.
- */
public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchMethodBinding.class);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
index a18a8dd5544..ef00e1a79e6 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -477,14 +478,14 @@ public class RestfulServer extends HttpServlet {
return;
}
- Integer count = RestfulServerUtils.extractCountParameter(theRequest.getServletRequest());
+ Integer count = RestfulServerUtils.extractCountParameter(theRequest);
if (count == null) {
count = getPagingProvider().getDefaultPageSize();
} else if (count > getPagingProvider().getMaximumPageSize()) {
count = getPagingProvider().getMaximumPageSize();
}
- Integer offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest.getServletRequest(), Constants.PARAM_PAGINGOFFSET);
+ Integer offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_PAGINGOFFSET);
if (offsetI == null || offsetI < 0) {
offsetI = 0;
}
@@ -545,6 +546,12 @@ public class RestfulServer extends HttpServlet {
requestDetails.setRequestType(theRequestType);
requestDetails.setServletRequest(theRequest);
requestDetails.setServletResponse(theResponse);
+ for (Enumeration iter = theRequest.getHeaderNames(); iter.hasMoreElements(); ) {
+ String nextName = iter.nextElement();
+ for (Enumeration valueIter = theRequest.getHeaders(nextName); valueIter.hasMoreElements();) {
+ requestDetails.addHeader(nextName, valueIter.nextElement());
+ }
+ }
try {
@@ -556,7 +563,6 @@ public class RestfulServer extends HttpServlet {
}
}
- String resourceName = null;
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
StringBuffer requestUrl = theRequest.getRequestURL();
@@ -572,11 +578,9 @@ public class RestfulServer extends HttpServlet {
ourLog.trace("Context Path: {}", servletContextPath);
}
- IdDt id = null;
- String operation = null;
- String compartment = null;
-
+
String requestPath = getRequestPath(requestFullPath, servletContextPath, servletPath);
+
if (requestPath.length() > 0 && requestPath.charAt(0) == '/') {
requestPath = requestPath.substring(1);
}
@@ -588,84 +592,16 @@ public class RestfulServer extends HttpServlet {
Map params = new HashMap(theRequest.getParameterMap());
requestDetails.setParameters(params);
- StringTokenizer tok = new StringTokenizer(requestPath, "/");
- if (tok.hasMoreTokens()) {
- resourceName = tok.nextToken();
- if (partIsOperation(resourceName)) {
- operation = resourceName;
- resourceName = null;
- }
- }
- requestDetails.setResourceName(resourceName);
-
- ResourceBinding resourceBinding = null;
- BaseMethodBinding> resourceMethod = null;
- if (Constants.URL_TOKEN_METADATA.equals(resourceName) || theRequestType == RequestTypeEnum.OPTIONS) {
- resourceMethod = myServerConformanceMethod;
- } else if (resourceName == null) {
- resourceBinding = myServerBinding;
- } else {
- resourceBinding = myResourceNameToBinding.get(resourceName);
- if (resourceBinding == null) {
- throw new InvalidRequestException("Unknown resource type '" + resourceName + "' - Server knows how to handle: " + myResourceNameToBinding.keySet());
- }
- }
-
- if (tok.hasMoreTokens()) {
- String nextString = tok.nextToken();
- if (partIsOperation(nextString)) {
- operation = nextString;
- } else {
- id = new IdDt(resourceName, UrlUtil.unescape(nextString));
- }
- }
-
- if (tok.hasMoreTokens()) {
- String nextString = tok.nextToken();
- if (nextString.equals(Constants.PARAM_HISTORY)) {
- if (tok.hasMoreTokens()) {
- String versionString = tok.nextToken();
- if (id == null) {
- throw new InvalidRequestException("Don't know how to handle request path: " + requestPath);
- }
- id = new IdDt(resourceName, id.getIdPart(), UrlUtil.unescape(versionString));
- } else {
- operation = Constants.PARAM_HISTORY;
- }
- } else if (partIsOperation(nextString)) {
- if (operation != null) {
- throw new InvalidRequestException("URL Path contains two operations: " + requestPath);
- }
- operation = nextString;
- } else {
- compartment = nextString;
- }
- }
-
- // Secondary is for things like ..../_tags/_delete
- String secondaryOperation = null;
-
- while (tok.hasMoreTokens()) {
- String nextString = tok.nextToken();
- if (operation == null) {
- operation = nextString;
- } else if (secondaryOperation == null) {
- secondaryOperation = nextString;
- } else {
- throw new InvalidRequestException("URL path has unexpected token '" + nextString + "' at the end: " + requestPath);
- }
- }
+ IdDt id;
+ populateRequestDetailsFromRequestPath(requestDetails, requestPath);
if (theRequestType == RequestTypeEnum.PUT) {
String contentLocation = theRequest.getHeader(Constants.HEADER_CONTENT_LOCATION);
if (contentLocation != null) {
id = new IdDt(contentLocation);
+ requestDetails.setId(id);
}
}
- requestDetails.setId(id);
- requestDetails.setOperation(operation);
- requestDetails.setSecondaryOperation(secondaryOperation);
- requestDetails.setCompartmentName(compartment);
String acceptEncoding = theRequest.getHeader(Constants.HEADER_ACCEPT_ENCODING);
boolean respondGzip = false;
@@ -696,18 +632,7 @@ public class RestfulServer extends HttpServlet {
return;
}
- if (resourceMethod == null) {
- if (resourceBinding != null) {
- resourceMethod = resourceBinding.getMethod(requestDetails);
- }
- }
- if (resourceMethod == null) {
- if (isBlank(requestPath)) {
- throw new InvalidRequestException(myFhirContext.getLocalizer().getMessage(RestfulServer.class, "rootRequest"));
- } else {
- throw new InvalidRequestException(myFhirContext.getLocalizer().getMessage(RestfulServer.class, "unknownMethod", theRequestType.name(), requestPath, params.keySet()));
- }
- }
+ BaseMethodBinding> resourceMethod = determineResourceMethod(requestDetails, requestPath);
requestDetails.setRestOperationType(resourceMethod.getRestOperationType());
@@ -806,6 +731,105 @@ public class RestfulServer extends HttpServlet {
}
}
+ public BaseMethodBinding> determineResourceMethod(RequestDetails requestDetails, String requestPath) {
+ RequestTypeEnum requestType = requestDetails.getRequestType();
+
+ ResourceBinding resourceBinding = null;
+ BaseMethodBinding> resourceMethod = null;
+ String resourceName = requestDetails.getResourceName();
+ if (Constants.URL_TOKEN_METADATA.equals(resourceName) || requestType == RequestTypeEnum.OPTIONS) {
+ resourceMethod = myServerConformanceMethod;
+ } else if (resourceName == null) {
+ resourceBinding = myServerBinding;
+ } else {
+ resourceBinding = myResourceNameToBinding.get(resourceName);
+ if (resourceBinding == null) {
+ throw new InvalidRequestException("Unknown resource type '" + resourceName + "' - Server knows how to handle: " + myResourceNameToBinding.keySet());
+ }
+ }
+
+ if (resourceMethod == null) {
+ if (resourceBinding != null) {
+ resourceMethod = resourceBinding.getMethod(requestDetails);
+ }
+ }
+ if (resourceMethod == null) {
+ if (isBlank(requestPath)) {
+ throw new InvalidRequestException(myFhirContext.getLocalizer().getMessage(RestfulServer.class, "rootRequest"));
+ } else {
+ throw new InvalidRequestException(myFhirContext.getLocalizer().getMessage(RestfulServer.class, "unknownMethod", requestType.name(), requestPath, requestDetails.getParameters().keySet()));
+ }
+ }
+ return resourceMethod;
+ }
+
+ public void populateRequestDetailsFromRequestPath(RequestDetails theRequestDetails, String theRequestPath) {
+ StringTokenizer tok = new StringTokenizer(theRequestPath, "/");
+ String resourceName = null;
+
+ IdDt id = null;
+ String operation = null;
+ String compartment = null;
+ if (tok.hasMoreTokens()) {
+ resourceName = tok.nextToken();
+ if (partIsOperation(resourceName)) {
+ operation = resourceName;
+ resourceName = null;
+ }
+ }
+ theRequestDetails.setResourceName(resourceName);
+
+ if (tok.hasMoreTokens()) {
+ String nextString = tok.nextToken();
+ if (partIsOperation(nextString)) {
+ operation = nextString;
+ } else {
+ id = new IdDt(resourceName, UrlUtil.unescape(nextString));
+ }
+ }
+
+ if (tok.hasMoreTokens()) {
+ String nextString = tok.nextToken();
+ if (nextString.equals(Constants.PARAM_HISTORY)) {
+ if (tok.hasMoreTokens()) {
+ String versionString = tok.nextToken();
+ if (id == null) {
+ throw new InvalidRequestException("Don't know how to handle request path: " + theRequestPath);
+ }
+ id = new IdDt(resourceName, id.getIdPart(), UrlUtil.unescape(versionString));
+ } else {
+ operation = Constants.PARAM_HISTORY;
+ }
+ } else if (partIsOperation(nextString)) {
+ if (operation != null) {
+ throw new InvalidRequestException("URL Path contains two operations: " + theRequestPath);
+ }
+ operation = nextString;
+ } else {
+ compartment = nextString;
+ }
+ }
+
+ // Secondary is for things like ..../_tags/_delete
+ String secondaryOperation = null;
+
+ while (tok.hasMoreTokens()) {
+ String nextString = tok.nextToken();
+ if (operation == null) {
+ operation = nextString;
+ } else if (secondaryOperation == null) {
+ secondaryOperation = nextString;
+ } else {
+ throw new InvalidRequestException("URL path has unexpected token '" + nextString + "' at the end: " + theRequestPath);
+ }
+ }
+
+ theRequestDetails.setId(id);
+ theRequestDetails.setOperation(operation);
+ theRequestDetails.setSecondaryOperation(secondaryOperation);
+ theRequestDetails.setCompartmentName(compartment);
+ }
+
/**
* Initializes the server. Note that this method is final to avoid accidentally introducing bugs in implementations, but subclasses may put initialization code in {@link #initialize()}, which is
* called immediately before beginning initialization of the restful server's internal init.
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
index f0cf84d7250..5f13cb2b324 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
@@ -394,8 +394,9 @@ public class RestfulServerUtils {
return retVal;
}
- public static Integer extractCountParameter(HttpServletRequest theRequest) {
- return RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_COUNT);
+ public static Integer extractCountParameter(RequestDetails theRequest) {
+ String paramName = Constants.PARAM_COUNT;
+ return tryToExtractNamedParameter(theRequest, paramName);
}
public static IParser getNewParser(FhirContext theContext, RequestDetails theRequestDetails) {
@@ -674,18 +675,18 @@ public class RestfulServerUtils {
}
}
- static Integer tryToExtractNamedParameter(HttpServletRequest theRequest, String name) {
- String countString = theRequest.getParameter(name);
- Integer count = null;
- if (isNotBlank(countString)) {
- try {
- count = Integer.parseInt(countString);
- } catch (NumberFormatException e) {
- ourLog.debug("Failed to parse _count value '{}': {}", countString, e);
- }
- }
- return count;
- }
+// static Integer tryToExtractNamedParameter(HttpServletRequest theRequest, String name) {
+// String countString = theRequest.getParameter(name);
+// Integer count = null;
+// if (isNotBlank(countString)) {
+// try {
+// count = Integer.parseInt(countString);
+// } catch (NumberFormatException e) {
+// ourLog.debug("Failed to parse _count value '{}': {}", countString, e);
+// }
+// }
+// return count;
+// }
public static void validateResourceListNotNull(List extends IBaseResource> theResourceList) {
if (theResourceList == null) {
@@ -701,4 +702,17 @@ public class RestfulServerUtils {
}
}
+ public static Integer tryToExtractNamedParameter(RequestDetails theRequest, String theParamName) {
+ String[] retVal = theRequest.getParameters().get(theParamName);
+ if (retVal == null) {
+ return null;
+ }
+ try {
+ return Integer.parseInt(retVal[0]);
+ } catch (NumberFormatException e) {
+ ourLog.debug("Failed to parse {} value '{}': {}", new Object[] {theParamName, retVal[0], e});
+ return null;
+ }
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java
index b5dfc950b2a..8359edae06d 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/UrlUtil.java
@@ -187,7 +187,7 @@ public class UrlUtil {
char nextChar = url.charAt(idx);
boolean atEnd = (idx + 1) == url.length();
if (nextChar == '?' || nextChar == '/' || atEnd) {
- int endIdx = atEnd ? idx + 1 : idx;
+ int endIdx = (atEnd && nextChar != '?') ? idx + 1 : idx;
String nextSubstring = url.substring(nextStart, endIdx);
if (retVal.getResourceType() == null) {
retVal.setResourceType(nextSubstring);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/schematron/SchematronProvider.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/schematron/SchematronProvider.java
index a48abde04b1..82997ef1327 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/schematron/SchematronProvider.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/schematron/SchematronProvider.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.validation.schematron;
+/*
+ * #%L
+ * HAPI FHIR - Core Library
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import java.lang.reflect.Constructor;
import ca.uhn.fhir.context.FhirContext;
diff --git a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/WebsocketSubscribeCommand.java b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/WebsocketSubscribeCommand.java
index 82f762a7456..3f62b076604 100644
--- a/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/WebsocketSubscribeCommand.java
+++ b/hapi-fhir-cli/src/main/java/ca/uhn/fhir/cli/WebsocketSubscribeCommand.java
@@ -8,6 +8,7 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
@@ -100,8 +101,12 @@ public class WebsocketSubscribeCommand extends BaseCommand {
@OnWebSocketFrame
public void onFrame(Frame theFrame) {
- ourLog.info("Websocket frame: {}", theFrame);
- myQuit = true;
+ ourLog.debug("Websocket frame: {}", theFrame);
+ }
+
+ @OnWebSocketClose
+ public void onClose(int statusCode, String reason) {
+ ourLog.info("Received CLOSE status={} reason={}", statusCode, reason);
}
@OnWebSocketConnect
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java
index f7feb361d22..2b302234187 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseConfig.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.config;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu1Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu1Config.java
index 78b24f7ec90..51a9b8aac30 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu1Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu1Config.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.config;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import java.util.List;
import org.springframework.beans.factory.annotation.Autowire;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu2Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu2Config.java
index d06555616fe..9fd9a5df70d 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu2Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/BaseDstu2Config.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.config;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/WebsocketDstu2Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/WebsocketDstu2Config.java
index df988da814f..2e4ea229d30 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/WebsocketDstu2Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/WebsocketDstu2Config.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.config;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
index 570c416f71c..3a9292b9323 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
@@ -802,22 +802,7 @@ public abstract class BaseHapiFhirDao implements IDao {
public static SearchParameterMap translateMatchUrl(String theMatchUrl, RuntimeResourceDefinition resourceDef) {
SearchParameterMap paramMap = new SearchParameterMap();
- List parameters;
- String matchUrl = theMatchUrl;
- int questionMarkIndex = matchUrl.indexOf('?');
- if (questionMarkIndex != -1) {
- matchUrl = matchUrl.substring(questionMarkIndex + 1);
- }
- matchUrl = matchUrl.replace("|", "%7C");
- matchUrl = matchUrl.replace("=>=", "=%3E%3D");
- matchUrl = matchUrl.replace("=<=", "=%3C%3D");
- matchUrl = matchUrl.replace("=>", "=%3E");
- matchUrl = matchUrl.replace("=<", "=%3C");
- if (matchUrl.contains(" ")) {
- throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - URL is invalid (must not contain spaces)");
- }
-
- parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&');
+ List parameters = translateMatchUrl(theMatchUrl);
ArrayListMultimap nameToParamLists = ArrayListMultimap.create();
for (NameValuePair next : parameters) {
@@ -891,6 +876,26 @@ public abstract class BaseHapiFhirDao implements IDao {
return paramMap;
}
+ protected static List translateMatchUrl(String theMatchUrl) {
+ List parameters;
+ String matchUrl = theMatchUrl;
+ int questionMarkIndex = matchUrl.indexOf('?');
+ if (questionMarkIndex != -1) {
+ matchUrl = matchUrl.substring(questionMarkIndex + 1);
+ }
+ matchUrl = matchUrl.replace("|", "%7C");
+ matchUrl = matchUrl.replace("=>=", "=%3E%3D");
+ matchUrl = matchUrl.replace("=<=", "=%3C%3D");
+ matchUrl = matchUrl.replace("=>", "=%3E");
+ matchUrl = matchUrl.replace("=<", "=%3C");
+ if (matchUrl.contains(" ")) {
+ throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - URL is invalid (must not contain spaces)");
+ }
+
+ parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&');
+ return parameters;
+ }
+
@Override
public void registerDaoListener(IDaoListener theListener) {
Validate.notNull(theListener, "theListener");
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSearchParameterDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSearchParameterDstu2.java
index 6f1210d209e..ecd483ea18d 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSearchParameterDstu2.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSearchParameterDstu2.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSearchDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSearchDao.java
index 235cc471b43..53707a0a4c8 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSearchDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSearchDao.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1.java
index 16f79a65a38..fd2c690e07f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1.java
@@ -44,6 +44,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
+import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
@@ -59,7 +60,7 @@ public class FhirSystemDaoDstu1 extends BaseHapiFhirSystemDao> {
@Transactional(propagation = Propagation.REQUIRED)
@Override
- public List transaction(List theResources) {
+ public List transaction(RequestDetails theRequestDetails, List theResources) {
ourLog.info("Beginning transaction with {} resources", theResources.size());
// Notify interceptors
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
index 1345274c576..da7c2077323 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
@@ -23,6 +23,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -32,15 +33,19 @@ import java.util.Set;
import javax.persistence.TypedQuery;
+import org.apache.http.NameValuePair;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
+import com.google.common.collect.ArrayListMultimap;
+
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.entity.TagDefinition;
import ca.uhn.fhir.model.api.IResource;
@@ -57,13 +62,19 @@ import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
-import ca.uhn.fhir.rest.method.MethodUtil;
+import ca.uhn.fhir.rest.method.BaseMethodBinding;
+import ca.uhn.fhir.rest.method.BaseResourceReturningMethodBinding;
+import ca.uhn.fhir.rest.method.BaseResourceReturningMethodBinding.ResourceOrDstu1Bundle;
+import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
-import ca.uhn.fhir.rest.server.IBundleProvider;
+import ca.uhn.fhir.rest.server.RestfulServerUtils;
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.NotModifiedException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.fhir.util.UrlUtil;
@@ -83,12 +94,12 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
return url;
}
- private Bundle batch(Bundle theRequest) {
+ private Bundle batch(final RequestDetails theRequestDetails, Bundle theRequest) {
ourLog.info("Beginning batch with {} resources", theRequest.getEntry().size());
long start = System.currentTimeMillis();
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
- txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
+ txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
Bundle resp = new Bundle();
resp.setType(BundleTypeEnum.BATCH_RESPONSE);
@@ -96,8 +107,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
resp.addEntry().setResource(ooResp);
/*
- * For batch, we handle each entry as a mini-transaction in its own database transaction so that if one fails, it
- * doesn't prevent others
+ * For batch, we handle each entry as a mini-transaction in its own database transaction so that if one fails, it doesn't prevent others
*/
for (final Entry nextRequestEntry : theRequest.getEntry()) {
@@ -109,7 +119,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
subRequestBundle.setType(BundleTypeEnum.TRANSACTION);
subRequestBundle.addEntry(nextRequestEntry);
- Bundle subResponseBundle = transaction(subRequestBundle, "Batch sub-request");
+ Bundle subResponseBundle = transaction(theRequestDetails, subRequestBundle, "Batch sub-request");
return subResponseBundle;
}
};
@@ -122,8 +132,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
Entry subResponseEntry = nextResponseBundle.getEntry().get(0);
resp.addEntry(subResponseEntry);
/*
- * If the individual entry didn't have a resource in its response, bring the sub-transaction's
- * OperationOutcome across so the client can see it
+ * If the individual entry didn't have a resource in its response, bring the sub-transaction's OperationOutcome across so the client can see it
*/
if (subResponseEntry.getResource() == null) {
subResponseEntry.setResource(nextResponseBundle.getEntry().get(0).getResource());
@@ -173,19 +182,19 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
@Transactional(propagation = Propagation.REQUIRED)
@Override
- public Bundle transaction(Bundle theRequest) {
+ public Bundle transaction(RequestDetails theRequestDetails, Bundle theRequest) {
ActionRequestDetails requestDetails = new ActionRequestDetails(null, "Bundle", theRequest);
notifyInterceptors(RestOperationTypeEnum.TRANSACTION, requestDetails);
- String theActionName = "Transaction";
- return transaction(theRequest, theActionName);
+ String actionName = "Transaction";
+ return transaction(theRequestDetails, theRequest, actionName);
}
@SuppressWarnings("unchecked")
- private Bundle transaction(Bundle theRequest, String theActionName) {
+ private Bundle transaction(RequestDetails theRequestDetails, Bundle theRequest, String theActionName) {
BundleTypeEnum transactionType = theRequest.getTypeElement().getValueAsEnum();
if (transactionType == BundleTypeEnum.BATCH) {
- return batch(theRequest);
+ return batch(theRequestDetails, theRequest);
}
if (transactionType == null) {
@@ -222,7 +231,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
if (res != null) {
nextResourceId = res.getId();
-
+
if (nextResourceId.hasIdPart() == false) {
if (isNotBlank(nextEntry.getFullUrl())) {
nextResourceId = new IdDt(nextEntry.getFullUrl());
@@ -232,7 +241,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+\\:.*") && !isPlaceholder(nextResourceId)) {
throw new InvalidRequestException("Invalid placeholder ID found: " + nextResourceId.getIdPart() + " - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'");
}
-
+
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !isPlaceholder(nextResourceId)) {
nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
res.setId(nextResourceId);
@@ -312,67 +321,67 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
}
case GET: {
// SEARCH/READ/VREAD
+ RequestDetails requestDetails = new RequestDetails();
+ requestDetails.setServletRequest(theRequestDetails.getServletRequest());
+ requestDetails.setRequestType(RequestTypeEnum.GET);
+ requestDetails.setServer(theRequestDetails.getServer());
+
String url = extractTransactionUrlOrThrowException(nextEntry, verb);
- UrlParts parts = UrlUtil.parseUrl(url);
-
- @SuppressWarnings("rawtypes")
- IFhirResourceDao dao = toDao(parts, verb.getCode(), url);
-
- String ifNoneMatch = nextEntry.getRequest().getIfNoneMatch();
- if (isNotBlank(ifNoneMatch)) {
- ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
+
+ int qIndex = url.indexOf('?');
+ ArrayListMultimap paramValues = ArrayListMultimap.create();
+ requestDetails.setParameters(new HashMap());
+ if (qIndex != -1) {
+ String params = url.substring(qIndex);
+ List parameters = translateMatchUrl(params);
+ for (NameValuePair next : parameters) {
+ paramValues.put(next.getName(), next.getValue());
+ }
+ for (java.util.Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) {
+ String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]);
+ requestDetails.getParameters().put(nextParamEntry.getKey(), nextValue);
+ }
+ url = url.substring(0, qIndex);
}
- if (parts.getResourceId() != null && parts.getParams() == null) {
- IResource found;
- boolean notChanged = false;
- if (parts.getVersionId() != null) {
- if (isNotBlank(ifNoneMatch)) {
- throw new InvalidRequestException("Unable to perform vread on '" + url + "' with ifNoneMatch also set. Do not include a version in the URL to perform a conditional read.");
- }
- found = (IResource) dao.read(new IdDt(parts.getResourceType(), parts.getResourceId(), parts.getVersionId()));
- } else {
- found = (IResource) dao.read(new IdDt(parts.getResourceType(), parts.getResourceId()));
- if (isNotBlank(ifNoneMatch) && ifNoneMatch.equals(found.getId().getVersionIdPart())) {
- notChanged = true;
+ requestDetails.setRequestPath(url);
+ requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase());
+
+ theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url);
+ BaseMethodBinding> method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url);
+ if (method == null) {
+ throw new IllegalArgumentException("Unable to handle GET " + url);
+ }
+
+ if (isNotBlank(nextEntry.getRequest().getIfMatch())) {
+ requestDetails.addHeader(Constants.HEADER_IF_MATCH, nextEntry.getRequest().getIfMatch());
+ }
+ if (isNotBlank(nextEntry.getRequest().getIfNoneExist())) {
+ requestDetails.addHeader(Constants.HEADER_IF_NONE_EXIST, nextEntry.getRequest().getIfNoneExist());
+ }
+ if (isNotBlank(nextEntry.getRequest().getIfNoneMatch())) {
+ requestDetails.addHeader(Constants.HEADER_IF_NONE_MATCH, nextEntry.getRequest().getIfNoneMatch());
+ }
+
+ if (method instanceof BaseResourceReturningMethodBinding) {
+ try {
+ ResourceOrDstu1Bundle responseData = ((BaseResourceReturningMethodBinding) method).invokeServer(theRequestDetails.getServer(), requestDetails, new byte[0]);
+ Entry newEntry = response.addEntry();
+ IBaseResource resource = responseData.getResource();
+ if (paramValues.containsKey(Constants.PARAM_SUMMARY) || paramValues.containsKey(Constants.PARAM_CONTENT)) {
+ resource = filterNestedBundle(requestDetails, resource);
}
+ newEntry.setResource((IResource) resource);
+ newEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK));
+ } catch (NotModifiedException e) {
+ Entry newEntry = response.addEntry();
+ newEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED));
}
- Entry entry = response.addEntry();
- if (notChanged == false) {
- entry.setResource(found);
- }
- EntryResponse resp = entry.getResponse();
- resp.setLocation(found.getId().toUnqualified().getValue());
- resp.setEtag(found.getId().getVersionIdPart());
- if (!notChanged) {
- resp.setStatus(toStatusString(Constants.STATUS_HTTP_200_OK));
- } else {
- resp.setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED));
- }
- } else if (parts.getParams() != null) {
- RuntimeResourceDefinition def = getContext().getResourceDefinition(dao.getResourceType());
- SearchParameterMap params = translateMatchUrl(url, def);
- IBundleProvider bundle = dao.search(params);
-
- Bundle searchBundle = new Bundle();
- searchBundle.setTotal(bundle.size());
-
- int configuredMax = 200; // this should probably be configurable or something
- if (bundle.size() > configuredMax) {
- throw new InvalidRequestException("Search nested within transaction found more than " + configuredMax + " matches, but paging is not supported in nested transactions");
- }
- List resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
- for (IBaseResource next : resourcesToAdd) {
- searchBundle.addEntry().setResource((IResource) next);
- }
-
- Entry newEntry = response.addEntry();
- newEntry.setResource(searchBundle);
- newEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK));
+ } else {
+ throw new IllegalArgumentException("Unable to handle GET " + url);
}
}
}
-
}
FhirTerser terser = getContext().newTerser();
@@ -416,7 +425,8 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
IFhirResourceDao> resourceDao = getDao(nextEntry.getResource().getClass());
Set val = resourceDao.processMatchUrl(matchUrl);
if (val.size() > 1) {
- throw new InvalidRequestException("Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
+ throw new InvalidRequestException(
+ "Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
}
}
}
@@ -442,6 +452,20 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
return response;
}
+ /**
+ * This method is called for nested bundles (e.g. if we received a transaction with an entry that
+ * was a GET search, this method is called on the bundle for the search result, that will be placed in the
+ * outer bundle). This method applies the _summary and _content parameters to the output of
+ * that bundle.
+ *
+ * TODO: This isn't the most efficient way of doing this.. hopefully we can come up with something better in the future.
+ */
+ private IBaseResource filterNestedBundle(RequestDetails theRequestDetails, IBaseResource theResource) {
+ IParser p = getContext().newJsonParser();
+ RestfulServerUtils.configureResponseParser(theRequestDetails, p);
+ return p.parseResource(theResource.getClass(), p.encodeResourceToString(theResource));
+ }
+
private ca.uhn.fhir.jpa.dao.IFhirResourceDao extends IBaseResource> toDao(UrlParts theParts, String theVerb, String theUrl) {
RuntimeResourceDefinition resType;
try {
@@ -459,10 +483,10 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
throw new InvalidRequestException(msg);
}
- if (theParts.getResourceId() == null && theParts.getParams() == null) {
- String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theVerb, theUrl);
- throw new InvalidRequestException(msg);
- }
+ // if (theParts.getResourceId() == null && theParts.getParams() == null) {
+ // String msg = getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionInvalidUrl", theVerb, theUrl);
+ // throw new InvalidRequestException(msg);
+ // }
return dao;
}
@@ -475,15 +499,15 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
return retVal;
}
- private static void handleTransactionCreateOrUpdateOutcome(Map idSubstitutions, Map idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome, Entry newEntry, String theResourceType, IResource theRes) {
+ private static void handleTransactionCreateOrUpdateOutcome(Map idSubstitutions, Map idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
+ Entry newEntry, String theResourceType, IResource theRes) {
IdDt newId = (IdDt) outcome.getId().toUnqualifiedVersionless();
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
if (newId.equals(resourceId) == false) {
idSubstitutions.put(resourceId, newId);
if (isPlaceholder(resourceId)) {
/*
- * The correct way for substitution IDs to be is to be with no resource type, but we'll accept the qualified
- * kind too just to be lenient.
+ * The correct way for substitution IDs to be is to be with no resource type, but we'll accept the qualified kind too just to be lenient.
*/
idSubstitutions.put(new IdDt(theResourceType + '/' + resourceId.getValue()), newId);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirSystemDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirSystemDao.java
index cec8fca78dd..9e5c05a783a 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirSystemDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirSystemDao.java
@@ -25,6 +25,7 @@ import java.util.Map;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
+import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.IBundleProvider;
/**
@@ -58,6 +59,6 @@ public interface IFhirSystemDao extends IDao {
*/
MetaDt metaGetOperation();
- T transaction(T theResources);
+ T transaction(RequestDetails theRequestDetails, T theResources);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchDao.java
index f273037aadb..9b52fa3c561 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchDao.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import java.util.List;
public interface ISearchDao {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaProvider.java
index 3f3e9c9350a..22efc907338 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaProvider.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaProvider.java
@@ -29,12 +29,23 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jboss.logging.MDC;
+import ca.uhn.fhir.rest.method.RequestDetails;
+
public class BaseJpaProvider {
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaProvider.class);
public static final String REMOTE_ADDR = "req.remoteAddr";
+
public static final String REMOTE_UA = "req.userAgent";
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaProvider.class);
+ public void endRequest(HttpServletRequest theRequest) {
+ MDC.remove(REMOTE_ADDR);
+ MDC.remove(REMOTE_UA);
+ }
+
+ public void endRequest(RequestDetails theRequest) {
+ endRequest(theRequest.getServletRequest());
+ }
public void startRequest(HttpServletRequest theRequest) {
if (theRequest == null) {
@@ -49,13 +60,13 @@ public class BaseJpaProvider {
Enumeration forwardedFors = theRequest.getHeaders("x-forwarded-for");
StringBuilder b = new StringBuilder();
- for (Enumeration enums = forwardedFors; enums.hasMoreElements();) {
+ for (Enumeration enums = forwardedFors; enums != null && enums.hasMoreElements();) {
if (b.length() > 0) {
b.append(" / ");
}
b.append(enums.nextElement());
}
-
+
String forwardedFor = b.toString();
String ip = theRequest.getRemoteAddr();
if (StringUtils.isBlank(forwardedFor)) {
@@ -68,12 +79,11 @@ public class BaseJpaProvider {
String userAgent = StringUtils.defaultString(theRequest.getHeader("user-agent"));
org.slf4j.MDC.put(REMOTE_UA, userAgent);
-
+
}
- public void endRequest(HttpServletRequest theRequest) {
- MDC.remove(REMOTE_ADDR);
- MDC.remove(REMOTE_UA);
+ public void startRequest(RequestDetails theRequest) {
+ startRequest(theRequest.getServletRequest());
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu1.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu1.java
index 3b20234a2d1..e4f958d3757 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu1.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu1.java
@@ -22,21 +22,20 @@ package ca.uhn.fhir.jpa.provider;
import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
+import ca.uhn.fhir.rest.method.RequestDetails;
public class JpaSystemProviderDstu1 extends BaseJpaSystemProvider> {
@Transaction
- public List transaction(HttpServletRequest theRequest, @TransactionParam List theResources) {
- startRequest(theRequest);
+ public List transaction(RequestDetails theRequestDetails, @TransactionParam List theResources) {
+ startRequest(theRequestDetails);
try {
- return getDao().transaction(theResources);
+ return getDao().transaction(theRequestDetails, theResources);
} finally {
- endRequest(theRequest);
+ endRequest(theRequestDetails);
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java
index e164cf34d40..61dd3473c9a 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaSystemProviderDstu2.java
@@ -40,6 +40,7 @@ import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
+import ca.uhn.fhir.rest.method.RequestDetails;
public class JpaSystemProviderDstu2 extends BaseJpaSystemProvider {
@@ -182,12 +183,12 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProvider {
}
@Transaction
- public Bundle transaction(HttpServletRequest theRequest, @TransactionParam Bundle theResources) {
- startRequest(theRequest);
+ public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
+ startRequest(theRequestDetails);
try {
- return getDao().transaction(theResources);
+ return getDao().transaction(theRequestDetails, theResources);
} finally {
- endRequest(theRequest);
+ endRequest(theRequestDetails);
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java
index d960832fac2..e440cf65917 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/IndexNonDeletedInterceptor.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.search;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.hibernate.search.indexes.interceptor.EntityIndexingInterceptor;
import org.hibernate.search.indexes.interceptor.IndexingOverride;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
index 922ffc7668a..39f4ee4abdb 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
@@ -218,7 +218,9 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
if (!id.hasIdPart() || !id.isIdPartValid()) {
try {
- theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), "Invalid bind request - No ID included"));
+ String message = "Invalid bind request - No ID included";
+ ourLog.warn(message);
+ theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), message));
} catch (IOException e) {
handleFailure(e);
}
@@ -236,7 +238,9 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
myState = new BoundStaticSubscipriptionState(theSession);
} catch (ResourceNotFoundException e) {
try {
- theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), "Invalid bind request - Unknown subscription: " + id.getValue()));
+ String message = "Invalid bind request - Unknown subscription: " + id.getValue();
+ ourLog.warn(message);
+ theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), message));
} catch (IOException e1) {
handleFailure(e);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java
index 444383addd1..97bafcc760e 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BigDecimalNumericFieldBridge.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.util;
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2015 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import java.math.BigDecimal;
import org.apache.lucene.document.Document;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu2Config.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu2Config.java
index 742711a7c7f..5ce08eeab7a 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu2Config.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu2Config.java
@@ -60,6 +60,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update");
+ extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect");
return extraProperties;
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1Test.java
index 6fc5146a06c..1d4e35945a6 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu1Test.java
@@ -9,6 +9,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -21,10 +22,10 @@ import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestDstu1Config;
@@ -41,6 +42,7 @@ import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
+import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@@ -54,6 +56,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
private static IFhirResourceDao ourObservationDao;
private static IFhirResourceDao ourPatientDao;
private static IFhirSystemDao> ourSystemDao;
+ private RequestDetails myRequestDetails;
@Test
public void testGetResourceCounts() {
@@ -140,7 +143,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
obs.getName().addCoding().setSystem("urn:system").setCode("testPersistWithSimpleLinkO01");
obs.setSubject(new ResourceReferenceDt("Patient/testPersistWithSimpleLinkP01"));
- ourSystemDao.transaction(Arrays.asList((IResource) patient, obs));
+ ourSystemDao.transaction(myRequestDetails, Arrays.asList((IResource) patient, obs));
String patientId = (patient.getId().getIdPart());
String obsId = (obs.getId().getIdPart());
@@ -169,7 +172,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
patient.addIdentifier().setSystem("urn:system").setValue("testPersistWithSimpleLinkP02");
obs.getName().addCoding().setSystem("urn:system").setCode("testPersistWithSimpleLinkO02");
- ourSystemDao.transaction(Arrays.asList((IResource) patient, obs));
+ ourSystemDao.transaction(myRequestDetails, Arrays.asList((IResource) patient, obs));
String patientId2 = (patient.getId().getIdPart());
String patientVersion2 = (patient.getId().getVersionIdPart());
@@ -182,6 +185,11 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
assertEquals(obsVersion2, "2");
}
+
+ @Before
+ public void before() {
+ myRequestDetails = mock(RequestDetails.class);
+ }
@Test
public void testPersistWithUnknownId() {
@@ -190,7 +198,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
obs.setSubject(new ResourceReferenceDt("Patient/999998888888"));
try {
- ourSystemDao.transaction(Arrays.asList((IResource) obs));
+ ourSystemDao.transaction(myRequestDetails, Arrays.asList((IResource) obs));
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Resource Patient/999998888888 not found, specified in path: Observation.subject"));
}
@@ -200,7 +208,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
obs.setSubject(new ResourceReferenceDt("Patient/1.2.3.4"));
try {
- ourSystemDao.transaction(Arrays.asList((IResource) obs));
+ ourSystemDao.transaction(myRequestDetails, Arrays.asList((IResource) obs));
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Resource Patient/1.2.3.4 not found, specified in path: Observation.subject"));
}
@@ -290,7 +298,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
patient2.setId(new IdDt("Patient/testTransactionFailsWithDusplicateIds"));
patient2.addIdentifier().setSystem("urn:system").setValue("testPersistWithSimpleLinkP02");
- ourSystemDao.transaction(Arrays.asList((IResource) patient1, patient2));
+ ourSystemDao.transaction(myRequestDetails, Arrays.asList((IResource) patient1, patient2));
}
@Test
@@ -300,7 +308,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
Bundle bundle = ourFhirContext.newXmlParser().parseBundle(new InputStreamReader(bundleRes));
List res = bundle.toListOfResources();
- ourSystemDao.transaction(res);
+ ourSystemDao.transaction(myRequestDetails, res);
Patient p1 = (Patient) res.get(0);
String id = p1.getId().getValue();
@@ -333,7 +341,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
o2.setSubject(new ResourceReferenceDt("Patient/cid:patient1"));
res.add(o2);
- ourSystemDao.transaction(res);
+ ourSystemDao.transaction(myRequestDetails, res);
assertTrue(p1.getId().getValue(), p1.getId().getIdPart().matches("^[0-9]+$"));
assertTrue(o1.getId().getValue(), o1.getId().getIdPart().matches("^[0-9]+$"));
@@ -355,7 +363,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
res.add(next.getResource());
}
- List response = ourSystemDao.transaction(res);
+ List response = ourSystemDao.transaction(myRequestDetails, res);
String encodeResourceToString = ourFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(response.get(0));
ourLog.info(encodeResourceToString);
@@ -388,7 +396,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
o2.setSubject(new ResourceReferenceDt("cid:patient1"));
res.add(o2);
- ourSystemDao.transaction(res);
+ ourSystemDao.transaction(myRequestDetails, res);
assertTrue(p1.getId().getValue(), p1.getId().getIdPart().matches("^[0-9]+$"));
assertTrue(o1.getId().getValue(), o1.getId().getIdPart().matches("^[0-9]+$"));
@@ -421,7 +429,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
p3.addIdentifier().setSystem("urn:system").setValue("testTransactionWithDelete");
res.add(p3);
- ourSystemDao.transaction(res);
+ ourSystemDao.transaction(myRequestDetails, res);
/*
* Verify
@@ -447,7 +455,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
ResourceMetadataKeyEnum.DELETED_AT.put(p2, InstantDt.withCurrentTime());
res.add(p2);
- ourSystemDao.transaction(res);
+ ourSystemDao.transaction(myRequestDetails, res);
/*
* Verify
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2Test.java
index c2a4acc8257..e8692018115 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2Test.java
@@ -14,28 +14,36 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
import java.util.List;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.commons.io.IOUtils;
-import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
+import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
-import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
+import ca.uhn.fhir.jpa.rp.dstu2.PatientResourceProvider;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
@@ -47,7 +55,6 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryRequest;
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryResponse;
-import ca.uhn.fhir.model.dstu2.resource.Communication;
import ca.uhn.fhir.model.dstu2.resource.Medication;
import ca.uhn.fhir.model.dstu2.resource.MedicationOrder;
import ca.uhn.fhir.model.dstu2.resource.Observation;
@@ -58,11 +65,13 @@ import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
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.api.RestOperationTypeEnum;
+import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IBundleProvider;
+import ca.uhn.fhir.rest.server.IResourceProvider;
+import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
@@ -72,14 +81,26 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetai
public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2Test.class);
+ private RequestDetails myRequestDetails;
+ private RestfulServer myServer;
@Test
public void testTransactionFromBundle6() throws Exception {
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle3.xml");
String bundle = IOUtils.toString(bundleRes);
- Bundle output = mySystemDao.transaction(myFhirCtx.newXmlParser().parseResource(Bundle.class, bundle));
+ Bundle output = mySystemDao.transaction(myRequestDetails, myFhirCtx.newXmlParser().parseResource(Bundle.class, bundle));
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output));
}
+
+
+ @Test
+ public void testNestedCount() {
+ Patient p = new Patient();
+ p.addName().addFamily("family");
+ final IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
+
+ }
+
@Test
public void testRendexing() {
@@ -262,7 +283,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(2, resp.getEntry().size());
Entry respEntry = resp.getEntry().get(0);
@@ -290,7 +311,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Unable to process transaction where incoming Bundle.type = searchset", e.getMessage());
@@ -298,6 +319,27 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
}
+ @SuppressWarnings("unchecked")
+ @Before
+ public void before() throws ServletException {
+ myRequestDetails = mock(RequestDetails.class);
+
+ if (myServer == null) {
+ myServer = new RestfulServer(myFhirCtx);
+
+ PatientResourceProvider patientRp = new PatientResourceProvider();
+ patientRp.setDao(myPatientDao);
+ myServer.setResourceProviders(patientRp);
+ myServer.init(mock(ServletConfig.class));
+ }
+
+ when(myRequestDetails.getServer()).thenReturn(myServer);
+ HttpServletRequest servletRequest = mock(HttpServletRequest.class);
+ when(myRequestDetails.getServletRequest()).thenReturn(servletRequest);
+ when(servletRequest.getHeaderNames()).thenReturn(mock(Enumeration.class));
+ when(servletRequest.getRequestURL()).thenReturn(new StringBuffer("/Patient"));
+ }
+
@Test
public void testTransactionSingleEmptyResource() {
@@ -307,7 +349,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Unable to process transaction where incoming Bundle.type = searchset", e.getMessage());
@@ -327,7 +369,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient/THIS_ID_DOESNT_EXIST");
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(3, resp.getEntry().size());
assertEquals(BundleTypeEnum.BATCH_RESPONSE, resp.getTypeElement().getValueAsEnum());
@@ -377,7 +419,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals(e.getMessage(),
@@ -397,7 +439,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
try {
entry.setIfNoneExist("Patient?identifier identifier" + methodName);
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Failed to parse match URL[Patient?identifier identifiertestTransactionCreateWithInvalidMatchUrl] - URL is invalid (must not contain spaces)", e.getMessage());
@@ -405,7 +447,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
try {
entry.setIfNoneExist("Patient?identifier=");
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Invalid match URL[Patient?identifier=] - URL has no search parameters", e.getMessage());
@@ -413,7 +455,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
try {
entry.setIfNoneExist("Patient?foo=bar");
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage());
@@ -435,7 +477,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertEquals(e.getMessage(),
@@ -470,7 +512,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (PreconditionFailedException e) {
assertThat(e.getMessage(), containsString("with match URL \"Patient"));
@@ -493,7 +535,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
assertEquals(2, resp.getEntry().size());
@@ -525,7 +567,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
p.setId("Patient/" + methodName);
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(1, resp.getEntry().size());
Entry respEntry = resp.getEntry().get(0);
@@ -564,7 +606,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Resource Organization/9999999999999999 not found, specified in path: Patient.managingOrganization"));
@@ -583,7 +625,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Resource Organization/" + methodName + " not found, specified in path: Patient.managingOrganization"));
@@ -613,7 +655,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
myPatientDao.read(id1.toVersionless());
myPatientDao.read(id2.toVersionless());
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(2, resp.getEntry().size());
assertEquals("204 No Content", resp.getEntry().get(0).getResponse().getStatus());
@@ -647,7 +689,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
Bundle request = new Bundle();
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(1, resp.getEntry().size());
Entry nextEntry = resp.getEntry().get(0);
@@ -701,7 +743,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (PreconditionFailedException e) {
assertThat(e.getMessage(), containsString("resource with match URL \"Patient?"));
@@ -716,7 +758,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
// try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
// fail();
// } catch (ResourceNotFoundException e) {
// assertThat(e.getMessage(), containsString("resource matching URL \"Patient?"));
@@ -736,7 +778,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
Bundle request = new Bundle();
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
- Bundle res = mySystemDao.transaction(request);
+ Bundle res = mySystemDao.transaction(myRequestDetails, request);
assertEquals(1, res.getEntry().size());
assertEquals(Constants.STATUS_HTTP_204_NO_CONTENT + " No Content", res.getEntry().get(0).getResponse().getStatus());
@@ -763,7 +805,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
patient2.addIdentifier().setSystem("urn:system").setValue("testPersistWithSimpleLinkP02");
request.addEntry().setResource(patient2).getRequest().setMethod(HTTPVerbEnum.POST);
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
}
@Test
@@ -773,7 +815,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
String bundleStr = IOUtils.toString(bundleRes);
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, bundleStr);
- Bundle resp = mySystemDao.transaction(bundle);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, bundle);
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
@@ -792,7 +834,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
String bundleStr = IOUtils.toString(bundleRes);
Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, bundleStr);
- Bundle resp = mySystemDao.transaction(bundle);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, bundle);
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
@@ -817,7 +859,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
ourLog.info("Request:\n"+myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
- Bundle outcome = mySystemDao.transaction(bundle);
+ Bundle outcome = mySystemDao.transaction(myRequestDetails, bundle);
ourLog.info("Response:\n"+myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
IdDt medId1 = new IdDt(outcome.getEntry().get(0).getResponse().getLocation());
@@ -839,7 +881,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
mo.setMedication(new ResourceReferenceDt(medId));
bundle.addEntry().setResource(mo).setFullUrl(mo.getId().getValue()).getRequest().setMethod(HTTPVerbEnum.POST);
- outcome = mySystemDao.transaction(bundle);
+ outcome = mySystemDao.transaction(myRequestDetails, bundle);
IdDt medId2 = new IdDt(outcome.getEntry().get(0).getResponse().getLocation());
IdDt medOrderId2 = new IdDt(outcome.getEntry().get(1).getResponse().getLocation());
@@ -875,7 +917,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualified().getValue());
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(3, resp.getEntry().size());
@@ -943,7 +985,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
Bundle request = new Bundle();
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(1, resp.getEntry().size());
@@ -957,7 +999,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request = new Bundle();
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=GKJGKJG");
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
} catch (InvalidRequestException e) {
assertEquals(e.getMessage(), ("Invalid _count value: GKJGKJG"));
}
@@ -966,7 +1008,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request = new Bundle();
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=");
- respBundle = mySystemDao.transaction(request);
+ respBundle = mySystemDao.transaction(myRequestDetails, request);
assertThat(respBundle.getEntry().size(), greaterThan(0));
}
@@ -992,7 +1034,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv1.getVersionIdPart() + "\"");
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv2.getVersionIdPart() + "\"");
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(3, resp.getEntry().size());
@@ -1011,8 +1053,8 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
assertEquals("200 OK", nextEntry.getResponse().getStatus());
nextEntry = resp.getEntry().get(2);
- assertNull(nextEntry.getResource());
assertEquals("304 Not Modified", nextEntry.getResponse().getStatus());
+ assertNull(nextEntry.getResource());
}
@Test
@@ -1036,7 +1078,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(2, resp.getEntry().size());
Entry nextEntry = resp.getEntry().get(0);
@@ -1083,7 +1125,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
try {
- mySystemDao.transaction(request);
+ mySystemDao.transaction(myRequestDetails, request);
fail();
} catch (PreconditionFailedException e) {
assertThat(e.getMessage(), containsString("with match URL \"Patient"));
@@ -1110,7 +1152,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(2, resp.getEntry().size());
Entry nextEntry = resp.getEntry().get(0);
@@ -1150,7 +1192,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o.getSubject().setReference("Patient/" + methodName);
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
- Bundle resp = mySystemDao.transaction(request);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, request);
assertEquals(2, resp.getEntry().size());
Entry nextEntry = resp.getEntry().get(0);
@@ -1293,7 +1335,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o2.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
- Bundle resp = mySystemDao.transaction(res);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
@@ -1336,7 +1378,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
o2.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
- Bundle resp = mySystemDao.transaction(res);
+ Bundle resp = mySystemDao.transaction(myRequestDetails, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
@@ -1355,22 +1397,4 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
}
- static void doDeleteEverything(IFhirSystemDao systemDao) {
- IBundleProvider all = systemDao.history(null);
- List allRes = all.getResources(0, all.size());
- for (IBaseResource iResource : allRes) {
- if (ResourceMetadataKeyEnum.DELETED_AT.get((IResource) iResource) == null) {
- ourLog.info("Deleting: {}", iResource.getIdElement());
-
- Bundle b = new Bundle();
- b.setType(BundleTypeEnum.TRANSACTION);
- String url = iResource.getIdElement().toVersionless().getValue();
- b.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl(url);
- systemDao.transaction(b);
- }
- }
-
- systemDao.deleteAllTagsOnServer();
- }
-
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderDstu2Test.java
index cd6dba0bd76..0b5c23ba4b8 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderDstu2Test.java
@@ -2,7 +2,12 @@ package ca.uhn.fhir.jpa.provider;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
@@ -16,29 +21,22 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
-import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.junit.AfterClass;
-import org.junit.BeforeClass;
+import org.junit.Before;
import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.jpa.config.TestDstu1Config;
-import ca.uhn.fhir.jpa.config.TestDstu2Config;
-import ca.uhn.fhir.jpa.dao.BaseJpaTest;
-import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
+import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test;
import ca.uhn.fhir.jpa.rp.dstu2.ObservationResourceProvider;
import ca.uhn.fhir.jpa.rp.dstu2.OrganizationResourceProvider;
import ca.uhn.fhir.jpa.rp.dstu2.PatientResourceProvider;
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
-import ca.uhn.fhir.model.dstu2.resource.Observation;
-import ca.uhn.fhir.model.dstu2.resource.Organization;
-import ca.uhn.fhir.model.dstu2.resource.Patient;
-import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.OperationDefinition;
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
+import ca.uhn.fhir.model.dstu2.resource.Patient;
+import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
+import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.server.EncodingEnum;
@@ -46,18 +44,95 @@ import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
-import net.sf.saxon.lib.OutputURIResolver;
-public class SystemProviderDstu2Test extends BaseJpaTest {
+public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
+ private static RestfulServer myRestServer;
+ private static IGenericClient ourClient;
+ private static FhirContext ourCtx;
+ private static CloseableHttpClient ourHttpClient;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderDstu2Test.class);
private static Server ourServer;
- private static AnnotationConfigApplicationContext ourAppCtx;
- private static FhirContext ourCtx;
- private static IGenericClient ourClient;
private static String ourServerBase;
- private static CloseableHttpClient ourHttpClient;
- private static RestfulServer restServer;
+
+ @Before
+ public void beforeStartServer() throws Exception {
+ if (myRestServer == null) {
+ PatientResourceProvider patientRp = new PatientResourceProvider();
+ patientRp.setDao(myPatientDao);
+
+ QuestionnaireResourceProviderDstu2 questionnaireRp = new QuestionnaireResourceProviderDstu2();
+ questionnaireRp.setDao(myQuestionnaireDao);
+
+ ObservationResourceProvider observationRp = new ObservationResourceProvider();
+ observationRp.setDao(myObservationDao);
+
+ OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
+ organizationRp.setDao(myOrganizationDao);
+
+ RestfulServer restServer = new RestfulServer(ourCtx);
+ restServer.setPagingProvider(new FifoMemoryPagingProvider(10).setDefaultPageSize(10));
+ restServer.setResourceProviders(patientRp, questionnaireRp, observationRp, organizationRp);
+
+ restServer.setPlainProviders(mySystemProvider);
+
+ int myPort = RandomServerPortProvider.findFreePort();
+ ourServer = new Server(myPort);
+
+ ServletContextHandler proxyHandler = new ServletContextHandler();
+ proxyHandler.setContextPath("/");
+
+ ourServerBase = "http://localhost:" + myPort + "/fhir/context";
+
+ ServletHolder servletHolder = new ServletHolder();
+ servletHolder.setServlet(restServer);
+ proxyHandler.addServlet(servletHolder, "/fhir/context/*");
+
+ ourCtx = FhirContext.forDstu2();
+ restServer.setFhirContext(ourCtx);
+
+ ourServer.setHandler(proxyHandler);
+ ourServer.start();
+
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
+ HttpClientBuilder builder = HttpClientBuilder.create();
+ builder.setConnectionManager(connectionManager);
+ ourHttpClient = builder.build();
+
+ ourCtx.getRestfulClientFactory().setSocketTimeout(600 * 1000);
+ ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
+ ourClient.setLogRequestAndResponse(true);
+ myRestServer = restServer;
+ }
+ }
+
+ @Test
+ public void testEverythingReturnsCorrectFormatInPagingLink() throws Exception {
+ myRestServer.setDefaultResponseEncoding(EncodingEnum.JSON);
+ myRestServer.setPagingProvider(new FifoMemoryPagingProvider(1).setDefaultPageSize(10));
+ ResponseHighlighterInterceptor interceptor = new ResponseHighlighterInterceptor();
+ myRestServer.registerInterceptor(interceptor);
+
+ for (int i = 0; i < 11; i++) {
+ Patient p = new Patient();
+ p.addName().addFamily("Name" + i);
+ ourClient.create().resource(p).execute();
+ }
+
+ HttpGet get = new HttpGet(ourServerBase + "/Patient/$everything");
+ get.addHeader("Accept", "application/xml, text/html");
+ CloseableHttpResponse http = ourHttpClient.execute(get);
+ try {
+ String response = IOUtils.toString(http.getEntity().getContent());
+ ourLog.info(response);
+ assertThat(response, not(containsString("_format")));
+ assertEquals(200, http.getStatusLine().getStatusCode());
+ } finally {
+ http.close();
+ }
+
+ myRestServer.unregisterInterceptor(interceptor);
+ }
@Test
public void testEverythingType() throws Exception {
@@ -71,74 +146,9 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
}
@Test
- public void testEverythingReturnsCorrectFormatInPagingLink() throws Exception {
- restServer.setDefaultResponseEncoding(EncodingEnum.JSON);
- restServer.setPagingProvider(new FifoMemoryPagingProvider(1).setDefaultPageSize(10));
- ResponseHighlighterInterceptor interceptor = new ResponseHighlighterInterceptor();
- restServer.registerInterceptor(interceptor);
-
- for (int i = 0; i < 11; i++) {
- Patient p = new Patient();
- p.addName().addFamily("Name" + i);
- ourClient.create().resource(p).execute();
- }
-
- HttpGet get = new HttpGet(ourServerBase + "/Patient/$everything");
- get.addHeader("Accept", "application/xml, text/html");
- CloseableHttpResponse http = ourHttpClient.execute(get);
- try {
- String response = IOUtils.toString(http.getEntity().getContent());
- ourLog.info(response);
- assertThat(response, not(containsString("_format")));
- assertEquals(200, http.getStatusLine().getStatusCode());
- } finally {
- http.close();
- }
-
- restServer.unregisterInterceptor(interceptor);
- }
-
- @Test
- public void testTransactionFromBundle4() throws Exception {
- InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle.xml");
- String bundle = IOUtils.toString(bundleRes);
- String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
- ourLog.info(response);
- Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
- IdDt id = new IdDt(bundleResp.getEntry().get(0).getResponse().getLocation());
- assertEquals("Patient", id.getResourceType());
- assertTrue(id.hasIdPart());
- assertTrue(id.isIdPartValidLong());
- assertTrue(id.hasVersionIdPart());
- assertTrue(id.isVersionIdPartValidLong());
- }
-
- @Test
- public void testTransactionFromBundle5() throws Exception {
- InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle2.xml");
- String bundle = IOUtils.toString(bundleRes);
- try {
- ourClient.transaction().withBundle(bundle).prettyPrint().execute();
- fail();
- } catch (InvalidRequestException e) {
- OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
- assertEquals("Invalid placeholder ID found: uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", oo.getIssue().get(0).getDiagnostics());
- assertEquals("processing", oo.getIssue().get(0).getCode());
- }
- }
-
- @Test
- public void testTransactionFromBundle6() throws Exception {
- InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle3.xml");
- String bundle = IOUtils.toString(bundleRes);
- ourClient.transaction().withBundle(bundle).prettyPrint().execute();
-// try {
-// fail();
-// } catch (InvalidRequestException e) {
-// OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
-// assertEquals("Invalid placeholder ID found: uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", oo.getIssue().get(0).getDiagnostics());
-// assertEquals("processing", oo.getIssue().get(0).getCode());
-// }
+ public void testGetOperationDefinition() {
+ OperationDefinition op = ourClient.read(OperationDefinition.class, "get-resource-counts");
+ assertEquals("$get-resource-counts", op.getCode());
}
@Test
@@ -149,24 +159,6 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
ourLog.info(response);
}
- /**
- * This is Gramahe's test transaction - it requires some set up in order to work
- */
- // @Test
- public void testTransactionFromBundle3() throws Exception {
-
- InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/grahame-transaction.xml");
- String bundle = IOUtils.toString(bundleRes);
- String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
- ourLog.info(response);
- }
-
- @Test
- public void testGetOperationDefinition() {
- OperationDefinition op = ourClient.read(OperationDefinition.class, "get-resource-counts");
- assertEquals("$get-resource-counts", op.getCode());
- }
-
@Test
public void testTransactionFromBundle2() throws Exception {
@@ -204,65 +196,108 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
assertEquals(id1_4.toVersionless(), id2_4.toVersionless());
}
+ /**
+ * This is Gramahe's test transaction - it requires some set up in order to work
+ */
+ // @Test
+ public void testTransactionFromBundle3() throws Exception {
+
+ InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/grahame-transaction.xml");
+ String bundle = IOUtils.toString(bundleRes);
+ String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
+ ourLog.info(response);
+ }
+
+ @Test
+ public void testTransactionFromBundle4() throws Exception {
+ InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle.xml");
+ String bundle = IOUtils.toString(bundleRes);
+ String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
+ ourLog.info(response);
+ Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
+ IdDt id = new IdDt(bundleResp.getEntry().get(0).getResponse().getLocation());
+ assertEquals("Patient", id.getResourceType());
+ assertTrue(id.hasIdPart());
+ assertTrue(id.isIdPartValidLong());
+ assertTrue(id.hasVersionIdPart());
+ assertTrue(id.isVersionIdPartValidLong());
+ }
+
+ @Test
+ public void testTransactionFromBundle5() throws Exception {
+ InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle2.xml");
+ String bundle = IOUtils.toString(bundleRes);
+ try {
+ ourClient.transaction().withBundle(bundle).prettyPrint().execute();
+ fail();
+ } catch (InvalidRequestException e) {
+ OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
+ assertEquals("Invalid placeholder ID found: uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", oo.getIssue().get(0).getDiagnostics());
+ assertEquals("processing", oo.getIssue().get(0).getCode());
+ }
+ }
+
+ @Test
+ public void testTransactionFromBundle6() throws Exception {
+ InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle3.xml");
+ String bundle = IOUtils.toString(bundleRes);
+ ourClient.transaction().withBundle(bundle).prettyPrint().execute();
+ // try {
+ // fail();
+ // } catch (InvalidRequestException e) {
+ // OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
+ // assertEquals("Invalid placeholder ID found: uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", oo.getIssue().get(0).getDiagnostics());
+ // assertEquals("processing", oo.getIssue().get(0).getCode());
+ // }
+ }
+
+ @Test
+ public void testTransactionSearch() throws Exception {
+ for (int i = 0; i < 20; i ++) {
+ Patient p = new Patient();
+ p.addName().addFamily("PATIENT_" + i);
+ myPatientDao.create(p);
+ }
+
+ Bundle req = new Bundle();
+ req.setType(BundleTypeEnum.TRANSACTION);
+ req.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?");
+ Bundle resp = ourClient.transaction().withBundle(req).execute();
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
+
+ assertEquals(1, resp.getEntry().size());
+ Bundle respSub = (Bundle)resp.getEntry().get(0).getResource();
+ assertEquals("self", respSub.getLink().get(0).getRelation());
+ assertEquals(ourServerBase + "/Patient", respSub.getLink().get(0).getUrl());
+ assertEquals("next", respSub.getLink().get(1).getRelation());
+ assertThat(respSub.getLink().get(1).getUrl(), containsString("/fhir/context?_getpages"));
+ assertThat(respSub.getEntry().get(0).getFullUrl(), startsWith(ourServerBase + "/Patient/"));
+ assertEquals(Patient.class, respSub.getEntry().get(0).getResource().getClass());
+ }
+
+ @Test
+ public void testTransactionCount() throws Exception {
+ for (int i = 0; i < 20; i ++) {
+ Patient p = new Patient();
+ p.addName().addFamily("PATIENT_" + i);
+ myPatientDao.create(p);
+ }
+
+ Bundle req = new Bundle();
+ req.setType(BundleTypeEnum.TRANSACTION);
+ req.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?_summary=count");
+ Bundle resp = ourClient.transaction().withBundle(req).execute();
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
+
+ assertEquals(1, resp.getEntry().size());
+ Bundle respSub = (Bundle)resp.getEntry().get(0).getResource();
+ assertEquals(20, respSub.getTotal().intValue());
+ assertEquals(0, respSub.getEntry().size());
+ }
+
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
- ourAppCtx.stop();
- }
-
- @SuppressWarnings("unchecked")
- @BeforeClass
- public static void beforeClass() throws Exception {
- ourAppCtx = new AnnotationConfigApplicationContext(TestDstu2Config.class);
-
- IFhirResourceDao patientDao = (IFhirResourceDao) ourAppCtx.getBean("myPatientDaoDstu2", IFhirResourceDao.class);
- PatientResourceProvider patientRp = new PatientResourceProvider();
- patientRp.setDao(patientDao);
-
- IFhirResourceDao questionnaireDao = (IFhirResourceDao) ourAppCtx.getBean("myQuestionnaireDaoDstu2", IFhirResourceDao.class);
- QuestionnaireResourceProviderDstu2 questionnaireRp = new QuestionnaireResourceProviderDstu2();
- questionnaireRp.setDao(questionnaireDao);
-
- IFhirResourceDao observationDao = (IFhirResourceDao) ourAppCtx.getBean("myObservationDaoDstu2", IFhirResourceDao.class);
- ObservationResourceProvider observationRp = new ObservationResourceProvider();
- observationRp.setDao(observationDao);
-
- IFhirResourceDao organizationDao = (IFhirResourceDao) ourAppCtx.getBean("myOrganizationDaoDstu2", IFhirResourceDao.class);
- OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
- organizationRp.setDao(organizationDao);
-
- restServer = new RestfulServer(ourCtx);
- restServer.setResourceProviders(patientRp, questionnaireRp, observationRp, organizationRp);
-
- JpaSystemProviderDstu2 systemProv = ourAppCtx.getBean(JpaSystemProviderDstu2.class, "mySystemProviderDstu2");
- restServer.setPlainProviders(systemProv);
-
- int myPort = RandomServerPortProvider.findFreePort();
- ourServer = new Server(myPort);
-
- ServletContextHandler proxyHandler = new ServletContextHandler();
- proxyHandler.setContextPath("/");
-
- ourServerBase = "http://localhost:" + myPort + "/fhir/context";
-
- ServletHolder servletHolder = new ServletHolder();
- servletHolder.setServlet(restServer);
- proxyHandler.addServlet(servletHolder, "/fhir/context/*");
-
- ourCtx = FhirContext.forDstu2();
- restServer.setFhirContext(ourCtx);
-
- ourServer.setHandler(proxyHandler);
- ourServer.start();
-
- PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
- HttpClientBuilder builder = HttpClientBuilder.create();
- builder.setConnectionManager(connectionManager);
- ourHttpClient = builder.build();
-
- ourCtx.getRestfulClientFactory().setSocketTimeout(600 * 1000);
- ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
- ourClient.setLogRequestAndResponse(true);
}
}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu1.xml_ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu1.xml_
deleted file mode 100644
index 5acd1694112..00000000000
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu1.xml_
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ca.uhn.fhir.jpa.entity
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu2.xml_ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu2.xml_
deleted file mode 100644
index 9c14d15cbc9..00000000000
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/resources/hapi-fhir-server-database-config-dstu2.xml_
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ca.uhn.fhir.jpa.entity
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/Dstu1BundleFactory.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/Dstu1BundleFactory.java
index 15c16ae9514..c525cf03b09 100644
--- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/Dstu1BundleFactory.java
+++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/Dstu1BundleFactory.java
@@ -2,7 +2,7 @@ package ca.uhn.fhir.rest.server;
/*
* #%L
- * HAPI FHIR - Core Library
+ * HAPI FHIR Structures - DSTU1 (FHIR v0.80)
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
diff --git a/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/tmpl-navbar-top.html b/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/tmpl-navbar-top.html
index 7efd7b63486..4bdc287ed34 100644
--- a/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/tmpl-navbar-top.html
+++ b/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/tmpl-navbar-top.html
@@ -11,7 +11,7 @@
- HAPI FHIR
+ Home
Jetty (JPA, CLI, Public Server): 9.2.6.v20141205 -> 9.3.4.v20151007
]]>
-
+
JPA and Tester Overlay now use Spring Java config files instead
of the older XML config files. All example projects have been updated.
@@ -183,6 +183,11 @@
Fix a crash when encoding a Binary resource in JSON encoding
if the resource has no content-type
+
+ JPA server now supports read/history/search in transaction entries
+ by calling the actual implementing method in the server (previously
+ the call was simulated, which meant that many features did not work)
+