diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java index 03e602326ce..fbc1e3e5408 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java @@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.search; * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -63,6 +63,18 @@ public class PersistedJpaBundleProvider implements IBundleProvider { myDao = theDao; } + /** + * When HAPI FHIR server is running "for real", a new + * instance of the bundle provider is created to serve + * every HTTP request, so it's ok for us to keep + * state in here and expect that it will go away. But + * in unit tests we keep this object around for longer + * sometimes. + */ + public void clearCachedDataForUnitTest() { + mySearchEntity = null; + } + protected List doHistoryInTransaction(int theFromIndex, int theToIndex) { List results; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java index bf776616241..f3baaf0a5c4 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java @@ -1,15 +1,15 @@ package ca.uhn.fhir.jpa.dao; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.jpa.entity.*; +import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test; import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc; +import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.term.VersionIndependentConcept; import ca.uhn.fhir.jpa.util.ExpungeOptions; import ca.uhn.fhir.jpa.util.JpaConstants; import ca.uhn.fhir.jpa.util.LoggingRule; -import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.rest.api.server.IBundleProvider; @@ -17,9 +17,9 @@ import ca.uhn.fhir.rest.api.server.IRequestOperationCallback; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.BundleUtil; +import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; -import org.hibernate.search.jpa.Search; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Resource; import org.hl7.fhir.instance.model.api.IBaseBundle; @@ -30,12 +30,7 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; import org.mockito.Mockito; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; -import javax.persistence.EntityManager; import java.io.IOException; import java.io.InputStream; import java.util.*; @@ -49,13 +44,12 @@ import static org.mockito.Mockito.when; public abstract class BaseJpaTest { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class); + @Rule + public LoggingRule myLoggingRule = new LoggingRule(); protected ServletRequestDetails mySrd; protected ArrayList myServerInterceptorList; protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class); - @Rule - public LoggingRule myLoggingRule = new LoggingRule(); - @After public final void afterPerformCleanup() { BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(false); @@ -166,24 +160,29 @@ public abstract class BaseJpaTest { } protected List toUnqualifiedVersionlessIds(IBundleProvider theFound) { + PersistedJpaBundleProvider provider = (PersistedJpaBundleProvider) theFound; + List retVal = new ArrayList<>(); - Integer size = theFound.size(); + Integer size = provider.size(); StopWatch sw = new StopWatch(); while (size == null) { int timeout = 20000; if (sw.getMillis() > timeout) { - fail("Waited over "+timeout+"ms for search"); + String message = "Waited over " + timeout + "ms for search " + provider.getUuid(); + ourLog.info(message); + fail(message); } try { Thread.sleep(100); } catch (InterruptedException theE) { //ignore } - size = theFound.size(); + provider.clearCachedDataForUnitTest(); + size = provider.size(); } ourLog.info("Found {} results", size); - List resources = theFound.getResources(0, size); + List resources = provider.getResources(0, size); for (IBaseResource next : resources) { retVal.add(next.getIdElement().toUnqualifiedVersionless()); } @@ -250,7 +249,7 @@ public abstract class BaseJpaTest { return bundleStr; } - public static void purgeDatabase(DaoConfig theDaoConfig, IFhirSystemDao theSystemDao, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) { + public static void purgeDatabase(DaoConfig theDaoConfig, IFhirSystemDao theSystemDao, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) { theSearchCoordinatorSvc.cancelAllActiveSearches(); boolean expungeEnabled = theDaoConfig.isExpungeEnabled(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java index 0c1e762798b..d484407c1aa 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java @@ -47,9 +47,9 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test { String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome); ourLog.info(ooString); - assertThat(ooString, containsString("Element '.subject': minimum required = 1, but only found 0")); - assertThat(ooString, containsString("Element encounter @ : max allowed = 0, but found 1")); - assertThat(ooString, containsString("Element '.device': minimum required = 1, but only found 0")); + assertThat(ooString, containsString("Element 'Observation.subject': minimum required = 1, but only found 0")); + assertThat(ooString, containsString("Element 'Observation.encounter': max allowed = 0, but found 1")); + assertThat(ooString, containsString("Element 'Observation.device': minimum required = 1, but only found 0")); } @Test @@ -59,9 +59,9 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test { String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome); ourLog.info(ooString); - assertThat(ooString, containsString("Element '/f:Observation.subject': minimum required = 1, but only found 0")); - assertThat(ooString, containsString("Element encounter @ /f:Observation: max allowed = 0, but found 1")); - assertThat(ooString, containsString("Element '/f:Observation.device': minimum required = 1, but only found 0")); + assertThat(ooString, containsString("Element 'Observation.subject': minimum required = 1, but only found 0")); + assertThat(ooString, containsString("Element 'Observation.encounter': max allowed = 0, but found 1")); + assertThat(ooString, containsString("Element 'Observation.device': minimum required = 1, but only found 0")); } private OperationOutcome doTestValidateResourceContainingProfileDeclaration(String methodName, EncodingEnum enc) throws IOException { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/BaseResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/BaseResourceProviderDstu2Test.java index b50dd291a99..993a1923503 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/BaseResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/BaseResourceProviderDstu2Test.java @@ -132,7 +132,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test { } protected List toIdListUnqualifiedVersionless(Bundle found) { - List list = new ArrayList(); + List list = new ArrayList<>(); for (Entry next : found.getEntry()) { list.add(next.getResource().getId().toUnqualifiedVersionless()); } @@ -140,7 +140,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test { } protected List toNameList(Bundle resp) { - List names = new ArrayList(); + List names = new ArrayList<>(); for (Entry next : resp.getEntry()) { Patient nextPt = (Patient) next.getResource(); String nextStr = nextPt.getNameFirstRep().getGivenAsSingleString() + " " + nextPt.getNameFirstRep().getFamilyAsSingleString(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderInterceptorDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderInterceptorDstu2Test.java index 886471b482e..f4e267243cb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderInterceptorDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderInterceptorDstu2Test.java @@ -154,7 +154,7 @@ public class ResourceProviderInterceptorDstu2Test extends BaseResourceProviderDs ArgumentCaptor ardCaptor = ArgumentCaptor.forClass(ActionRequestDetails.class); ArgumentCaptor opTypeCaptor = ArgumentCaptor.forClass(RestOperationTypeEnum.class); verify(myServerInterceptor, times(2)).incomingRequestPreHandled(opTypeCaptor.capture(), ardCaptor.capture()); - assertEquals(RestOperationTypeEnum.TRANSACTION, opTypeCaptor.getAllValues().get(0)); + assertEquals("Had types: " + opTypeCaptor.getAllValues() + " and requests: " + ardCaptor.getAllValues()RestOperationTypeEnum.TRANSACTION, opTypeCaptor.getAllValues().get(0)); assertEquals(null, ardCaptor.getAllValues().get(0).getResourceType()); assertNotNull(ardCaptor.getAllValues().get(0).getResource()); assertEquals(RestOperationTypeEnum.CREATE, opTypeCaptor.getAllValues().get(1)); @@ -175,10 +175,10 @@ public class ResourceProviderInterceptorDstu2Test extends BaseResourceProviderDs ardCaptor = ArgumentCaptor.forClass(ActionRequestDetails.class); opTypeCaptor = ArgumentCaptor.forClass(RestOperationTypeEnum.class); verify(myDaoInterceptor, atLeast(2)).incomingRequestPreHandled(opTypeCaptor.capture(), ardCaptor.capture()); - assertEquals(RestOperationTypeEnum.TRANSACTION, opTypeCaptor.getAllValues().get(0)); + assertEquals("Had types: " + opTypeCaptor.getAllValues() + " and requests: " + ardCaptor.getAllValues(), RestOperationTypeEnum.TRANSACTION, opTypeCaptor.getAllValues().get(0)); assertEquals("Bundle", ardCaptor.getAllValues().get(0).getResourceType()); assertNotNull(ardCaptor.getAllValues().get(0).getResource()); - assertEquals(RestOperationTypeEnum.CREATE, opTypeCaptor.getAllValues().get(1)); + assertEquals("Had types: " + opTypeCaptor.getAllValues() + " and requests: " + ardCaptor.getAllValues(), RestOperationTypeEnum.CREATE, opTypeCaptor.getAllValues().get(1)); assertEquals("Patient", ardCaptor.getAllValues().get(1).getResourceType()); assertNotNull(ardCaptor.getAllValues().get(1).getResource()); diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/IServerInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/IServerInterceptor.java index c2b2ec9d8b2..e91709dc40f 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/IServerInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/IServerInterceptor.java @@ -33,6 +33,8 @@ import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -368,6 +370,15 @@ public interface IServerInterceptor { return myResourceType; } + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("id", myId) + .append("resourceType", myResourceType) + .append("resource", myResource) + .toString(); + } + /** * Returns the same map which was */