diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java index 0f41138cc20..1cd6d7098cf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java @@ -25,11 +25,15 @@ import com.google.common.collect.ImmutableSet; import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath.ClassInfo; import org.apache.commons.lang3.Validate; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.InstantType; +import org.hl7.fhir.r4.model.Patient; import javax.persistence.*; import java.io.IOException; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; +import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -165,10 +169,21 @@ public class TestUtil { ourLog.info("Sleeping for {}ms", timeToSleep); Thread.sleep(timeToSleep); } catch (InterruptedException theE) { - theE.printStackTrace(); + ourLog.error("Interrupted", theE); } } } + public static void clearAllStaticFieldsForUnitTest() { + ca.uhn.fhir.util.TestUtil.clearAllStaticFieldsForUnitTest(); + } + + public static InstantType getTimestamp(IBaseResource resource) { + return new InstantType(new Date(resource.getMeta().getLastUpdated().getTime())); + } + + public static void sleepOneClick() { + sleepAtLeast(1); + } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchNoFtTest.java index 7bfd40cfb5c..bfa828616d7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchNoFtTest.java @@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao; import ca.uhn.fhir.jpa.model.entity.*; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.dstu2.composite.*; @@ -19,7 +20,6 @@ import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -374,6 +374,9 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test { patient.addIdentifier().setSystem("urn:system").setValue("001"); id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + + TestUtil.sleepOneClick(); + long betweenTime = System.currentTimeMillis(); IIdType id2; { @@ -820,8 +823,6 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test { @Test public void testSearchLastUpdatedParamWithComparator() throws InterruptedException { - String methodName = "testSearchLastUpdatedParamWithComparator"; - IIdType id0; { Patient patient = new Patient(); @@ -829,18 +830,16 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test { id0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - int sleep = 100; - long start = System.currentTimeMillis(); - Thread.sleep(sleep); + TestUtil.sleepOneClick(); - DateTimeDt beforeAny = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI); IIdType id1a; { Patient patient = new Patient(); patient.addIdentifier().setSystem("urn:system").setValue("001"); id1a = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); IIdType id1b; { Patient patient = new Patient(); @@ -853,11 +852,12 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test { InstantDt id1bpublished = ResourceMetadataKeyEnum.PUBLISHED.get(myPatientDao.read(id1b, mySrd)); ourLog.info("Res 3: {}", id1bpublished.getValueAsString()); - Thread.sleep(sleep); + TestUtil.sleepOneClick(); long end = System.currentTimeMillis(); SearchParameterMap params; Date startDate = new Date(start); + TestUtil.sleepOneClick(); Date endDate = new Date(end); DateTimeDt startDateTime = new DateTimeDt(startDate, TemporalPrecisionEnum.MILLI); DateTimeDt endDateTime = new DateTimeDt(endDate, TemporalPrecisionEnum.MILLI); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java index 5ebda85d4df..77bdfa62ed1 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java @@ -13,6 +13,7 @@ import javax.servlet.http.HttpServletRequest; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.util.TestUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.dstu3.model.*; @@ -40,7 +41,6 @@ import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.TestUtil; @SuppressWarnings("unchecked") public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { @@ -667,6 +667,9 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } long betweenTime = System.currentTimeMillis(); + + TestUtil.sleepOneClick(); + IIdType id2; { Patient patient = new Patient(); @@ -1020,7 +1023,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe"); id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - + TestUtil.sleepOneClick(); Date betweenTime = new Date(); IIdType id2; @@ -1196,10 +1199,9 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { id0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - int sleep = 100; - + TestUtil.sleepOneClick(); long start = System.currentTimeMillis(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(sleep); + TestUtil.sleepOneClick(); IIdType id1a; { @@ -1218,7 +1220,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { ourLog.info("Res 2: {}", myPatientDao.read(id1a, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); ourLog.info("Res 3: {}", myPatientDao.read(id1b, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(sleep); + TestUtil.sleepOneClick(); long end = System.currentTimeMillis(); SearchParameterMap map; @@ -1615,18 +1617,18 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { obs01.setSubject(new Reference(patientId01)); IIdType obsId01 = myObservationDao.create(obs01, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date between = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Observation obs02 = new Observation(); obs02.setEffective(new DateTimeType(new Date())); obs02.setSubject(new Reference(locId01)); IIdType obsId02 = myObservationDao.create(obs02, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date after = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[] { patientId01, locId01, obsId01, obsId02 }); @@ -1853,15 +1855,15 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { patient.addName().setFamily("Tester_testSearchStringParam").addGiven("Joe"); pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); Date between = new Date(); - Thread.sleep(10); { Patient patient = new Patient(); patient.addIdentifier().setSystem("urn:system").setValue("002"); patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); pid2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - Thread.sleep(10); + TestUtil.sleepOneClick(); Date after = new Date(); SearchParameterMap params; @@ -2871,6 +2873,8 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { tag1id = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); + Date betweenDate = new Date(); IIdType tag2id; @@ -3193,7 +3197,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { p01.addName().setFamily("B").addGiven("A"); String id1 = myPatientDao.create(p01).getId().toUnqualifiedVersionless().getValue(); - Thread.sleep(10); + TestUtil.sleepOneClick(); // Numeric ID Patient p02 = new Patient(); @@ -3203,7 +3207,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { p02.addName().setFamily("Z").addGiven("Z"); String id2 = myPatientDao.create(p02).getId().toUnqualifiedVersionless().getValue(); - Thread.sleep(10); + TestUtil.sleepOneClick(); // Forced ID Patient pAB = new Patient(); @@ -3213,7 +3217,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { pAB.addName().setFamily("A").addGiven("B"); myPatientDao.update(pAB); - Thread.sleep(10); + TestUtil.sleepOneClick(); // Forced ID Patient pAA = new Patient(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchPageExpiryTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchPageExpiryTest.java index 90b19eaaa53..779e8175506 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchPageExpiryTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchPageExpiryTest.java @@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao; import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4SearchPageExpiryTest; import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; @@ -29,7 +30,6 @@ import org.springframework.transaction.support.TransactionTemplate; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.*; @@ -105,8 +105,7 @@ public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test { } assertEquals(searchUuid1, searchUuid2); - sleepAtLeast(501); - + TestUtil.sleepAtLeast(501); // We're now past 500ms so we shouldn't reuse the search final String searchUuid3; @@ -277,7 +276,7 @@ public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test { } assertEquals(searchUuid1, searchUuid2); - sleepAtLeast(501); + TestUtil.sleepAtLeast(501); // We're now past 500ms so we shouldn't reuse the search @@ -363,7 +362,7 @@ public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test { } }); if (search == null) { - sleepAtLeast(100); + TestUtil.sleepAtLeast(100); } } assertNotNull("Search " + bundleProvider.getUuid() + " not found on disk after 10 seconds", search); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java index d8b94a50f9f..0d41ad30e2c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java @@ -2867,21 +2867,21 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { p.addName().setFamily(methodName); IIdType id1 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); p = new Patient(); p.addIdentifier().setSystem("urn:system2").setValue(methodName); p.addName().setFamily(methodName); IIdType id2 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); p = new Patient(); p.addIdentifier().setSystem("urn:system3").setValue(methodName); p.addName().setFamily(methodName); IIdType id3 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); p = new Patient(); p.addIdentifier().setSystem("urn:system4").setValue(methodName); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3UpdateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3UpdateTest.java index 51089f210d4..ae9c5f521c9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3UpdateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3UpdateTest.java @@ -306,7 +306,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test { assertEquals("1", outcome.getId().getVersionIdPart()); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date now = new Date(); Patient retrieved = myPatientDao.read(outcome.getId(), mySrd); InstantType updated = retrieved.getMeta().getLastUpdatedElement().copy(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java index 9c60aea71f1..9e297d4d916 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java @@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.ValidationModeEnum; @@ -11,7 +12,6 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.util.StopWatch; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; @@ -25,8 +25,6 @@ import org.junit.Test; import java.io.IOException; import java.nio.charset.StandardCharsets; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; - public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ValidateTest.class); @@ -64,7 +62,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test { MethodOutcome results = myQuestionnaireResponseDao.validate(qr, null, null, null, null, null, null); ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(results.getOperationOutcome())); - sleepAtLeast(2500); + TestUtil.sleepAtLeast(2500); try { myQuestionnaireResponseDao.validate(qr, null, null, null, null, null, null); fail(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java index f49b54e57bf..221fbeaec8c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.model.entity.*; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.parser.StrictErrorHandler; @@ -12,7 +13,6 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IAnyResource; @@ -151,16 +151,16 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { List ids; Date beforeAll = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Organization org = new Organization(); org.setName("O1"); org.setId("O1"); myOrganizationDao.update(org); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date beforePatient = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Patient p = new Patient(); p.setId("P1"); @@ -168,7 +168,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { p.setManagingOrganization(new Reference("Organization/O1")); myPatientDao.update(p); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date afterAll = new Date(); // Search with between date (should still return Organization even though @@ -216,7 +216,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { myOrganizationDao.update(org); Date beforeAll = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Patient p = new Patient(); p.setId("P1"); @@ -224,17 +224,17 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { p.setManagingOrganization(new Reference("Organization/O1")); myPatientDao.update(p); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date beforeOrg = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); org = new Organization(); org.setActive(true); org.setId("O1"); myOrganizationDao.update(org); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date afterAll = new Date(); // Everything should come back @@ -889,7 +889,11 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { patient.addIdentifier().setSystem("urn:system").setValue("001"); id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + + TestUtil.sleepOneClick(); + long betweenTime = System.currentTimeMillis(); + IIdType id2; { Patient patient = new Patient(); @@ -1264,8 +1268,12 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); + Date betweenTime = new Date(); + TestUtil.sleepOneClick(); + IIdType id2; { Patient patient = new Patient(); @@ -1439,10 +1447,11 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { id0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - int sleep = 100; + TestUtil.sleepOneClick(); long start = System.currentTimeMillis(); - Thread.sleep(sleep); + + TestUtil.sleepOneClick(); IIdType id1a; { @@ -1450,6 +1459,9 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { patient.addIdentifier().setSystem("urn:system").setValue("001"); id1a = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + + TestUtil.sleepOneClick(); + IIdType id1b; { Patient patient = new Patient(); @@ -1461,7 +1473,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { ourLog.info("Res 2: {}", myPatientDao.read(id1a, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); ourLog.info("Res 3: {}", myPatientDao.read(id1b, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); - Thread.sleep(sleep); + TestUtil.sleepOneClick(); + long end = System.currentTimeMillis(); SearchParameterMap map; @@ -1487,7 +1500,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { map = new SearchParameterMap(); map.setLastUpdated(new DateRangeParam(new DateParam(ParamPrefixEnum.GREATERTHAN, startDateTime.getValue()), - new DateParam(ParamPrefixEnum.LESSTHAN, myPatientDao.read(id1b, mySrd).getMeta().getLastUpdatedElement().getValue()))); + new DateParam(ParamPrefixEnum.LESSTHAN, TestUtil.getTimestamp(myPatientDao.read(id1b, mySrd))))); ourLog.info("Searching: {}", map.getLastUpdated()); assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a)); } @@ -1857,15 +1870,15 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { obs01.setSubject(new Reference(patientId01)); IIdType obsId01 = myObservationDao.create(obs01, mySrd).getId().toUnqualifiedVersionless(); + TestUtil.sleepOneClick(); Date between = new Date(); - Thread.sleep(10); Observation obs02 = new Observation(); obs02.setEffective(new DateTimeType(new Date())); obs02.setSubject(new Reference(locId01)); IIdType obsId02 = myObservationDao.create(obs02, mySrd).getId().toUnqualifiedVersionless(); - Thread.sleep(10); + TestUtil.sleepOneClick(); Date after = new Date(); ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", patientId01, locId01, obsId01, obsId02); @@ -1988,15 +2001,16 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { patient.addName().setFamily("Tester_testSearchStringParam").addGiven("Joe"); pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); Date between = new Date(); - Thread.sleep(10); + { Patient patient = new Patient(); patient.addIdentifier().setSystem("urn:system").setValue("002"); patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); pid2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - Thread.sleep(10); + TestUtil.sleepOneClick(); Date after = new Date(); SearchParameterMap params; @@ -2966,6 +2980,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { tag1id = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); + Date betweenDate = new Date(); IIdType tag2id; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java index ff2144142d3..9d2c7036f75 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoHashesTest.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.model.entity.*; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.parser.StrictErrorHandler; @@ -12,7 +13,6 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IAnyResource; @@ -153,16 +153,16 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { List ids; Date beforeAll = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Organization org = new Organization(); org.setName("O1"); org.setId("O1"); myOrganizationDao.update(org); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date beforePatient = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Patient p = new Patient(); p.setId("P1"); @@ -170,7 +170,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { p.setManagingOrganization(new Reference("Organization/O1")); myPatientDao.update(p); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date afterAll = new Date(); // Search with between date (should still return Organization even though @@ -218,7 +218,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { myOrganizationDao.update(org); Date beforeAll = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Patient p = new Patient(); p.setId("P1"); @@ -226,17 +226,17 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { p.setManagingOrganization(new Reference("Organization/O1")); myPatientDao.update(p); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date beforeOrg = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); org = new Organization(); org.setActive(true); org.setId("O1"); myOrganizationDao.update(org); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(100); + ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick(); Date afterAll = new Date(); // Everything should come back @@ -891,6 +891,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { patient.addIdentifier().setSystem("urn:system").setValue("001"); id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); long betweenTime = System.currentTimeMillis(); IIdType id2; { @@ -1266,6 +1267,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); + Date betweenTime = new Date(); IIdType id2; @@ -1349,8 +1352,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { public void testSearchLastUpdatedParam() throws InterruptedException { String methodName = "testSearchLastUpdatedParam"; - int sleep = 100; - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(sleep); + TestUtil.sleepOneClick(); DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); IIdType id1a; @@ -1368,9 +1370,9 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { id1b = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1100); + TestUtil.sleepAtLeast(1100); DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(1100); + TestUtil.sleepAtLeast(1100); IIdType id2; { @@ -1441,10 +1443,11 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { id0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - int sleep = 100; + TestUtil.sleepOneClick(); long start = System.currentTimeMillis(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(sleep); + + TestUtil.sleepOneClick(); IIdType id1a; { @@ -1452,6 +1455,9 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { patient.addIdentifier().setSystem("urn:system").setValue("001"); id1a = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + + TestUtil.sleepOneClick(); + IIdType id1b; { Patient patient = new Patient(); @@ -1463,11 +1469,13 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { ourLog.info("Res 2: {}", myPatientDao.read(id1a, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); ourLog.info("Res 3: {}", myPatientDao.read(id1b, mySrd).getMeta().getLastUpdatedElement().getValueAsString()); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(sleep); + TestUtil.sleepOneClick(); + long end = System.currentTimeMillis(); SearchParameterMap map; Date startDate = new Date(start); + TestUtil.sleepOneClick(); Date endDate = new Date(end); DateTimeType startDateTime = new DateTimeType(startDate, TemporalPrecisionEnum.MILLI); DateTimeType endDateTime = new DateTimeType(endDate, TemporalPrecisionEnum.MILLI); @@ -1489,7 +1497,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { map = new SearchParameterMap(); map.setLastUpdated(new DateRangeParam(new DateParam(ParamPrefixEnum.GREATERTHAN, startDateTime.getValue()), - new DateParam(ParamPrefixEnum.LESSTHAN, myPatientDao.read(id1b, mySrd).getMeta().getLastUpdatedElement().getValue()))); + new DateParam(ParamPrefixEnum.LESSTHAN, TestUtil.getTimestamp(myPatientDao.read(id1b, mySrd))))); ourLog.info("Searching: {}", map.getLastUpdated()); assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a)); } @@ -1860,14 +1868,14 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { IIdType obsId01 = myObservationDao.create(obs01, mySrd).getId().toUnqualifiedVersionless(); Date between = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(10); + TestUtil.sleepOneClick(); Observation obs02 = new Observation(); obs02.setEffective(new DateTimeType(new Date())); obs02.setSubject(new Reference(locId01)); IIdType obsId02 = myObservationDao.create(obs02, mySrd).getId().toUnqualifiedVersionless(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(10); + TestUtil.sleepOneClick(); Date after = new Date(); ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", patientId01, locId01, obsId01, obsId02); @@ -1990,15 +1998,16 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { patient.addName().setFamily("Tester_testSearchStringParam").addGiven("Joe"); pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); Date between = new Date(); - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(10); + TestUtil.sleepOneClick(); { Patient patient = new Patient(); patient.addIdentifier().setSystem("urn:system").setValue("002"); patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); pid2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); } - ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast(10); + TestUtil.sleepOneClick(); Date after = new Date(); SearchParameterMap params; @@ -2945,6 +2954,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test { tag1id = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); } + TestUtil.sleepOneClick(); + Date betweenDate = new Date(); IIdType tag2id; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java index aa99e4dbb4b..1dd6c8a479d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java @@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao; import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.SearchStatusEnum; import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; @@ -29,7 +30,6 @@ import javax.annotation.Nullable; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; -import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.*; @@ -100,7 +100,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } assertEquals(searchUuid1, searchUuid2); - sleepAtLeast(501); + TestUtil.sleepAtLeast(501); // We're now past 500ms so we shouldn't reuse the search @@ -274,7 +274,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } assertEquals(searchUuid1, searchUuid2); - sleepAtLeast(501); + TestUtil.sleepAtLeast(501); // We're now past 500ms so we shouldn't reuse the search @@ -360,7 +360,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { } }); if (search == null) { - sleepAtLeast(100); + TestUtil.sleepAtLeast(100); } } assertNotNull("Search " + bundleProvider.getUuid() + " not found on disk after 10 seconds", search); @@ -407,7 +407,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test { for (int i = 0; i < 20 && search == null; i++) { search = theSearchEntityDao.findByUuid(theUuid); if (search == null || search.getStatus() == SearchStatusEnum.LOADING) { - sleepAtLeast(100); + TestUtil.sleepAtLeast(100); } } assertNotNull(search); 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 f75d4a5fbba..ea6c924d38b 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 @@ -10,6 +10,7 @@ import ca.uhn.fhir.jpa.model.entity.*; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; @@ -20,7 +21,6 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.util.TestUtil; import com.google.common.base.Charsets; import com.google.common.collect.Lists; import org.apache.commons.io.IOUtils; @@ -3159,16 +3159,22 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test { p.addName().setFamily(methodName); IIdType id1 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); + TestUtil.sleepOneClick(); + p = new Patient(); p.addIdentifier().setSystem("urn:system2").setValue(methodName); p.addName().setFamily(methodName); IIdType id2 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); + TestUtil.sleepOneClick(); + p = new Patient(); p.addIdentifier().setSystem("urn:system3").setValue(methodName); p.addName().setFamily(methodName); IIdType id3 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); + TestUtil.sleepOneClick(); + p = new Patient(); p.addIdentifier().setSystem("urn:system4").setValue(methodName); p.addName().setFamily(methodName); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UpdateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UpdateTest.java index aa6008ccc73..9301cbd1c59 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UpdateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UpdateTest.java @@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4; import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; @@ -12,7 +13,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.*; @@ -313,12 +313,15 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test { assertEquals("1", outcome.getId().getVersionIdPart()); + TestUtil.sleepOneClick(); + Date now = new Date(); + Patient retrieved = myPatientDao.read(outcome.getId(), mySrd); - InstantType updated = retrieved.getMeta().getLastUpdatedElement().copy(); + InstantType updated = TestUtil.getTimestamp(retrieved); assertTrue(updated.before(now)); - Thread.sleep(1000); + TestUtil.sleepOneClick(); reset(myInterceptor); retrieved.getIdentifier().get(0).setValue("002"); @@ -335,17 +338,18 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test { assertEquals("Patient", details.getResourceType()); assertEquals(Patient.class, details.getResource().getClass()); + TestUtil.sleepOneClick(); Date now2 = new Date(); Patient retrieved2 = myPatientDao.read(outcome.getId().toVersionless(), mySrd); assertEquals("2", retrieved2.getIdElement().getVersionIdPart()); assertEquals("002", retrieved2.getIdentifier().get(0).getValue()); - InstantType updated2 = retrieved2.getMeta().getLastUpdatedElement(); + InstantType updated2 = TestUtil.getTimestamp(retrieved2); assertTrue(updated2.after(now)); assertTrue(updated2.before(now2)); - Thread.sleep(2000); + TestUtil.sleepOneClick(); /* * Get history 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 ae52fbdfcd3..af487089ba1 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 @@ -211,9 +211,11 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test { obs.getCode().setText("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL"); myObservationDao.update(obs, mySrd); + // Try to wait for the indexing to complete + waitForSize(2, ()-> fetchSuggestionCount(ptId)); + HttpGet get = new HttpGet(ourServerBase + "/$suggest-keywords?context=Patient/" + ptId.getIdPart() + "/$everything&searchParam=_content&text=zxc&_pretty=true&_format=xml"); - CloseableHttpResponse http = ourHttpClient.execute(get); - try { + try (CloseableHttpResponse http = ourHttpClient.execute(get)) { assertEquals(200, http.getStatusLine().getStatusCode()); String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(output); @@ -225,8 +227,16 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test { assertEquals("score", parameters.getParameter().get(0).getPart().get(1).getName()); assertEquals(new DecimalDt("1.0"), parameters.getParameter().get(0).getPart().get(1).getValue()); - } finally { - http.close(); + } + } + + private Number fetchSuggestionCount(IIdType thePtId) throws IOException { + HttpGet get = new HttpGet(ourServerBase + "/$suggest-keywords?context=Patient/" + thePtId.getIdPart() + "/$everything&searchParam=_content&text=zxc&_pretty=true&_format=xml"); + try (CloseableHttpResponse http = ourHttpClient.execute(get)) { + assertEquals(200, http.getStatusLine().getStatusCode()); + String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8); + Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output); + return parameters.getParameter().size(); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java index 1792f9fe300..dd4eb173b2f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4CacheTest.java @@ -2,12 +2,12 @@ package ca.uhn.fhir.jpa.provider.r4; import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.parser.StrictErrorHandler; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Patient; import org.junit.After; @@ -160,12 +160,18 @@ public class ResourceProviderR4CacheTest extends BaseResourceProviderR4Test { Date beforeFirst = new Date(); + TestUtil.sleepOneClick(); + Bundle results1 = ourClient.search().forResource("Patient").where(Patient.FAMILY.matches().value("FAM")).returnBundle(Bundle.class).execute(); + + TestUtil.sleepOneClick(); + assertEquals(1, results1.getEntry().size()); assertEquals(1, mySearchEntityDao.count()); assertThat(myCapturingInterceptor.getLastResponse().getHeaders(Constants.HEADER_X_CACHE), empty()); - assertThat(results1.getMeta().getLastUpdated(), greaterThan(beforeFirst)); - assertThat(results1.getMeta().getLastUpdated(), lessThan(new Date())); + Date results1Date = TestUtil.getTimestamp(results1).getValue(); + assertThat(results1Date, greaterThan(beforeFirst)); + assertThat(results1Date, lessThan(new Date())); assertThat(results1.getId(), not(blankOrNullString())); Patient pt2 = new Patient(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index 4a4cddfa7e7..aee27813903 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -37,6 +37,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; +import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.rest.api.PreferReturnEnum; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -116,13 +117,13 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; import ca.uhn.fhir.util.StopWatch; -import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.UrlUtil; @SuppressWarnings("Duplicates") public class ResourceProviderR4Test extends BaseResourceProviderR4Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class); + public static final int LARGE_NUMBER = 77; private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw; private CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor(); @@ -1755,7 +1756,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { p.setActive(true); IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless(); - for (int i = 1; i < 77; i++) { + for (int i = 1; i < LARGE_NUMBER; i++) { Observation obs = new Observation(); obs.setId("A" + StringUtils.leftPad(Integer.toString(i), 2, '0')); obs.setSubject(new Reference(id)); @@ -1793,8 +1794,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { } assertThat(ids, hasItem(id.getIdPart())); - assertEquals(77, ids.size()); - for (int i = 1; i < 77; i++) { + assertEquals(LARGE_NUMBER, ids.size()); + for (int i = 1; i < LARGE_NUMBER; i++) { assertThat(ids.size() + " ids: " + ids, ids, hasItem("A" + StringUtils.leftPad(Integer.toString(i), 2, '0'))); } } @@ -3687,6 +3688,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { Search search1 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuid(uuid1)); Date lastReturned1 = search1.getSearchLastReturned(); + TestUtil.sleepOneClick(); + Bundle result2 = ourClient .search() .forResource("Organization") diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java index 137d05f9492..3c4300011c7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java @@ -279,6 +279,9 @@ public class SystemProviderR4Test extends BaseJpaR4Test { obs.getCode().setText("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL"); myObservationDao.update(obs, mySrd); + // Try to wait for the indexing to complete + waitForSize(2, ()-> fetchSuggestionCount(ptId)); + HttpGet get = new HttpGet(ourServerBase + "/$suggest-keywords?context=Patient/" + ptId.getIdPart() + "/$everything&searchParam=_content&text=zxc&_pretty=true&_format=xml"); CloseableHttpResponse http = ourHttpClient.execute(get); try { @@ -298,6 +301,16 @@ public class SystemProviderR4Test extends BaseJpaR4Test { } } + private Number fetchSuggestionCount(IIdType thePtId) throws IOException { + HttpGet get = new HttpGet(ourServerBase + "/$suggest-keywords?context=Patient/" + thePtId.getIdPart() + "/$everything&searchParam=_content&text=zxc&_pretty=true&_format=xml"); + try (CloseableHttpResponse http = ourHttpClient.execute(get)) { + assertEquals(200, http.getStatusLine().getStatusCode()); + String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8); + Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output); + return parameters.getParameter().size(); + } + } + @Test public void testSuggestKeywordsInvalid() throws Exception { Patient patient = new Patient(); diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/api/HookParams.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/api/HookParams.java index 5c97f1ae081..5156e67c66a 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/api/HookParams.java +++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/api/HookParams.java @@ -23,6 +23,8 @@ package ca.uhn.fhir.jpa.model.interceptor.api; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -73,4 +75,7 @@ public class HookParams { return myParams.values().stream().map(t -> t.getClass().getSimpleName()).collect(Collectors.toList()); } + public Collection values() { + return Collections.unmodifiableCollection(myParams.values()); + } } diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java index f240b810453..b055a20d5c4 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java @@ -311,6 +311,15 @@ public class CanonicalSubscription implements Serializable, Cloneable { myDeliverLatestVersion = theDeliverLatestVersion; } + + public boolean isStripVersionId() { + return myStripVersionId; + } + + public void setStripVersionId(boolean theStripVersionId) { + myStripVersionId = theStripVersionId; + } + @Override public boolean equals(Object theO) { if (this == theO) return true; @@ -333,14 +342,6 @@ public class CanonicalSubscription implements Serializable, Cloneable { .toHashCode(); } - public boolean isStripVersionId() { - return myStripVersionId; - } - - public void setStripVersionId(boolean theStripVersionId) { - myStripVersionId = theStripVersionId; - } - } @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/ActiveSubscriptionCache.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/ActiveSubscriptionCache.java index 0aa92298c04..6afcd485850 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/ActiveSubscriptionCache.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/ActiveSubscriptionCache.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.subscription.module.cache; * #L% */ +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.Validate; import java.util.ArrayList; @@ -69,4 +70,9 @@ public class ActiveSubscriptionCache { } } } + + @VisibleForTesting + public void clearForUnitTests() { + myCache.clear(); + } } diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java index 4199054d76b..0c87b0d0076 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java @@ -28,6 +28,7 @@ import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.IPrimitiveDatatype; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; +import org.hl7.fhir.dstu3.model.Subscription; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -96,10 +97,10 @@ public class SubscriptionCanonicalizer { retVal.setIdElement(subscription.getIdElement()); retVal.setPayloadString(subscription.getChannel().getPayload()); - if (retVal.getChannelType() == CanonicalSubscriptionChannelType.EMAIL) { + if (retVal.getChannelType() == CanonicalSubscriptionChannelType.EMAIL) { String from; String subjectTemplate; - String bodyTemplate; + try { from = subscription.getChannel().getExtensionString(SubscriptionConstants.EXT_SUBSCRIPTION_EMAIL_FROM); subjectTemplate = subscription.getChannel().getExtensionString(SubscriptionConstants.EXT_SUBSCRIPTION_SUBJECT_TEMPLATE); @@ -111,6 +112,7 @@ public class SubscriptionCanonicalizer { } if (retVal.getChannelType() == CanonicalSubscriptionChannelType.RESTHOOK) { + String stripVersionIds; String deliverLatestVersion; try { diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionRegistry.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionRegistry.java index 29c6e939d2c..7c9b9b5da50 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionRegistry.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionRegistry.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.interceptor.api.IInterceptorRegistry; import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription; +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -155,4 +156,9 @@ public class SubscriptionRegistry { public int size() { return myActiveSubscriptionCache.size(); } + + @VisibleForTesting + public void clearForUnitTests() { + myActiveSubscriptionCache.clearForUnitTests(); + } } diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java new file mode 100644 index 00000000000..6c0a5108203 --- /dev/null +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java @@ -0,0 +1,151 @@ +package ca.uhn.fhir.jpa.subscription.module; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.model.interceptor.api.HookParams; +import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousLambdaHook; +import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class PointcutLatch implements IAnonymousLambdaHook { + private static final Logger ourLog = LoggerFactory.getLogger(PointcutLatch.class); + private static final int DEFAULT_TIMEOUT_SECONDS = 10; + private final String name; + + private CountDownLatch myCountdownLatch; + private AtomicReference myFailure; + private AtomicReference> myCalledWith; + + public PointcutLatch(Pointcut thePointcut) { + this.name = thePointcut.name(); + } + + public PointcutLatch(String theName) { + this.name = theName; + } + + public void setExpectedCount(int count) throws InterruptedException { + if (myCountdownLatch != null) { + throw new PointcutLatchException("setExpectedCount() called before previous awaitExpected() completed."); + } + createLatch(count); + } + + private void createLatch(int count) { + myFailure = new AtomicReference<>(); + myCalledWith = new AtomicReference<>(new ArrayList<>()); + myCountdownLatch = new CountDownLatch(count); + } + + private void setFailure(String failure) { + if (myFailure != null) { + myFailure.set(failure); + } else { + throw new PointcutLatchException("trying to set failure on latch that hasn't been created: " + failure); + } + } + + private String getName() { + return name + " " + this.getClass().getSimpleName(); + } + + public void awaitExpected() throws InterruptedException { + awaitExpectedWithTimeout(DEFAULT_TIMEOUT_SECONDS); + } + + public void awaitExpectedWithTimeout(int timeoutSecond) throws InterruptedException { + try { + assertNotNull(getName() + " awaitExpected() called before setExpected() called.", myCountdownLatch); + assertTrue(getName() + " timed out waiting " + timeoutSecond + " seconds for latch to be triggered.", myCountdownLatch.await(timeoutSecond, TimeUnit.SECONDS)); + + if (myFailure.get() != null) { + String error = getName() + ": " + myFailure.get(); + error += "\nLatch called with values: " + myCalledWithString(); + throw new AssertionError(error); + } + } finally { + destroyLatch(); + } + } + + public void expectNothing() { + destroyLatch(); + } + + private void destroyLatch() { + myCountdownLatch = null; + } + + private String myCalledWithString() { + if (myCalledWith == null) { + return "[]"; + } + List calledWith = myCalledWith.get(); + if (calledWith.isEmpty()) { + return "[]"; + } + String retVal = "[ "; + retVal += calledWith.stream().flatMap(hookParams -> hookParams.values().stream()).map(itemToString()).collect(Collectors.joining(", ")); + return retVal + " ]"; + } + + private static Function itemToString() { + return object -> { + if (object instanceof IBaseResource) { + IBaseResource resource = (IBaseResource) object; + return "Resource " + resource.getIdElement().getValue(); + } else if (object instanceof ResourceModifiedMessage) { + ResourceModifiedMessage resourceModifiedMessage = (ResourceModifiedMessage)object; + // FIXME KHS can we get the context from the payload? + return "ResourceModified Message { " + resourceModifiedMessage.getOperationType() + ", " + resourceModifiedMessage.getNewPayload(FhirContext.forDstu3()).getIdElement().getValue() + "}"; + } else { + return object.toString(); + } + }; + } + + @Override + public void invoke(HookParams theArgs) { + if (myCountdownLatch == null) { + throw new PointcutLatchException("countdown() called before setExpectedCount() called.", theArgs); + } else if (myCountdownLatch.getCount() <= 0) { + setFailure("countdown() called " + (1 - myCountdownLatch.getCount()) + " more times than expected."); + } + + this.countdown(); + if (myCalledWith.get() != null) { + myCalledWith.get().add(theArgs); + } + } + + private void countdown() { + ourLog.info("{} counting down {}", name, myCountdownLatch); + myCountdownLatch.countDown(); + } + + private class PointcutLatchException extends IllegalStateException { + public PointcutLatchException(String message, HookParams theArgs) { + super(getName() + ": " + message + " called with values: " + hookParamsToString(theArgs)); + } + + public PointcutLatchException(String message) { + super(getName() + ": " + message); + } + } + + private static String hookParamsToString(HookParams hookParams) { + return hookParams.values().stream().map(itemToString()).collect(Collectors.joining(", ")); + } +} diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java index 8b3186ea951..f2608b12f95 100644 --- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java @@ -1,9 +1,14 @@ package ca.uhn.fhir.jpa.subscription.module.standalone; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.model.interceptor.api.HookParams; +import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut; +import ca.uhn.fhir.jpa.model.interceptor.executor.InterceptorRegistry; import ca.uhn.fhir.jpa.subscription.module.BaseSubscriptionDstu3Test; +import ca.uhn.fhir.jpa.subscription.module.PointcutLatch; import ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage; import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionChannelFactory; +import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry; import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceModifiedJsonMessage; import ca.uhn.fhir.jpa.subscription.module.subscriber.SubscriptionMatchingSubscriberTest; import ca.uhn.fhir.rest.annotation.Create; @@ -21,6 +26,7 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -33,9 +39,11 @@ import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicLong; public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends BaseSubscriptionDstu3Test { private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionMatchingSubscriberTest.class); + protected static ObservationListener ourObservationListener; @Autowired FhirContext myFhirContext; @@ -43,6 +51,11 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base StandaloneSubscriptionMessageHandler myStandaloneSubscriptionMessageHandler; @Autowired SubscriptionChannelFactory mySubscriptionChannelFactory; + @Autowired + InterceptorRegistry myInterceptorRegistry; + @Autowired + protected SubscriptionRegistry mySubscriptionRegistry; + protected String myCode = "1000000050"; @@ -55,30 +68,44 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base protected static List ourContentTypes = Collections.synchronizedList(new ArrayList<>()); private static SubscribableChannel ourSubscribableChannel; private List mySubscriptionIds = Collections.synchronizedList(new ArrayList<>()); - private long idCounter = 0; + private static AtomicLong idCounter = new AtomicLong(); + protected PointcutLatch mySubscriptionMatchingPost = new PointcutLatch(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED); + protected PointcutLatch mySubscriptionActivatedPost = new PointcutLatch(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED); @Before public void beforeReset() { ourCreatedObservations.clear(); ourUpdatedObservations.clear(); ourContentTypes.clear(); + mySubscriptionRegistry.clearForUnitTests(); if (ourSubscribableChannel == null) { ourSubscribableChannel = mySubscriptionChannelFactory.newDeliveryChannel("test", Subscription.SubscriptionChannelType.RESTHOOK.toCode().toLowerCase()); ourSubscribableChannel.subscribe(myStandaloneSubscriptionMessageHandler); } + myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED, mySubscriptionMatchingPost); + myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED, mySubscriptionActivatedPost); } - public T sendResource(T theResource) { + @After + public void cleanup() { + myInterceptorRegistry.clearAnonymousHookForUnitTest(); + } + + public T sendResource(T theResource) throws InterruptedException { ResourceModifiedMessage msg = new ResourceModifiedMessage(myFhirContext, theResource, ResourceModifiedMessage.OperationTypeEnum.CREATE); ResourceModifiedJsonMessage message = new ResourceModifiedJsonMessage(msg); + mySubscriptionMatchingPost.setExpectedCount(1); ourSubscribableChannel.send(message); + mySubscriptionMatchingPost.awaitExpected(); return theResource; } protected Subscription sendSubscription(String theCriteria, String thePayload, String theEndpoint) throws InterruptedException { Subscription subscription = returnedActiveSubscription(theCriteria, thePayload, theEndpoint); - - return sendResource(subscription); + mySubscriptionActivatedPost.setExpectedCount(1); + Subscription retval = sendResource(subscription); + mySubscriptionActivatedPost.awaitExpected(); + return retval; } protected Subscription returnedActiveSubscription(String theCriteria, String thePayload, String theEndpoint) { @@ -86,8 +113,7 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)"); subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE); subscription.setCriteria(theCriteria); - ++idCounter; - IdType id = new IdType("Subscription", idCounter); + IdType id = new IdType("Subscription", idCounter.incrementAndGet()); subscription.setId(id); Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent(); @@ -98,10 +124,9 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base return subscription; } - protected Observation sendObservation(String code, String system) { + protected Observation sendObservation(String code, String system) throws InterruptedException { Observation observation = new Observation(); - ++idCounter; - IdType id = new IdType("Observation", idCounter); + IdType id = new IdType("Observation", idCounter.incrementAndGet()); observation.setId(id); CodeableConcept codeableConcept = new CodeableConcept(); @@ -115,15 +140,14 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base return sendResource(observation); } - @BeforeClass public static void startListenerServer() throws Exception { ourListenerPort = PortUtil.findFreePort(); ourListenerRestServer = new RestfulServer(FhirContext.forDstu3()); ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context"; - ObservationListener obsListener = new ObservationListener(); - ourListenerRestServer.setResourceProviders(obsListener); + ourObservationListener = new ObservationListener(); + ourListenerRestServer.setResourceProviders(ourObservationListener); ourListenerServer = new Server(ourListenerPort); @@ -145,6 +169,8 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base public static class ObservationListener implements IResourceProvider { + private PointcutLatch updateLatch = new PointcutLatch("Observation Update"); + @Create public MethodOutcome create(@ResourceParam Observation theObservation, HttpServletRequest theRequest) { ourLog.info("Received Listener Create"); @@ -162,8 +188,21 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base public MethodOutcome update(@ResourceParam Observation theObservation, HttpServletRequest theRequest) { ourContentTypes.add(theRequest.getHeader(Constants.HEADER_CONTENT_TYPE).replaceAll(";.*", "")); ourUpdatedObservations.add(theObservation); + updateLatch.invoke(new HookParams().add(Observation.class, theObservation)); ourLog.info("Received Listener Update (now have {} updates)", ourUpdatedObservations.size()); return new MethodOutcome(new IdType("Observation/1"), false); } + + public void setExpectedCount(int count) throws InterruptedException { + updateLatch.setExpectedCount(count); + } + + public void awaitExpected() throws InterruptedException { + updateLatch.awaitExpected(); + } + + public void expectNothing() { + updateLatch.expectNothing(); + } } } diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionCheckingSubscriberTest.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionCheckingSubscriberTest.java index 2b656d1f79d..d3fe0ba2a38 100644 --- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionCheckingSubscriberTest.java +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionCheckingSubscriberTest.java @@ -1,10 +1,12 @@ package ca.uhn.fhir.jpa.subscription.module.subscriber; +import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry; import ca.uhn.fhir.jpa.subscription.module.standalone.BaseBlockingQueueSubscribableChannelDstu3Test; import ca.uhn.fhir.rest.api.Constants; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import static org.junit.Assert.assertEquals; @@ -25,10 +27,13 @@ public class SubscriptionCheckingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(1, ourUpdatedObservations); + ourObservationListener.setExpectedCount(1); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.awaitExpected(); + + assertEquals(1, ourContentTypes.size()); assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0)); } @@ -43,10 +48,13 @@ public class SubscriptionCheckingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(1, ourUpdatedObservations); + ourObservationListener.setExpectedCount(1); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.awaitExpected(); + + assertEquals(1, ourContentTypes.size()); assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0)); } @@ -61,9 +69,12 @@ public class SubscriptionCheckingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(0, ourUpdatedObservations); + ourObservationListener.setExpectedCount(0); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.expectNothing(); + + assertEquals(0, ourContentTypes.size()); } } diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionMatchingSubscriberTest.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionMatchingSubscriberTest.java index 2a8e605a577..446b903e4a3 100644 --- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionMatchingSubscriberTest.java +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/SubscriptionMatchingSubscriberTest.java @@ -25,10 +25,13 @@ public class SubscriptionMatchingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(1, ourUpdatedObservations); + ourObservationListener.setExpectedCount(1); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.awaitExpected(); + + assertEquals(1, ourContentTypes.size()); assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0)); } @@ -43,10 +46,13 @@ public class SubscriptionMatchingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(1, ourUpdatedObservations); + ourObservationListener.setExpectedCount(1); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.awaitExpected(); + + assertEquals(1, ourContentTypes.size()); assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0)); } @@ -61,9 +67,12 @@ public class SubscriptionMatchingSubscriberTest extends BaseBlockingQueueSubscri sendSubscription(criteria1, payload, ourListenerServerBase); sendSubscription(criteria2, payload, ourListenerServerBase); - sendObservation(code, "SNOMED-CT"); + assertEquals(2, mySubscriptionRegistry.size()); - waitForSize(0, ourCreatedObservations); - waitForSize(0, ourUpdatedObservations); + ourObservationListener.setExpectedCount(0); + sendObservation(code, "SNOMED-CT"); + ourObservationListener.expectNothing(); + + assertEquals(0, ourContentTypes.size()); } }