Merging master into working branch.

This commit is contained in:
Diederik Muylwyk 2019-12-30 14:36:58 -05:00
commit 990b43de2a
29 changed files with 97 additions and 77 deletions

View File

@ -23,7 +23,7 @@ jobs:
env:
JAVA_HOME_11_X64: /usr/local/openjdk-11
inputs:
goals: 'clean install'
goals: 'clean dependency:resolve install'
# These are Maven CLI options (and show up in the build logs) - "-nsu"=Don't update snapshots. We can remove this when Maven OSS is more healthy
options: '-P ALLMODULES,JACOCO,CI,ERRORPRONE -nsu'
# These are JVM options (and don't show up in the build logs)

View File

@ -97,7 +97,7 @@ List<ExtensionDt> resourceExts = patient.getUndeclaredExtensionsByUrl("http://fo
// Get all non-modifier extensions regardless of URL
List<ExtensionDt> nonModExts = patient.getUndeclaredExtensions();
//Get all non-modifier extensions regardless of URL
// Get all modifier extensions regardless of URL
List<ExtensionDt> modExts = patient.getUndeclaredModifierExtensions();
//END SNIPPET: parseExtension

View File

@ -150,7 +150,7 @@ List<Extension> resourceExts = patient.getExtensionsByUrl("http://fooextensions.
// Get all non-modifier extensions regardless of URL
List<Extension> nonModExts = patient.getExtension();
//Get all non-modifier extensions regardless of URL
// Get all modifier extensions regardless of URL
List<Extension> modExts = patient.getModifierExtension();
//END SNIPPET: parseExtension

View File

@ -74,7 +74,7 @@ List<ExtensionDt> resourceExts = patient.getUndeclaredExtensionsByUrl("http://fo
// Get all non-modifier extensions regardless of URL
List<ExtensionDt> nonModExts = patient.getUndeclaredExtensions();
//Get all non-modifier extensions regardless of URL
// Get all modifier extensions regardless of URL
List<ExtensionDt> modExts = patient.getUndeclaredModifierExtensions();
//END SNIPPET: parseExtension

View File

@ -304,6 +304,28 @@
"lat": -6.914744,
"lon": 107.609810,
"added": "2019-11-22"
},
{
"title": "Ivido",
"description": "Revolutionary personal healthcare environment",
"link": "https://ivido.nl/",
"contactName": "Jari Maijenburg",
"contactEmail": "info@ivido.nl",
"city": "The Hague, The Netherlands",
"lat": 52.070499,
"lon": 4.300700,
"added": "2019-12-18"
},
{
"title": "CDSS for EHR",
"description": "\"Hospital Italiano de Buenos Aires\", founded in 1853, is a non-profit civil association dedicated to general and highly complex medicine.",
"link": null,
"contactName": "Natalia Pérez López",
"contactEmail": "natalia.perez@hospitalitaliano.org.ar",
"city": "Buenos Aires, Argentina",
"lat": -34.603683,
"lon": -58.381557,
"added": "2019-12-27"
}
]

View File

@ -50,4 +50,9 @@
issue: 1588
type: add
title: "Support for several new operators has been added to the `_filter` support in the JPA server. Thanks
to Anthony Sute for the Pull Request!
to Anthony Sute for the Pull Request!"
- item:
issue: 1650
type: fix
title: Several misleading comments in documentation code snippets were fixed. Thanks to
Jafer Khan for the pull request!

View File

@ -18,5 +18,5 @@ The HAPI JPA Server has the following components:
# Schema
This implementation uses a fairly simple table design, with a single table being used to hold resource bodies (which are stored as CLOBs, optionally GZipped to save space) and a set of tables to hold search indexes, tags, history details, etc. This design has proven to be very scalable and flexible, and has been successfully used in large scale production architectures. That said,
This implementation uses a fairly simple table design, with a single table being used to hold resource bodies (which are stored as CLOBs, optionally GZipped to save space) and a set of tables to hold search indexes, tags, history details, etc. This design has proven to be very scalable and flexible, and has been successfully used in large scale production architectures. That said, this design is still only one of many possible ways of designing a FHIR server so it is worth considering whether it is appropriate for the problem you are trying to solve.

View File

@ -698,7 +698,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<runOrder>alphabetical</runOrder>
<argLine>@{argLine} ${surefire_jvm_args}</argLine>
<argLine>@{argLine} ${surefire_jvm_args} -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError</argLine>
<forkCount>0.6C</forkCount>
<excludes>*StressTest*</excludes>
</configuration>

View File

@ -1771,8 +1771,12 @@ public class SearchBuilder implements ISearchBuilder {
Predicate predicate;
if ((operation == null) ||
(operation == SearchFilterParser.CompareOperation.sw) ||
(operation == SearchFilterParser.CompareOperation.ew) ||
(operation == SearchFilterParser.CompareOperation.sw)) {
Long hash = ResourceIndexedSearchParamString.calculateHashNormalized(myDaoConfig.getModelConfig(), theResourceName, theParamName, normalizedString);
Predicate hashCode = theBuilder.equal(theFrom.get("myHashNormalizedPrefix").as(Long.class), hash);
Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), likeExpression);
predicate = theBuilder.and(hashCode, singleCode);
} else if ((operation == SearchFilterParser.CompareOperation.ew) ||
(operation == SearchFilterParser.CompareOperation.co)) {
Predicate singleCode = theBuilder.like(theFrom.get("myValueNormalized").as(String.class), likeExpression);
predicate = combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode);

