diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml
index d4085fca4ecc..1bdd3b18d478 100644
--- a/hapi-fhir-client-okhttp/pom.xml
+++ b/hapi-fhir-client-okhttp/pom.xml
@@ -79,11 +79,6 @@
jetty-servlet
test
-
- org.jboss.resteasy
- resteasy-jaxrs
- test
-
org.jboss.resteasy
resteasy-client
diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_7_0/changes.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_7_0/changes.yaml
index 8f9f59d7b94c..a8c23850b6fc 100644
--- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_7_0/changes.yaml
+++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_7_0/changes.yaml
@@ -25,6 +25,7 @@
Jetty Server (CLI): 9.4.43.v20210629 -> 9.4.44.v20210927
Spring Boot (Boot): 2.5.0 -> 2.6.2
Swagger UI (OpenAPI): 3.46.0 -> 4.1.3
+Resteasy (JAX-RS): 4.0.0.Beta3 -> 5.0.2.Final
"
diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml
index 4e86e70a4612..460d69725174 100644
--- a/hapi-fhir-jaxrsserver-base/pom.xml
+++ b/hapi-fhir-jaxrsserver-base/pom.xml
@@ -72,11 +72,6 @@
${project.version}
-
- javax.ws.rs
- javax.ws.rs-api
- provided
-
javax.ejb
ejb-api
@@ -87,6 +82,11 @@
javax.servlet-api
provided
+
+ org.jboss.spec.javax.ws.rs
+ jboss-jaxrs-api_2.1_spec
+ provided
+
javax.annotation
@@ -122,11 +122,6 @@
-
- org.jboss.resteasy
- resteasy-jaxrs
- test
-
org.jboss.resteasy
resteasy-client
@@ -162,7 +157,7 @@
test
-
+
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpClient.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpClient.java
index 6a1445b46cfe..beff27524a59 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpClient.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/client/JaxRsHttpClient.java
@@ -20,27 +20,31 @@
* #L%
*/
-import java.util.List;
-import java.util.Map;
-
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.api.EncodingEnum;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
+import ca.uhn.fhir.rest.client.api.Header;
+import ca.uhn.fhir.rest.client.api.HttpClientUtil;
+import ca.uhn.fhir.rest.client.api.IHttpClient;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
+import ca.uhn.fhir.rest.client.method.MethodUtil;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation.Builder;
-import javax.ws.rs.core.*;
-
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
import org.hl7.fhir.instance.model.api.IBaseBinary;
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.rest.api.*;
-import ca.uhn.fhir.rest.client.api.*;
-import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
-import ca.uhn.fhir.rest.client.method.MethodUtil;
-import ca.uhn.fhir.rest.server.RestfulServerUtils;
+import java.util.List;
+import java.util.Map;
/**
* A Http Request based on JaxRs. This is an adapter around the class
* {@link javax.ws.rs.client.Client Client}
- *
+ *
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
*/
public class JaxRsHttpClient implements IHttpClient {
@@ -52,8 +56,8 @@ public class JaxRsHttpClient implements IHttpClient {
private String myIfNoneExistString;
private RequestTypeEnum myRequestType;
- public JaxRsHttpClient(Client theClient, StringBuilder theUrl, Map> theIfNoneExistParams, String theIfNoneExistString,
- RequestTypeEnum theRequestType, List theHeaders) {
+ public JaxRsHttpClient(Client theClient, StringBuilder theUrl, Map> theIfNoneExistParams, String theIfNoneExistString,
+ RequestTypeEnum theRequestType, List theHeaders) {
this.myClient = theClient;
this.myUrl = theUrl;
this.myIfNoneExistParams = theIfNoneExistParams;
@@ -82,7 +86,7 @@ public IHttpRequest createParamRequest(FhirContext theContext, Map entity = Entity.form(map);
JaxRsHttpRequest retVal = createHttpRequest(entity);
- addHeadersToRequest(retVal, theEncoding, theContext);
+ addHeadersToRequest(retVal, theEncoding, theContext);
return retVal;
}
@@ -110,13 +114,13 @@ public void addHeadersToRequest(JaxRsHttpRequest theHttpRequest, EncodingEnum th
theHttpRequest.addHeader("User-Agent", HttpClientUtil.createUserAgentString(theContext, "jax-rs"));
theHttpRequest.addHeader("Accept-Charset", "utf-8");
-
+
Builder request = theHttpRequest.getRequest();
request.acceptEncoding("gzip");
MethodUtil.addAcceptHeaderToRequest(theEncoding, theHttpRequest, theContext);
}
-
+
private JaxRsHttpRequest createHttpRequest(Entity> entity) {
Builder request = myClient.target(myUrl.toString()).request();
JaxRsHttpRequest result = new JaxRsHttpRequest(request, myRequestType, entity);
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsBundleProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsBundleProvider.java
index 1ee23a88ef37..3c138e9bab19 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsBundleProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsBundleProvider.java
@@ -26,6 +26,8 @@
import javax.interceptor.Interceptors;
import javax.ws.rs.*;
+
+import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java
index 7a0385f3c3c0..c88df0fa98c8 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProvider.java
@@ -20,54 +20,77 @@
* #L%
*/
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.annotation.PostConstruct;
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
+import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.context.FhirVersionEnum;
+import ca.uhn.fhir.context.RuntimeResourceDefinition;
+import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
+import ca.uhn.fhir.rest.annotation.IdParam;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
+import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
+import ca.uhn.fhir.rest.api.SummaryEnum;
+import ca.uhn.fhir.rest.api.server.IRestfulResponse;
+import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
+import ca.uhn.fhir.rest.server.IResourceProvider;
+import ca.uhn.fhir.rest.server.ResourceBinding;
+import ca.uhn.fhir.rest.server.RestfulServerConfiguration;
+import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
import ca.uhn.fhir.rest.server.provider.ServerCapabilityStatementProvider;
+import ca.uhn.fhir.util.ReflectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu2.hapi.rest.server.ServerConformanceProvider;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CapabilityStatement;
import org.slf4j.LoggerFactory;
-import ca.uhn.fhir.context.*;
-import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
-import ca.uhn.fhir.rest.annotation.IdParam;
-import ca.uhn.fhir.rest.api.*;
-import ca.uhn.fhir.rest.api.server.IRestfulResponse;
-import ca.uhn.fhir.rest.server.*;
-import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
-import ca.uhn.fhir.util.ReflectionUtil;
-import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+import javax.ws.rs.GET;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* This is the conformance provider for the jax rs servers. It requires all providers to be registered during startup because the conformance profile is generated during the postconstruct phase.
- *
+ *
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
*/
-@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProvider implements IResourceProvider {
- /** the logger */
+ /**
+ * the logger
+ */
private static final org.slf4j.Logger ourLog = LoggerFactory.getLogger(AbstractJaxRsConformanceProvider.class);
- /** the server bindings */
+ /**
+ * the server bindings
+ */
private ResourceBinding myServerBinding = new ResourceBinding();
- /** the resource bindings */
+ /**
+ * the resource bindings
+ */
private ConcurrentHashMap myResourceNameToBinding = new ConcurrentHashMap();
- /** the server configuration */
+ /**
+ * the server configuration
+ */
private RestfulServerConfiguration serverConfiguration = new RestfulServerConfiguration();
- /** the conformance. It is created once during startup */
+ /**
+ * the conformance. It is created once during startup
+ */
private org.hl7.fhir.r4.model.CapabilityStatement myR4CapabilityStatement;
private org.hl7.fhir.dstu3.model.CapabilityStatement myDstu3CapabilityStatement;
private org.hl7.fhir.dstu2016may.model.Conformance myDstu2_1Conformance;
@@ -77,13 +100,10 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
/**
* Constructor allowing the description, servername and server to be set
- *
- * @param implementationDescription
- * the implementation description. If null, "" is used
- * @param serverName
- * the server name. If null, "" is used
- * @param serverVersion
- * the server version. If null, "" is used
+ *
+ * @param implementationDescription the implementation description. If null, "" is used
+ * @param serverName the server name. If null, "" is used
+ * @param serverVersion the server version. If null, "" is used
*/
protected AbstractJaxRsConformanceProvider(String implementationDescription, String serverName, String serverVersion) {
serverConfiguration.setFhirContext(getFhirContext());
@@ -94,15 +114,11 @@ protected AbstractJaxRsConformanceProvider(String implementationDescription, Str
/**
* Constructor allowing the description, servername and server to be set
- *
- * @param ctx
- * the {@link FhirContext} instance.
- * @param implementationDescription
- * the implementation description. If null, "" is used
- * @param serverName
- * the server name. If null, "" is used
- * @param serverVersion
- * the server version. If null, "" is used
+ *
+ * @param ctx the {@link FhirContext} instance.
+ * @param implementationDescription the implementation description. If null, "" is used
+ * @param serverName the server name. If null, "" is used
+ * @param serverVersion the server version. If null, "" is used
*/
protected AbstractJaxRsConformanceProvider(FhirContext ctx, String implementationDescription, String serverName, String serverVersion) {
super(ctx);
@@ -167,15 +183,15 @@ protected synchronized void setUpPostConstruct() {
/**
* This method must return all the resource providers which need to be included in the conformance
- *
+ *
* @return a map of the resource providers and their corresponding classes. This class needs to be given explicitly because retrieving the interface using {@link Object#getClass()} may not give the
- * correct interface in a jee environment.
+ * correct interface in a jee environment.
*/
protected abstract ConcurrentHashMap, IResourceProvider> getProviders();
/**
* This method will retrieve the conformance using the http OPTIONS method
- *
+ *
* @return the response containing the conformance
*/
@OPTIONS
@@ -186,7 +202,7 @@ public Response conformanceUsingOptions() throws IOException {
/**
* This method will retrieve the conformance using the http GET method
- *
+ *
* @return the response containing the conformance
*/
@GET
@@ -197,7 +213,7 @@ public Response conformance() throws IOException {
Builder request = getRequest(RequestTypeEnum.OPTIONS, RestOperationTypeEnum.METADATA);
IRestfulResponse response = request.build().getResponse();
response.addHeader(Constants.HEADER_CORS_ALLOW_ORIGIN, "*");
-
+
IBaseResource conformance;
FhirVersionEnum fhirContextVersion = super.getFhirContext().getVersion().getVersion();
switch (fhirContextVersion) {
@@ -219,7 +235,7 @@ public Response conformance() throws IOException {
default:
throw new ConfigurationException("Unsupported Fhir version: " + fhirContextVersion);
}
-
+
if (conformance != null) {
Set summaryMode = Collections.emptySet();
return (Response) response.streamResponseAsResource(conformance, false, summaryMode, Constants.STATUS_HTTP_200_OK, null, true, false);
@@ -229,11 +245,9 @@ public Response conformance() throws IOException {
/**
* This method will add a provider to the conformance. This method is almost an exact copy of {@link ca.uhn.fhir.rest.server.RestfulServer#findResourceMethods(Object)}
- *
- * @param theProvider
- * an instance of the provider interface
- * @param theProviderInterface
- * the class describing the providers interface
+ *
+ * @param theProvider an instance of the provider interface
+ * @param theProviderInterface the class describing the providers interface
* @return the numbers of basemethodbindings added
* @see ca.uhn.fhir.rest.server.RestfulServer#findResourceMethods(Object)
*/
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsPageProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsPageProvider.java
index 2ec8a4679a5d..5023802fb22a 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsPageProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsPageProvider.java
@@ -23,7 +23,10 @@
import java.io.IOException;
import javax.interceptor.Interceptors;
-import javax.ws.rs.*;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
index f1afff31a577..e5992c307b60 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
@@ -23,9 +23,13 @@
import java.util.*;
import java.util.Map.Entry;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.context.FhirContext;
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java
index da458ab8c2d9..3259d3223414 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsConformanceProviderDstu2_1Test.java
@@ -5,6 +5,7 @@
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu2_1;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
+import javax.ws.rs.core.MultivaluedMap;
import org.jboss.resteasy.specimpl.ResteasyHttpHeaders;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -16,7 +17,8 @@
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -27,7 +29,7 @@ public class AbstractJaxRsConformanceProviderDstu2_1Test {
AbstractJaxRsConformanceProvider provider;
private ConcurrentHashMap, IResourceProvider> providers;
private ResteasyHttpHeaders headers;
- private MultivaluedHashMap queryParameters;
+ private MultivaluedMap queryParameters;
@BeforeEach
public void setUp() throws Exception {
@@ -85,7 +87,7 @@ public void testConformanceInXml() throws Exception {
}
private AbstractJaxRsConformanceProvider createConformanceProvider(final ConcurrentHashMap, IResourceProvider> providers)
- throws Exception {
+ throws Exception {
AbstractJaxRsConformanceProvider result = new AbstractJaxRsConformanceProvider(FhirContext.forDstu2_1(), null, null, null) {
@Override
protected ConcurrentHashMap, IResourceProvider> getProviders() {
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java
index 5879df0fb890..620a8b3dc1c5 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderDstu3Test.java
@@ -14,7 +14,6 @@
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
-import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.test.utilities.JettyUtil;
@@ -36,6 +35,7 @@
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -68,12 +68,9 @@
public class AbstractJaxRsResourceProviderDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AbstractJaxRsResourceProviderDstu3Test.class);
+ private static final String PATIENT_NAME = "Van Houte";
private static IGenericClient client;
-
-
private static FhirContext ourCtx = FhirContext.forDstu3();
- private static final String PATIENT_NAME = "Van Houte";
-
private static int ourPort;
private static String serverBase;
private static Server jettyServer;
@@ -85,12 +82,6 @@ public class AbstractJaxRsResourceProviderDstu3Test {
private void compareResultId(int id, IBaseResource resource) {
assertEquals(id, Integer.parseInt(resource.getIdElement().getIdPart()));
}
-
- @AfterAll
- public static void afterClassClearContext() throws Exception {
- JettyUtil.closeServer(jettyServer);
- TestUtil.randomizeLocaleAndTimezone();
- }
private void compareResultUrl(String url, IBaseResource resource) {
assertEquals(url, resource.getIdElement().getValueAsString().substring(serverBase.length() - 1));
@@ -98,7 +89,7 @@ private void compareResultUrl(String url, IBaseResource resource) {
private Patient createPatient(long id) {
Patient theResource = new Patient();
- theResource.setId(new IdType(id));
+ theResource.setId(new IdType(id));
return theResource;
}
@@ -110,7 +101,9 @@ private List createPatients(int firstId, int lastId) {
return result;
}
- /** Find By Id */
+ /**
+ * Find By Id
+ */
@Test
public void findUsingGenericClientById() {
when(mock.find(any(IdType.class))).thenReturn(createPatient(1));
@@ -129,7 +122,7 @@ private Bundle getPatientBundle(int size) {
for (long i = 0; i < size; i++) {
Patient patient = createPatient(i);
BundleEntryComponent entry = new BundleEntryComponent();
- entry.setResource(patient);
+ entry.setResource(patient);
result.addEntry(entry);
}
return result;
@@ -144,7 +137,9 @@ public void setUp() {
reset(mock);
}
- /** Conditional Creates */
+ /**
+ * Conditional Creates
+ */
@Test
public void testConditionalCreate() throws Exception {
Patient toCreate = createPatient(1);
@@ -156,14 +151,16 @@ public void testConditionalCreate() throws Exception {
client.setEncoding(EncodingEnum.JSON);
MethodOutcome response = client.create().resource(toCreate).conditional()
- .where(Patient.IDENTIFIER.exactly().identifier("2")).prefer(PreferReturnEnum.REPRESENTATION).execute();
+ .where(Patient.IDENTIFIER.exactly().identifier("2")).prefer(PreferReturnEnum.REPRESENTATION).execute();
assertEquals("myIdentifier", patientCaptor.getValue().getIdentifier().get(0).getValue());
IBaseResource resource = response.getResource();
compareResultId(1, resource);
}
- /** Conformance - Server */
+ /**
+ * Conformance - Server
+ */
@Test
public void testConformance() {
final CapabilityStatement conf = client.fetchConformance().ofType(CapabilityStatement.class).execute();
@@ -180,7 +177,7 @@ public void testCreatePatient() throws Exception {
when(mock.create(patientCaptor.capture(), isNull())).thenReturn(outcome);
client.setEncoding(EncodingEnum.JSON);
final MethodOutcome response = client.create().resource(toCreate).prefer(PreferReturnEnum.REPRESENTATION)
- .execute();
+ .execute();
IBaseResource resource = response.getResource();
compareResultId(1, resource);
assertEquals("myIdentifier", patientCaptor.getValue().getIdentifier().get(0).getValue());
@@ -192,15 +189,17 @@ public void testDeletePatient() {
final IBaseOperationOutcome results = client.delete().resourceById("Patient", "1").execute().getOperationOutcome();
assertEquals("1", idCaptor.getValue().getIdPart());
}
-
- @Test
- public void testConditionalDelete() {
- when(mock.delete(idCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome());
- client.delete().resourceConditionalByType("Patient").where(Patient.IDENTIFIER.exactly().identifier("2")).execute();
- assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue());
- }
-
- /** Extended Operations */
+
+ @Test
+ public void testConditionalDelete() {
+ when(mock.delete(idCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome());
+ client.delete().resourceConditionalByType("Patient").where(Patient.IDENTIFIER.exactly().identifier("2")).execute();
+ assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue());
+ }
+
+ /**
+ * Extended Operations
+ */
@Test
public void testExtendedOperations() {
// prepare mock
@@ -214,23 +213,9 @@ public void testExtendedOperations() {
inParams.addParameter().setName("dummy").setValue(new StringType("myAwesomeDummyValue"));
//invoke
Parameters outParams = client.operation().onInstance(new IdType("Patient", "1")).named("$someCustomOperation")
- .withParameters(inParams).execute();
+ .withParameters(inParams).execute();
//verify
- assertEquals("outputValue", ((StringType)outParams.getParameter().get(0).getValue()).getValueAsString());
- }
-
- class StringTypeMatcher implements ArgumentMatcher {
- private StringType myStringType;
-
- public StringTypeMatcher(StringType stringType) {
- myStringType = stringType;
- }
-
- @Override
- public boolean matches(StringType argument) {
- return myStringType.getValue().equals(argument.getValue());
- }
-
+ assertEquals("outputValue", ((StringType) outParams.getParameter().get(0).getValue()).getValueAsString());
}
@Test
@@ -238,7 +223,7 @@ public void testExtendedOperationsUsingGet() {
// prepare mock
Parameters resultParameters = new Parameters();
resultParameters.addParameter().setName("return").setResource(createPatient(1)).setValue(new StringType("outputValue"));
- when(mock.someCustomOperation(any(IdType.class), argThat(new StringTypeMatcher(new StringType("myAwesomeDummyValue"))))).thenReturn(resultParameters);
+ when(mock.someCustomOperation(any(IdType.class), argThat(new StringTypeMatcher(new StringType("myAwesomeDummyValue"))))).thenReturn(resultParameters);
// Create the input parameters to pass to the server
Parameters inParams = new Parameters();
inParams.addParameter().setName("start").setValue(new DateType("2001-01-01"));
@@ -255,7 +240,7 @@ public void testExtendedOperationsUsingGet() {
.execute();
// verify
- assertEquals("outputValue", ((StringType)outParams.getParameter().get(0).getValue()).getValueAsString());
+ assertEquals("outputValue", ((StringType) outParams.getParameter().get(0).getValue()).getValueAsString());
}
@Test
@@ -267,37 +252,43 @@ public void testRead() {
assertEquals("1", idCaptor.getValue().getIdPart());
}
- /** Search - Compartments */
+ /**
+ * Search - Compartments
+ */
@Test
public void testSearchCompartments() {
when(mock.searchCompartment(any(IdType.class))).thenReturn(Arrays.asList((IBaseResource) createPatient(1)));
org.hl7.fhir.dstu3.model.Bundle response = client.search().forResource(Patient.class).withIdAndCompartment("1", "Condition")
- .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
+ .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
Resource resource = response.getEntry().get(0).getResource();
compareResultId(1, resource);
compareResultUrl("/Patient/1", resource);
}
- /** */
+ /**
+ *
+ */
@Test
public void testSearchPost() {
when(mock.search(ArgumentMatchers.isNull(), ArgumentMatchers.isNull()))
- .thenReturn(createPatients(1, 13));
+ .thenReturn(createPatients(1, 13));
org.hl7.fhir.dstu3.model.Bundle result = client.search().forResource("Patient").usingStyle(SearchStyleEnum.POST)
- .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
+ .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
Resource resource = result.getEntry().get(0).getResource();
compareResultId(1, resource);
compareResultUrl("/Patient/1", resource);
}
- /** Search/Query - Type */
+ /**
+ * Search/Query - Type
+ */
@Test
public void testSearchUsingGenericClientBySearch() {
// Perform a search
when(mock.search(any(StringParam.class), isNull()))
- .thenReturn(Arrays.asList(createPatient(1)));
+ .thenReturn(Arrays.asList(createPatient(1)));
final Bundle results = client.search().forResource(Patient.class)
- .where(Patient.NAME.matchesExactly().value(PATIENT_NAME)).returnBundle(Bundle.class).execute();
+ .where(Patient.NAME.matchesExactly().value(PATIENT_NAME)).returnBundle(Bundle.class).execute();
verify(mock).search(any(StringParam.class), isNull());
IBaseResource resource = results.getEntry().get(0).getResource();
@@ -305,29 +296,33 @@ public void testSearchUsingGenericClientBySearch() {
compareResultUrl("/Patient/1", resource);
}
- /** Search - Multi-valued Parameters (ANY/OR) */
+ /**
+ * Search - Multi-valued Parameters (ANY/OR)
+ */
@Test
public void testSearchUsingGenericClientBySearchWithMultiValues() {
when(mock.search(any(StringParam.class), ArgumentMatchers.notNull()))
- .thenReturn(Arrays.asList(createPatient(1)));
+ .thenReturn(Arrays.asList(createPatient(1)));
final Bundle results = client.search().forResource(Patient.class)
- .where(Patient.ADDRESS.matches().values("Toronto")).and(Patient.ADDRESS.matches().values("Ontario"))
- .and(Patient.ADDRESS.matches().values("Canada"))
- .where(Patient.NAME.matches().value("SHORTNAME")).returnBundle(Bundle.class).execute();
+ .where(Patient.ADDRESS.matches().values("Toronto")).and(Patient.ADDRESS.matches().values("Ontario"))
+ .and(Patient.ADDRESS.matches().values("Canada"))
+ .where(Patient.NAME.matches().value("SHORTNAME")).returnBundle(Bundle.class).execute();
IBaseResource resource = results.getEntry().get(0).getResource();
compareResultId(1, resource);
compareResultUrl("/Patient/1", resource);
}
- /** Search - Paging */
+ /**
+ * Search - Paging
+ */
@Test
public void testSearchWithPaging() {
// Perform a search
when(mock.search(ArgumentMatchers.isNull(), ArgumentMatchers.isNull()))
- .thenReturn(createPatients(1, 13));
+ .thenReturn(createPatients(1, 13));
final org.hl7.fhir.dstu3.model.Bundle results = client.search().forResource(Patient.class).count(8).returnBundle(org.hl7.fhir.dstu3.model.Bundle.class)
- .execute();
+ .execute();
assertEquals(results.getEntry().size(), 8);
IBaseResource resource = results.getEntry().get(0).getResource();
@@ -348,15 +343,19 @@ public void testSearchWithPaging() {
assertNull(nextPage.getLink(org.hl7.fhir.dstu3.model.Bundle.LINK_NEXT));
}
- /** Search - Subsetting (_summary and _elements) */
+ /**
+ * Search - Subsetting (_summary and _elements)
+ */
@Test
@Disabled
public void testSummary() {
Object response = client.search().forResource(Patient.class)
- .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
+ .returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
}
- /** Transaction - Server */
+ /**
+ * Transaction - Server
+ */
// @Disabled
// @Test
// public void testTransaction() {
@@ -371,7 +370,6 @@ public void testSummary() {
// entry.setTransactionMethod(theTransactionOperation);
// ca.uhn.fhir.model.api.Bundle response = client.transaction().withBundle(bundle).execute();
// }
-
@Test
public void testUpdateById() throws Exception {
when(mock.update(idCaptor.capture(), patientCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome());
@@ -379,17 +377,17 @@ public void testUpdateById() throws Exception {
assertEquals("1", idCaptor.getValue().getIdPart());
compareResultId(1, patientCaptor.getValue());
}
-
- @Test
- public void testConditionalUpdate() throws Exception {
- when(mock.update(idCaptor.capture(), patientCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome());
- client.update().resource(createPatient(1)).conditional().where(Patient.IDENTIFIER.exactly().identifier("2")).execute();
-
- assertEquals(null, patientCaptor.getValue().getIdElement().getIdPart());
- assertEquals(null, patientCaptor.getValue().getIdElement().getVersionIdPart());
- assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue());
- }
-
+
+ @Test
+ public void testConditionalUpdate() throws Exception {
+ when(mock.update(idCaptor.capture(), patientCaptor.capture(), conditionalCaptor.capture())).thenReturn(new MethodOutcome());
+ client.update().resource(createPatient(1)).conditional().where(Patient.IDENTIFIER.exactly().identifier("2")).execute();
+
+ assertEquals(null, patientCaptor.getValue().getIdElement().getIdPart());
+ assertEquals(null, patientCaptor.getValue().getIdElement().getVersionIdPart());
+ assertEquals("Patient?identifier=2&_format=json", conditionalCaptor.getValue());
+ }
+
@SuppressWarnings("unchecked")
@Disabled
@Test
@@ -425,8 +423,8 @@ public void testXFindUnknownPatient() {
assertTrue(e.getMessage().contains("999955541264"));
}
}
-
- @Test
+
+ @Test
public void testValidate() {
// prepare mock
final OperationOutcome oo = new OperationOutcome();
@@ -441,33 +439,53 @@ public void testValidate() {
assertNotNull(mO.getOperationOutcome());
}
+ class StringTypeMatcher implements ArgumentMatcher {
+ private StringType myStringType;
+
+ public StringTypeMatcher(StringType stringType) {
+ myStringType = stringType;
+ }
+
+ @Override
+ public boolean matches(StringType argument) {
+ return myStringType.getValue().equals(argument.getValue());
+ }
+
+ }
+
+ @AfterAll
+ public static void afterClassClearContext() throws Exception {
+ JettyUtil.closeServer(jettyServer);
+ TestUtil.randomizeLocaleAndTimezone();
+ }
+
@BeforeAll
public static void setUpClass() throws Exception {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
jettyServer = new Server(0);
jettyServer.setHandler(context);
- ServletHolder jerseyServlet = context.addServlet(org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.class, "/*");
+ ServletHolder jerseyServlet = context.addServlet(HttpServletDispatcher.class, "/*");
jerseyServlet.setInitOrder(0);
//@formatter:off
jerseyServlet.setInitParameter("resteasy.resources",
- StringUtils.join(Arrays.asList(
- TestJaxRsMockPatientRestProviderDstu3.class.getCanonicalName(),
+ StringUtils.join(Arrays.asList(
+ TestJaxRsMockPatientRestProviderDstu3.class.getCanonicalName(),
// JaxRsExceptionInterceptor.class.getCanonicalName(),
- TestJaxRsConformanceRestProviderDstu3.class.getCanonicalName(),
- TestJaxRsMockPageProviderDstu3.class.getCanonicalName()
- ), ","));
+ TestJaxRsConformanceRestProviderDstu3.class.getCanonicalName(),
+ TestJaxRsMockPageProviderDstu3.class.getCanonicalName()
+ ), ","));
//@formatter:on
-
+
JettyUtil.startServer(jettyServer);
- ourPort = JettyUtil.getPortForStartedServer(jettyServer);
+ ourPort = JettyUtil.getPortForStartedServer(jettyServer);
ourCtx.setRestfulClientFactory(new JaxRsRestfulClientFactory(ourCtx));
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
- serverBase = "http://localhost:" + ourPort + "/";
- client = ourCtx.newRestfulGenericClient(serverBase);
+ serverBase = "http://localhost:" + ourPort + "/";
+ client = ourCtx.newRestfulGenericClient(serverBase);
client.setEncoding(EncodingEnum.JSON);
client.registerInterceptor(new LoggingInterceptor(true));
}
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java
index c6271d0bb60c..67b5fff1d673 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProviderTest.java
@@ -439,7 +439,7 @@ public static void setUpClass() throws Exception {
context.setContextPath("/");
jettyServer = new Server(0);
jettyServer.setHandler(context);
- ServletHolder jerseyServlet = context.addServlet(org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.class, "/*");
+ ServletHolder jerseyServlet = context.addServlet(org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher.class, "/*");
jerseyServlet.setInitOrder(0);
//@formatter:off
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProvider.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProvider.java
index 09821ecda934..7d9231b09308 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProvider.java
@@ -1,22 +1,21 @@
package ca.uhn.fhir.jaxrs.server.test;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.ejb.Stateless;
+import ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.server.IResourceProvider;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider;
-import ca.uhn.fhir.rest.api.Constants;
-import ca.uhn.fhir.rest.server.IResourceProvider;
+import javax.ejb.Stateless;
+import java.util.concurrent.ConcurrentHashMap;
/**
* A conformance provider exposes the mock patient and this provider
*/
@Path("")
@Stateless
-@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
+@Produces({MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML})
public class TestJaxRsConformanceRestProvider extends AbstractJaxRsConformanceProvider {
public TestJaxRsConformanceRestProvider() {
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProviderDstu3.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProviderDstu3.java
index 5ff2b78f5402..335272b506dd 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProviderDstu3.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/server/test/TestJaxRsConformanceRestProviderDstu3.java
@@ -3,6 +3,7 @@
import java.util.concurrent.ConcurrentHashMap;
import javax.ejb.Stateless;
+
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
index cf2d4299b789..b399265fd18b 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
@@ -50,6 +50,7 @@
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.test.BaseTest;
+import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.test.utilities.LoggingExtension;
import ca.uhn.fhir.test.utilities.ProxyUtil;
import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
@@ -81,6 +82,10 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.springframework.batch.core.repository.dao.JobExecutionDao;
+import org.springframework.batch.core.repository.dao.JobInstanceDao;
+import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
+import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.jpa.JpaTransactionManager;
@@ -195,6 +200,21 @@ public abstract class BaseJpaTest extends BaseTest {
private IForcedIdDao myForcedIdDao;
@Autowired(required = false)
protected IFulltextSearchSvc myFulltestSearchSvc;
+ @Autowired(required = false)
+ protected BatchJobHelper myBatchJobHelper;
+ @Autowired(required = false)
+ private JobExecutionDao myMapJobExecutionDao;
+ @Autowired(required = false)
+ private JobInstanceDao myMapJobInstanceDao;
+
+ @AfterEach
+ public void afterEnsureNoStaleBatchJobs() {
+ if (myMapJobInstanceDao != null) {
+ myBatchJobHelper.ensureNoRunningJobs();
+ ProxyUtil.getSingletonTarget(myMapJobExecutionDao, MapJobExecutionDao.class).clear();
+ ProxyUtil.getSingletonTarget(myMapJobInstanceDao, MapJobInstanceDao.class).clear();
+ }
+ }
@AfterEach
public void afterPerformCleanup() {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
index d5434c6c63b5..4b718b5184e4 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
@@ -87,7 +87,9 @@
import ca.uhn.fhir.rest.server.BasePagingProvider;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
+import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
+import ca.uhn.fhir.test.utilities.ProxyUtil;
import ca.uhn.fhir.util.ClasspathUtil;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.validation.FhirValidator;
@@ -171,6 +173,10 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.event.Level;
+import org.springframework.batch.core.repository.dao.JobExecutionDao;
+import org.springframework.batch.core.repository.dao.JobInstanceDao;
+import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
+import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
@@ -492,11 +498,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
@Autowired
protected DaoRegistry myDaoRegistry;
@Autowired
- private IValidationSupport myJpaValidationSupportChainR4;
- private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
- @Autowired
- private IBulkDataExportSvc myBulkDataExportSvc;
- @Autowired
protected IdHelperService myIdHelperService;
@Autowired
protected IBatchJobSubmitter myBatchJobSubmitter;
@@ -504,6 +505,11 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
protected ValidationSettings myValidationSettings;
@Autowired
protected IMdmLinkDao myMdmLinkDao;
+ @Autowired
+ private IValidationSupport myJpaValidationSupportChainR4;
+ private PerformanceTracingLoggingInterceptor myPerformanceTracingLoggingInterceptor;
+ @Autowired
+ private IBulkDataExportSvc myBulkDataExportSvc;
@AfterEach()
public void afterCleanupDao() {
@@ -564,7 +570,7 @@ public void beforeFlushFT() {
@AfterEach
public void afterPurgeDatabase() {
- runInTransaction(()->{
+ runInTransaction(() -> {
myMdmLinkDao.deleteAll();
});
purgeDatabase(myDaoConfig, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataExportSvc);
@@ -623,23 +629,6 @@ protected void validate(IBaseResource theResource) {
}
}
- public class ValidationPolicyAdvisor implements IValidationPolicyAdvisor {
- @Override
- public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) {
- return ReferenceValidationPolicy.CHECK_VALID;
- }
-
- @Override
- public CodedContentValidationPolicy policyForCodedContent(IResourceValidator iResourceValidator, Object o, String s, ElementDefinition elementDefinition, org.hl7.fhir.r5.model.StructureDefinition structureDefinition, BindingKind bindingKind, org.hl7.fhir.r5.model.ValueSet valueSet, List list) {
- return CodedContentValidationPolicy.CODE;
- }
-
- @Override
- public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, String containerType, String containerId, Element.SpecialElement containingResourceType, String path, String url) {
- return ContainedReferenceValidationPolicy.CHECK_VALID;
- }
- }
-
@SuppressWarnings("unchecked")
protected void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath);
@@ -649,7 +638,6 @@ protected void upload(String theClasspath) throws IOException {
dao.update(resourceParsed);
}
-
protected void assertHierarchyContains(String... theStrings) {
List hierarchy = runInTransaction(() -> {
List hierarchyHolder = new ArrayList<>();
@@ -667,6 +655,72 @@ protected void assertHierarchyContains(String... theStrings) {
}
}
+ protected ValueSet.ConceptReferenceDesignationComponent assertConceptContainsDesignation(ValueSet.ValueSetExpansionContainsComponent theConcept, String theLanguage, String theUseSystem, String theUseCode, String theUseDisplay, String theDesignationValue) {
+ Stream stream = theConcept.getDesignation().stream();
+ if (theLanguage != null) {
+ stream = stream.filter(designation -> theLanguage.equalsIgnoreCase(designation.getLanguage()));
+ }
+ if (theUseSystem != null) {
+ stream = stream.filter(designation -> theUseSystem.equalsIgnoreCase(designation.getUse().getSystem()));
+ }
+ if (theUseCode != null) {
+ stream = stream.filter(designation -> theUseCode.equalsIgnoreCase(designation.getUse().getCode()));
+ }
+ if (theUseDisplay != null) {
+ stream = stream.filter(designation -> theUseDisplay.equalsIgnoreCase(designation.getUse().getDisplay()));
+ }
+ if (theDesignationValue != null) {
+ stream = stream.filter(designation -> theDesignationValue.equalsIgnoreCase(designation.getValue()));
+ }
+
+ Optional first = stream.findFirst();
+ if (!first.isPresent()) {
+ String failureMessage = String.format("Concept %s did not contain designation [%s|%s|%s|%s|%s] ", theConcept, theLanguage, theUseSystem, theUseCode, theUseDisplay, theDesignationValue);
+ fail(failureMessage);
+ return null;
+ } else {
+ return first.get();
+ }
+ }
+
+ protected ValueSet.ValueSetExpansionContainsComponent assertExpandedValueSetContainsConcept(ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Integer theDesignationCount) {
+ List contains = theValueSet.getExpansion().getContains();
+
+ Stream stream = contains.stream();
+ if (theSystem != null) {
+ stream = stream.filter(concept -> theSystem.equalsIgnoreCase(concept.getSystem()));
+ }
+ if (theCode != null) {
+ stream = stream.filter(concept -> theCode.equalsIgnoreCase(concept.getCode()));
+ }
+ if (theDisplay != null) {
+ stream = stream.filter(concept -> theDisplay.equalsIgnoreCase(concept.getDisplay()));
+ }
+ if (theDesignationCount != null) {
+ stream = stream.filter(concept -> concept.getDesignation().size() == theDesignationCount);
+ }
+
+ Optional first = stream.findFirst();
+ if (!first.isPresent()) {
+ String expandedValueSetString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(theValueSet);
+ String failureMessage = String.format("Expanded ValueSet %s did not contain concept [%s|%s|%s] with [%d] designations. Outcome:\n%s", theValueSet.getId(), theSystem, theCode, theDisplay, theDesignationCount, expandedValueSetString);
+ fail(failureMessage);
+ return null;
+ } else {
+ return first.get();
+ }
+ }
+
+ public List getExpandedConceptsByValueSetUrl(String theValuesetUrl) {
+ return runInTransaction(() -> {
+ List valueSets = myTermValueSetDao.findTermValueSetByUrl(Pageable.unpaged(), theValuesetUrl);
+ assertEquals(1, valueSets.size());
+ TermValueSet valueSet = valueSets.get(0);
+ List concepts = valueSet.getConcepts();
+ return concepts.stream().map(concept -> concept.getCode()).collect(Collectors.toList());
+ });
+ }
+
private static void flattenExpansionHierarchy(List theFlattenedHierarchy, List theCodes, String thePrefix) {
theCodes.sort((o1, o2) -> {
int s1 = o1.getSequence() != null ? o1.getSequence() : o1.getCode().hashCode();
@@ -796,70 +850,20 @@ public static String toSearchUuidFromLinkNext(Bundle theBundle) {
return uuid;
}
-
- protected ValueSet.ConceptReferenceDesignationComponent assertConceptContainsDesignation(ValueSet.ValueSetExpansionContainsComponent theConcept, String theLanguage, String theUseSystem, String theUseCode, String theUseDisplay, String theDesignationValue) {
- Stream stream = theConcept.getDesignation().stream();
- if (theLanguage != null) {
- stream = stream.filter(designation -> theLanguage.equalsIgnoreCase(designation.getLanguage()));
- }
- if (theUseSystem != null) {
- stream = stream.filter(designation -> theUseSystem.equalsIgnoreCase(designation.getUse().getSystem()));
- }
- if (theUseCode != null) {
- stream = stream.filter(designation -> theUseCode.equalsIgnoreCase(designation.getUse().getCode()));
- }
- if (theUseDisplay != null) {
- stream = stream.filter(designation -> theUseDisplay.equalsIgnoreCase(designation.getUse().getDisplay()));
- }
- if (theDesignationValue != null) {
- stream = stream.filter(designation -> theDesignationValue.equalsIgnoreCase(designation.getValue()));
- }
-
- Optional first = stream.findFirst();
- if (!first.isPresent()) {
- String failureMessage = String.format("Concept %s did not contain designation [%s|%s|%s|%s|%s] ", theConcept, theLanguage, theUseSystem, theUseCode, theUseDisplay, theDesignationValue);
- fail(failureMessage);
- return null;
- } else {
- return first.get();
+ public class ValidationPolicyAdvisor implements IValidationPolicyAdvisor {
+ @Override
+ public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) {
+ return ReferenceValidationPolicy.CHECK_VALID;
}
- }
-
- protected ValueSet.ValueSetExpansionContainsComponent assertExpandedValueSetContainsConcept(ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Integer theDesignationCount) {
- List contains = theValueSet.getExpansion().getContains();
- Stream stream = contains.stream();
- if (theSystem != null) {
- stream = stream.filter(concept -> theSystem.equalsIgnoreCase(concept.getSystem()));
- }
- if (theCode != null) {
- stream = stream.filter(concept -> theCode.equalsIgnoreCase(concept.getCode()));
- }
- if (theDisplay != null) {
- stream = stream.filter(concept -> theDisplay.equalsIgnoreCase(concept.getDisplay()));
- }
- if (theDesignationCount != null) {
- stream = stream.filter(concept -> concept.getDesignation().size() == theDesignationCount);
+ @Override
+ public CodedContentValidationPolicy policyForCodedContent(IResourceValidator iResourceValidator, Object o, String s, ElementDefinition elementDefinition, org.hl7.fhir.r5.model.StructureDefinition structureDefinition, BindingKind bindingKind, org.hl7.fhir.r5.model.ValueSet valueSet, List list) {
+ return CodedContentValidationPolicy.CODE;
}
- Optional first = stream.findFirst();
- if (!first.isPresent()) {
- String expandedValueSetString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(theValueSet);
- String failureMessage = String.format("Expanded ValueSet %s did not contain concept [%s|%s|%s] with [%d] designations. Outcome:\n%s", theValueSet.getId(), theSystem, theCode, theDisplay, theDesignationCount, expandedValueSetString);
- fail(failureMessage);
- return null;
- } else {
- return first.get();
+ @Override
+ public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, String containerType, String containerId, Element.SpecialElement containingResourceType, String path, String url) {
+ return ContainedReferenceValidationPolicy.CHECK_VALID;
}
}
-
- public List getExpandedConceptsByValueSetUrl(String theValuesetUrl) {
- return runInTransaction(() -> {
- List valueSets = myTermValueSetDao.findTermValueSetByUrl(Pageable.unpaged(), theValuesetUrl);
- assertEquals(1, valueSets.size());
- TermValueSet valueSet = valueSets.get(0);
- List concepts = valueSet.getConcepts();
- return concepts.stream().map(concept -> concept.getCode()).collect(Collectors.toList());
- });
- }
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
index ad1a93e57edc..a3f369761166 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
@@ -158,9 +158,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4Test.class);
- @Autowired
- private BatchJobHelper myBatchJobHelper;
-
@AfterEach
public final void after() {
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/BatchJobHelper.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/BatchJobHelper.java
index 0a8e64efe57d..b14c8257a583 100644
--- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/BatchJobHelper.java
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/BatchJobHelper.java
@@ -20,6 +20,9 @@
* #L%
*/
+import ca.uhn.fhir.util.StopWatch;
+import org.awaitility.core.ConditionTimeoutException;
+import org.hamcrest.Matchers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.BatchStatus;
@@ -37,7 +40,11 @@
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.oneOf;
import static org.junit.jupiter.api.Assertions.fail;
public class BatchJobHelper {
@@ -55,15 +62,18 @@ public List awaitAllBulkJobCompletions(String... theJobNames) {
/**
* Await and report for job completions
+ *
* @param theFailIfNotJobsFound indicate if must fail in case no matching jobs are found
- * @param theJobNames The job names to match
+ * @param theJobNames The job names to match
* @return the matched JobExecution(s)
*/
public List awaitAllBulkJobCompletions(boolean theFailIfNotJobsFound, String... theJobNames) {
assert theJobNames.length > 0;
if (theFailIfNotJobsFound) {
- await().until(() -> !getJobInstances(theJobNames).isEmpty());
+ await()
+ .alias("Wait for jobs to exist named: " + Arrays.asList(theJobNames))
+ .until(() -> getJobInstances(theJobNames), not(empty()));
}
List matchingJobInstances = getJobInstances(theJobNames);
@@ -97,19 +107,43 @@ public JobExecution awaitJobExecution(Long theJobExecutionId) {
}
protected void awaitJobCompletions(Collection theJobs) {
- theJobs.forEach(jobExecution -> awaitJobCompletion(jobExecution));
+ // This intermittently fails for unknown reasons, so I've added a bunch
+ // of extra junk here to improve what we output when it fails
+ for (JobExecution jobExecution : theJobs) {
+ try {
+ awaitJobCompletion(jobExecution);
+ } catch (ConditionTimeoutException e) {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Failed waiting for job to complete.\n");
+ msg.append("Error: ").append(e).append("\n");
+ msg.append("Statuses:");
+ for (JobExecution next : theJobs) {
+ JobExecution execution = myJobExplorer.getJobExecution(next.getId());
+ msg.append("\n * Execution ")
+ .append(execution.getId())
+ .append(" has status ")
+ .append(execution.getStatus());
+ }
+ fail(msg.toString());
+ }
+ }
}
public void awaitJobCompletion(JobExecution theJobExecution) {
- await().atMost(120, TimeUnit.SECONDS).until(() -> {
- JobExecution jobExecution = myJobExplorer.getJobExecution(theJobExecution.getId());
- ourLog.info("JobExecution {} currently has status: {}- Failures if any: {}", theJobExecution.getId(), jobExecution.getStatus(), jobExecution.getFailureExceptions());
- // JM: Adding ABANDONED status because given the description, it s similar to FAILURE, and we need to avoid tests failing because
- // of wait timeouts caused by unmatched statuses. Also adding STOPPED because tests were found where this wait timed out
- // with jobs keeping that status during the whole wait
- return jobExecution.getStatus() == BatchStatus.COMPLETED || jobExecution.getStatus() == BatchStatus.FAILED
- || jobExecution.getStatus() == BatchStatus.ABANDONED || jobExecution.getStatus() == BatchStatus.STOPPED;
- });
+ await()
+ .atMost(120, TimeUnit.SECONDS).until(() -> {
+ JobExecution jobExecution = myJobExplorer.getJobExecution(theJobExecution.getId());
+ ourLog.info("JobExecution {} currently has status: {}- Failures if any: {}", theJobExecution.getId(), jobExecution.getStatus(), jobExecution.getFailureExceptions());
+ return jobExecution.getStatus();
+ }, Matchers.oneOf(
+ // JM: Adding ABANDONED status because given the description, it s similar to FAILURE, and we need to avoid tests failing because
+ // of wait timeouts caused by unmatched statuses. Also adding STOPPED because tests were found where this wait timed out
+ // with jobs keeping that status during the whole wait
+ BatchStatus.COMPLETED,
+ BatchStatus.FAILED,
+ BatchStatus.ABANDONED,
+ BatchStatus.STOPPED
+ ));
}
public int getReadCount(Long theJobExecutionId) {
@@ -129,4 +163,24 @@ private StepExecution getStepExecution(Long theJobExecutionId) {
return stepExecutions.iterator().next();
}
+ public void ensureNoRunningJobs() {
+ for (String nextJobName : myJobExplorer.getJobNames()) {
+ List instances = myJobExplorer.getJobInstances(nextJobName, 0, 10000);
+ for (JobInstance nextInstance : instances) {
+ List executions = myJobExplorer.getJobExecutions(nextInstance);
+ for (JobExecution nextExecution : executions) {
+ ourLog.info("Have job execution {} in status: {}", nextExecution.getId(), nextExecution.getStatus());
+ try {
+ await().until(() -> myJobExplorer.getJobExecution(nextExecution.getId()).getStatus(), oneOf(BatchStatus.STOPPED, BatchStatus.ABANDONED, BatchStatus.FAILED, BatchStatus.COMPLETED));
+ } catch (ConditionTimeoutException e) {
+ JobExecution execution = myJobExplorer.getJobExecution(nextExecution.getId());
+ fail("Execution " + execution + "\n" +
+ "Instance: " + nextInstance + "\n" +
+ "Job: " + nextJobName);
+ }
+
+ }
+ }
+ }
+ }
}
diff --git a/pom.xml b/pom.xml
index 818df5f410b2..0dcacac6ced6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -825,7 +825,7 @@
3.8.1
4.1.2
1.4
- 4.0.0.Beta3
+ 5.0.2.Final
5.6.5
9.5.4
2.9.0
@@ -1156,11 +1156,6 @@
validation-api
2.0.1.Final
-
- javax.ws.rs
- javax.ws.rs-api
- 2.0.1
-