View File

@ -31,9 +31,6 @@ import java.util.UUID;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
@TestPropertySource(properties = {
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE
})
public class BulkDataExportSvcImplR4Test extends BaseJpaR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(BulkDataExportSvcImplR4Test.class);

View File

@ -35,11 +35,6 @@ public class TestJPAConfig {
return retVal;
}
@Bean
public UnregisterScheduledProcessor unregisterScheduledProcessor(Environment theEnv) {
return new UnregisterScheduledProcessor(theEnv);
}
@Lazy
@Bean
public SubscriptionTestUtil subscriptionTestUtil() {

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.LoggingRule;
import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
@ -45,6 +46,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
@ -67,6 +69,11 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@TestPropertySource(properties = {
// Since scheduled tasks can cause searches, which messes up the
// value returned by SearchBuilder.getLastHandlerMechanismForUnitTest()
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE
})
public abstract class BaseJpaTest extends BaseTest {
protected static final String CM_URL = "http://example.com/my_concept_map";

View File

@ -25,9 +25,6 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.reset;
@TestPropertySource(properties = {
"scheduling_disabled=true"
})
public class FhirResourceDaoR4QueryCountTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4QueryCountTest.class);

View File

@ -45,10 +45,6 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@TestPropertySource(properties = {
"scheduling_disabled=true"
})
@SuppressWarnings({"unchecked", "deprecation", "Duplicates"})
public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchOptimizedTest.class);

View File

@ -27,10 +27,12 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
@ -44,6 +46,8 @@ import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4ConfigWithElasticSearch.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@Ignore // FIXME: remove
public class FhirResourceDaoR4SearchWithElasticSearchTest extends BaseJpaTest {
public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system";
public static final String URL_MY_VALUE_SET = "http://example.com/my_value_set";

View File

@ -31,6 +31,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
@ -47,6 +48,7 @@ import static org.junit.Assert.fail;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4WithLuceneDisabledConfig.class})
@DirtiesContext
public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchWithLuceneDisabledTest.class);
@Autowired

View File

@ -54,11 +54,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@TestPropertySource(properties = {
// Since scheduled tasks can cause searches, which messes up the
// value returned by SearchBuilder.getLastHandlerMechanismForUnitTest()
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE
})
public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4UniqueSearchParamTest.class);

View File

@ -28,9 +28,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@TestPropertySource(properties = {
"scheduling_disabled=true"
})
public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4UpdateTest.class);

View File

@ -600,7 +600,11 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
.executeUpdate();
});
assertEquals(0, myPatientDao.search(searchParamMap).size().intValue());
myCaptureQueriesListener.clear();
Integer found = myPatientDao.search(searchParamMap).size();
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
assertEquals(0, found.intValue());
myResourceReindexingSvc.markAllResourcesForReindexing();
myResourceReindexingSvc.forceReindexingPass();

View File

@ -1,22 +1,16 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestR4Config;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.param.HasParam;
import ca.uhn.fhir.test.BaseTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4Config.class})
public class SearchParameterMapTest {
@Autowired
FhirContext myContext;
public class SearchParameterMapTest extends BaseTest {
private FhirContext myContext = FhirContext.forR4();
@Test
public void toNormalizedQueryStringTest() {
@ -25,4 +19,5 @@ public class SearchParameterMapTest {
String criteria = params.toNormalizedQueryString(myContext);
assertEquals(criteria, "?_has:Observation:identifier:urn:system|FOO=urn%3Asystem%7CFOO");
}
}

View File

@ -1,6 +1,5 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.config.TestR4Config;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import org.hl7.fhir.instance.model.api.IIdType;
@ -10,18 +9,12 @@ import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Reference;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4Config.class})
public class TransactionDeleteR4Test extends BaseJpaR4SystemTest {
@After

View File

@ -35,11 +35,6 @@ import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@TestPropertySource(properties = {
// Since scheduled tasks can cause searches, which messes up the
// value returned by SearchBuilder.getLastHandlerMechanismForUnitTest()
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE
})
public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StaleSearchDeletingSvcR4Test.class);

View File

@ -20,6 +20,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.AopTestUtils;
@ -34,6 +35,7 @@ import static org.junit.Assert.fail;
@ContextConfiguration(classes = SchedulerServiceImplTest.TestConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class SchedulerServiceImplTest {
private static final Logger ourLog = LoggerFactory.getLogger(SchedulerServiceImplTest.class);

View File

@ -35,6 +35,7 @@ import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.codesystems.HttpVerb;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.util.AopTestUtils;
@ -53,11 +54,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@TestPropertySource(properties = {
// Since scheduled tasks can cause searches, which messes up the
// value returned by SearchBuilder.getLastHandlerMechanismForUnitTest()
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE,
"max_db_connections=10"
})
@DirtiesContext
public class StressTestR4Test extends BaseResourceProviderR4Test {
static {

View File

@ -17,15 +17,30 @@ 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.test.utilities.JettyUtil;
import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
import com.google.common.collect.Lists;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.Subscription;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
@ -33,12 +48,18 @@ import java.util.Collections;
import java.util.List;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* Test the rest-hook subscriptions
*/
@SuppressWarnings("Duplicates")
@TestPropertySource(properties = {
UnregisterScheduledProcessor.SCHEDULING_DISABLED + "=false"
})
@DirtiesContext
public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SubscriptionTriggeringDstu3Test.class);
@ -244,7 +265,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
// Create lots
for (int i = 0; i < 10; i++) {
Patient p = new Patient();
p.setId("P"+i);
p.setId("P" + i);
p.addName().setFamily("P" + i);
ourClient.update().resource(p).execute();
}
@ -278,7 +299,7 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
// Create lots
for (int i = 0; i < 10; i++) {
Patient p = new Patient();
p.setId("P"+i);
p.setId("P" + i);
p.addName().setFamily("P" + i);
ourClient.update().resource(p).execute();
}
@ -521,8 +542,8 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
ourListenerServer.setHandler(proxyHandler);
JettyUtil.startServer(ourListenerServer);
ourListenerPort = JettyUtil.getPortForStartedServer(ourListenerServer);
ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context";
ourListenerPort = JettyUtil.getPortForStartedServer(ourListenerServer);
ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context";
}
@AfterClass

View File

@ -21,9 +21,6 @@ import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Nonnull;
import java.io.IOException;
@TestPropertySource(properties = {
"scheduling_disabled=true"
})
public abstract class BaseTermR4Test extends BaseJpaR4Test {
IIdType myExtensionalCsId;

View File

@ -30,9 +30,6 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.*;
@TestPropertySource(properties = {
"scheduling_disabled=true"
})
public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcDeltaR4Test.class);

View File

@ -33,8 +33,4 @@ public class TestSubscriptionConfig {
return new InMemorySubscriptionMatcher();
}
@Bean
public UnregisterScheduledProcessor unregisterScheduledProcessor(Environment theEnv) {
return new UnregisterScheduledProcessor(theEnv);
}
}

View File

@ -601,7 +601,7 @@
<fhir_core_version>4.1.7-SNAPSHOT</fhir_core_version>
<ucum_version>1.0.2</ucum_version>
<surefire_jvm_args>-Dfile.encoding=UTF-8 -Xmx1024m</surefire_jvm_args>
<surefire_jvm_args>-Dfile.encoding=UTF-8 -Xmx2048m</surefire_jvm_args>
<!-- configure timestamp in MANIFEST.MF for maven-war-provider -->
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
@ -1313,7 +1313,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.8</version>
<version>42.2.9</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>