This commit is contained in:
James Agnew 2024-11-07 11:04:18 -05:00 committed by GitHub
commit d36efc8b9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 455 additions and 185 deletions

View File

@ -162,6 +162,7 @@ ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.onlyNegativeMatchesFound=Only negative matches found
ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.fullTextSearchingNotPossible=Fulltext searching is not enabled on this server, can not support the parameter(s): {0}
ca.uhn.fhir.jpa.dao.JpaResourceDaoSearchParameter.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1}
ca.uhn.fhir.jpa.search.builder.QueryStack.textModifierDisabledForSearchParam=The :text modifier is disabled for this search parameter

View File

@ -0,0 +1,11 @@
---
type: add
issue: 6426
title: "Previously, it was not possible to enable Hibernate Search but not use it
for fulltext indexing. This meant that you could not enable HS-based terminology
services without also enabling fulltext indexing of all resources. A new setting
has been added to the JpaStorageSettings bean
called `HibernateSearchIndexFullText` which controls whether HS will be used for
fulltext indexing. The existing property `AdvancedHSearchIndexing` has also been
deprecated and a new equivalent (but better named) property
called `HibernateSearchIndexSearchParams`."

View File

@ -0,0 +1,9 @@
---
- item:
type: "add"
title: "The version of a few dependencies have been bumped to the latest versions
(dependent HAPI modules listed in brackets):
<ul>
<li>H2 (JPA): 2.2.224 -&gt; 2.3.232</li>
<li>Postgresql JDBC Driver (JPA): 42.7.3 -&gt; 42.7.4</li>
</ul>"

View File

@ -56,6 +56,7 @@ import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.BaseTag;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryProvenanceEntity;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
@ -162,8 +163,6 @@ import static org.apache.commons.lang3.StringUtils.trim;
public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStorageResourceDao<T>
implements IDao, IJpaDao<T>, ApplicationContextAware {
public static final long INDEX_STATUS_INDEXED = 1L;
public static final long INDEX_STATUS_INDEXING_FAILED = 2L;
public static final String NS_JPA_PROFILE = "https://github.com/hapifhir/hapi-fhir/ns/jpa/profile";
private static final Logger ourLog = LoggerFactory.getLogger(BaseHapiFhirDao.class);
private static boolean ourValidationDisabledForUnitTest;
@ -904,7 +903,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
entity.setUpdated(theDeletedTimestampOrNull);
entity.setNarrativeText(null);
entity.setContentText(null);
entity.setIndexStatus(INDEX_STATUS_INDEXED);
entity.setIndexStatus(getEntityIndexedStatusEnum());
changed = populateResourceIntoEntity(theTransactionDetails, theRequest, theResource, entity, true);
} else {
@ -978,7 +977,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
entity.setUpdated(theTransactionDetails.getTransactionDate());
}
newParams.populateResourceTableSearchParamsPresentFlags(entity);
entity.setIndexStatus(INDEX_STATUS_INDEXED);
entity.setIndexStatus(getEntityIndexedStatusEnum());
}
if (myFulltextSearchSvc != null && !myFulltextSearchSvc.isDisabled()) {
@ -1114,6 +1113,22 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
return entity;
}
/**
* This methor returns the {@link EntityIndexStatusEnum} value that should be
* used for a successfully fully indexed resource. This method will return
* {@link EntityIndexStatusEnum#INDEXED_ALL} or {@link EntityIndexStatusEnum#INDEXED_RDBMS_ONLY}
* depending on configuration.
*/
@Nonnull
private EntityIndexStatusEnum getEntityIndexedStatusEnum() {
if (myStorageSettings.isHibernateSearchIndexFullText()
|| myStorageSettings.isHibernateSearchIndexSearchParams()) {
return EntityIndexStatusEnum.INDEXED_ALL;
} else {
return EntityIndexStatusEnum.INDEXED_RDBMS_ONLY;
}
}
/**
* Make sure that the match URL was actually appropriate for the supplied
* resource, if so configured, or do it only for first version, since technically it
@ -1675,9 +1690,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
theEntity.setNarrativeText(null);
theEntity.setContentText(null);
} else {
theEntity.setNarrativeText(parseNarrativeTextIntoWords(theResource));
theEntity.setContentText(parseContentTextIntoWords(theContext, theResource));
if (myStorageSettings.isAdvancedHSearchIndexing()) {
if (myStorageSettings.isHibernateSearchIndexFullText()) {
theEntity.setNarrativeText(parseNarrativeTextIntoWords(theResource));
theEntity.setContentText(parseContentTextIntoWords(theContext, theResource));
}
if (myStorageSettings.isHibernateSearchIndexSearchParams()) {
ExtendedHSearchIndexData hSearchIndexData =
myFulltextSearchSvc.extractLuceneIndexData(theResource, theNewParams);
theEntity.setLuceneIndexData(hSearchIndexData);

View File

@ -49,6 +49,7 @@ import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.BaseTag;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
@ -1651,7 +1652,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} catch (Exception e) {
ourLog.warn("Failure during reindex: {}", e.toString());
theReindexOutcome.addWarning("Failed to reindex resource " + entity.getIdDt() + ": " + e);
myResourceTableDao.updateIndexStatus(entity.getId(), INDEX_STATUS_INDEXING_FAILED);
myResourceTableDao.updateIndexStatus(entity.getId(), EntityIndexStatusEnum.INDEXING_FAILED);
}
}

View File

@ -51,6 +51,7 @@ import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
@ -264,6 +265,20 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
String theResourceType,
SearchParameterMap theParams,
IResourcePersistentId theReferencingPid) {
if (theParams.containsKey(Constants.PARAM_TEXT) || theParams.containsKey(Constants.PARAM_CONTENT)) {
if (!myStorageSettings.isHibernateSearchIndexFullText()) {
String params = theParams.keySet().stream()
.filter(t -> t.equals(Constants.PARAM_TEXT) || t.equals(Constants.PARAM_CONTENT))
.sorted()
.collect(Collectors.joining(", "));
String msg = myFhirContext
.getLocalizer()
.getMessage(FulltextSearchSvcImpl.class, "fullTextSearchingNotPossible", params);
throw new InvalidRequestException(Msg.code(2566) + msg);
}
}
return f.bool(b -> {
ExtendedHSearchClauseBuilder builder =
new ExtendedHSearchClauseBuilder(myFhirContext, myStorageSettings, b, f);

View File

@ -20,6 +20,7 @@
package ca.uhn.fhir.jpa.dao.data;
import ca.uhn.fhir.jpa.dao.data.custom.IForcedIdQueries;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@ -121,7 +122,7 @@ public interface IResourceTableDao
@Modifying
@Query("UPDATE ResourceTable t SET t.myIndexStatus = :status WHERE t.myId = :id")
void updateIndexStatus(@Param("id") Long theId, @Param("status") Long theIndexStatus);
void updateIndexStatus(@Param("id") Long theId, @Param("status") EntityIndexStatusEnum theIndexStatus);
@Modifying
@Query("UPDATE ResourceTable t SET t.myUpdated = :updated WHERE t.myId = :id")

View File

@ -19,15 +19,16 @@
*/
package ca.uhn.fhir.jpa.entity;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.search.DeferConceptIndexingRoutingBinder;
import ca.uhn.fhir.util.ValidateUtil;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.Nonnull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
@ -52,6 +53,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.Length;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.search.engine.backend.types.Projectable;
import org.hibernate.search.engine.backend.types.Searchable;
import org.hibernate.search.mapper.pojo.bridge.mapping.annotation.PropertyBinderRef;
@ -60,6 +62,7 @@ import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextFi
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.PropertyBinding;
import org.hibernate.type.SqlTypes;
import org.hl7.fhir.r4.model.Coding;
import java.io.Serializable;
@ -168,8 +171,13 @@ public class TermConcept implements Serializable {
@GenericField
private Long myId;
/**
* See {@link EntityIndexStatusEnum} for values
*/
@Column(name = "INDEX_STATUS", nullable = true)
private Long myIndexStatus;
@Enumerated(EnumType.ORDINAL)
@JdbcTypeCode(SqlTypes.TINYINT)
private EntityIndexStatusEnum myIndexStatus;
@Deprecated(since = "7.2.0")
@Lob
@ -360,11 +368,11 @@ public class TermConcept implements Serializable {
return this;
}
public Long getIndexStatus() {
public EntityIndexStatusEnum getIndexStatus() {
return myIndexStatus;
}
public TermConcept setIndexStatus(Long theIndexStatus) {
public TermConcept setIndexStatus(EntityIndexStatusEnum theIndexStatus) {
myIndexStatus = theIndexStatus;
return this;
}
@ -499,24 +507,6 @@ public class TermConcept implements Serializable {
return b.build();
}
public List<IValidationSupport.BaseConceptProperty> toValidationProperties() {
List<IValidationSupport.BaseConceptProperty> retVal = new ArrayList<>();
for (TermConceptProperty next : getProperties()) {
switch (next.getType()) {
case STRING:
retVal.add(new IValidationSupport.StringConceptProperty(next.getKey(), next.getValue()));
break;
case CODING:
retVal.add(new IValidationSupport.CodingConceptProperty(
next.getKey(), next.getCodeSystem(), next.getValue(), next.getDisplay()));
break;
default:
throw new IllegalStateException(Msg.code(830) + "Don't know how to handle " + next.getType());
}
}
return retVal;
}
/**
* Returns a view of {@link #getChildren()} but containing the actual child codes
*/

View File

@ -152,6 +152,19 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
.modifyColumn("20241023.50", "PACKAGE_DESC")
.nullable()
.withType(ColumnTypeEnum.STRING, 512);
// This will require a full table scan just to reduce a field size,
// so don't run it by default
version.onTable("HFJ_RESOURCE")
.modifyColumn("20241030.10", "SP_INDEX_STATUS")
.nullable()
.withType(ColumnTypeEnum.TINYINT)
.heavyweightSkipByDefault();
version.onTable("TRM_CONCEPT")
.modifyColumn("20241030.20", "INDEX_STATUS")
.nullable()
.withType(ColumnTypeEnum.TINYINT)
.heavyweightSkipByDefault();
}
protected void init740() {

View File

@ -24,10 +24,10 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.data.IResourceReindexJobDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.sched.HapiJob;
import ca.uhn.fhir.jpa.model.sched.IHasScheduledJobs;
@ -79,7 +79,6 @@ import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @see ca.uhn.fhir.jpa.reindex.job.ReindexJobConfig
* @deprecated Use the Batch2 {@link ca.uhn.fhir.batch2.api.IJobCoordinator#startInstance(JobInstanceStartRequest)} instead.
*/
@Deprecated
@ -435,7 +434,7 @@ public class ResourceReindexingSvcImpl implements IResourceReindexingSvc, IHasSc
txTemplate.execute((TransactionCallback<Void>) theStatus -> {
ourLog.info("Marking resource with PID {} as indexing_failed", theId);
myResourceTableDao.updateIndexStatus(theId, BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED);
myResourceTableDao.updateIndexStatus(theId, EntityIndexStatusEnum.INDEXING_FAILED);
Query q = myEntityManager.createQuery("DELETE FROM ResourceTag t WHERE t.myResourceId = :id");
q.setParameter("id", theId);

View File

@ -25,7 +25,6 @@ import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
@ -40,6 +39,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
@ -676,7 +676,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
}
theConcept.setCodeSystemVersion(theCodeSystem);
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
theConcept.setIndexStatus(EntityIndexStatusEnum.INDEXED_ALL);
if (theConceptsStack.size() <= myStorageSettings.getDeferIndexingForCodesystemsOfSize()) {
saveConcept(theConcept);

View File

@ -19,7 +19,6 @@
*/
package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao;
@ -27,6 +26,7 @@ import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -70,7 +70,7 @@ public class TermConceptDaoSvc {
if (theConcept.getId() == null || theConcept.getIndexStatus() == null) {
retVal++;
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
theConcept.setIndexStatus(EntityIndexStatusEnum.INDEXED_ALL);
theConcept.setUpdated(new Date());
theConcept.flagForLegacyLobSupport(mySupportLegacyLob);
myConceptDao.save(theConcept);

View File

@ -42,8 +42,6 @@ import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao;
import ca.uhn.fhir.jpa.dao.data.ITermValueSetConceptDao;
import ca.uhn.fhir.jpa.dao.data.ITermValueSetConceptDesignationDao;
import ca.uhn.fhir.jpa.dao.data.ITermValueSetConceptViewDao;
@ -219,12 +217,6 @@ public class TermReadSvcImpl implements ITermReadSvc, IHasScheduledJobs {
@Autowired
protected ITermConceptDao myConceptDao;
@Autowired
protected ITermConceptPropertyDao myConceptPropertyDao;
@Autowired
protected ITermConceptDesignationDao myConceptDesignationDao;
@Autowired
protected ITermValueSetDao myTermValueSetDao;

View File

@ -28,6 +28,7 @@ import ca.uhn.fhir.jpa.search.BaseSourceSearchParameterTestCases;
import ca.uhn.fhir.jpa.search.CompositeSearchParameterTestCases;
import ca.uhn.fhir.jpa.search.QuantitySearchParameterTestCases;
import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchRestClientFactory;
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -61,6 +62,9 @@ import ca.uhn.fhir.validation.ValidationResult;
import ca.uhn.test.util.LogbackTestExtension;
import ca.uhn.test.util.LogbackTestExtensionAssert;
import ch.qos.logback.classic.Level;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.cat.IndicesResponse;
import co.elastic.clients.elasticsearch.cat.count.CountRecord;
import jakarta.annotation.Nonnull;
import jakarta.persistence.EntityManager;
import org.apache.commons.lang3.RandomStringUtils;
@ -97,6 +101,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
import org.mockito.Mock;
import org.mockito.Mockito;
@ -268,18 +273,10 @@ public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest impl
@BeforeEach
public void enableContainsAndLucene() {
myStorageSettings.setAllowContainsSearches(true);
myStorageSettings.setAdvancedHSearchIndexing(true);
myStorageSettings.setHibernateSearchIndexFullText(true);
myStorageSettings.setHibernateSearchIndexSearchParams(true);
}
@AfterEach
public void restoreContains() {
JpaStorageSettings defaultConfig = new JpaStorageSettings();
myStorageSettings.setAllowContainsSearches(defaultConfig.isAllowContainsSearches());
myStorageSettings.setAdvancedHSearchIndexing(defaultConfig.isAdvancedHSearchIndexing());
myStorageSettings.setStoreResourceInHSearchIndex(defaultConfig.isStoreResourceInHSearchIndex());
}
class ElasticPerformanceTracingInterceptor {
private final List<StorageProcessingMessage> messages = new ArrayList<>();
@ -295,6 +292,36 @@ public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest impl
}
@ParameterizedTest
@CsvSource(value = {
"false, false",
"false, true",
"true, false",
"true, true",
})
public void testIndexingEnabledAndDisabled(boolean theHibernateSearchIndexFullText, boolean theHibernateSearchIndexSearchParams) throws IOException {
// Setup
myStorageSettings.setHibernateSearchIndexFullText(theHibernateSearchIndexFullText);
myStorageSettings.setHibernateSearchIndexSearchParams(theHibernateSearchIndexSearchParams);
ElasticsearchClient elasticsearchHighLevelRestClient = ElasticsearchRestClientFactory.createElasticsearchHighLevelRestClient(
"http", myElasticsearchContainer.getHost() + ":" + myElasticsearchContainer.getMappedPort(9200), "", "");
int initialCount = elasticsearchHighLevelRestClient.cat().count().valueBody().stream().mapToInt(next -> Integer.parseInt(next.count())).sum();
// Test
createPatient(withFamily("SIMPSON"));
// Verify
int newCount = elasticsearchHighLevelRestClient.cat().count().valueBody().stream().mapToInt(next -> Integer.parseInt(next.count())).sum();
int added = newCount - initialCount;
if (theHibernateSearchIndexFullText || theHibernateSearchIndexSearchParams) {
assertEquals(1, added);
} else {
assertEquals(0, added);
}
}
@Test
public void testFullTextSearchesArePerformanceLogged() {

View File

@ -0,0 +1,18 @@
package ca.uhn.fhir.jpa.model.entity;
public enum EntityIndexStatusEnum {
/**
* Only indexed in the relational database
*/
INDEXED_RDBMS_ONLY,
/**
* Indexed in relational and fulltext databases
*/
INDEXED_ALL,
/**
* Indexing failed - This should only happen if a resource is being reindexed and the reindexing fails
*/
INDEXING_FAILED;
}

View File

@ -31,6 +31,8 @@ import com.google.common.annotations.VisibleForTesting;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
@ -51,6 +53,7 @@ import org.hibernate.Session;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.GeneratorType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.search.engine.backend.types.Projectable;
import org.hibernate.search.engine.backend.types.Searchable;
@ -64,6 +67,7 @@ import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ObjectPath
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.PropertyBinding;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.PropertyValue;
import org.hibernate.tuple.ValueGenerator;
import org.hibernate.type.SqlTypes;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.InstantType;
@ -139,8 +143,10 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
private Long myId;
@Column(name = "SP_INDEX_STATUS", nullable = true)
@Enumerated(EnumType.ORDINAL)
@JdbcTypeCode(SqlTypes.TINYINT)
@OptimisticLock(excluded = true)
private Long myIndexStatus;
private EntityIndexStatusEnum myIndexStatus;
// TODO: Removed in 5.5.0. Drop in a future release.
@Column(name = "RES_LANGUAGE", length = MAX_LANGUAGE_LENGTH, nullable = true)
@ -464,11 +470,11 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
myId = theId;
}
public Long getIndexStatus() {
public EntityIndexStatusEnum getIndexStatus() {
return myIndexStatus;
}
public void setIndexStatus(Long theIndexStatus) {
public void setIndexStatus(EntityIndexStatusEnum theIndexStatus) {
myIndexStatus = theIndexStatus;
}

View File

@ -19,6 +19,7 @@
*/
package ca.uhn.fhir.jpa.model.search;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.hibernate.search.mapper.pojo.bridge.RoutingBridge;
import org.hibernate.search.mapper.pojo.bridge.binding.RoutingBindingContext;
@ -41,7 +42,8 @@ public class ResourceTableRoutingBinder implements RoutingBinder {
Object theO,
ResourceTable theResourceTable,
RoutingBridgeRouteContext theRoutingBridgeRouteContext) {
if (theResourceTable.getDeleted() == null && theResourceTable.getIndexStatus() != null) {
if (theResourceTable.getDeleted() == null
&& theResourceTable.getIndexStatus() == EntityIndexStatusEnum.INDEXED_ALL) {
theDocumentRoutes.addRoute();
} else {
theDocumentRoutes.notIndexed();

View File

@ -27,8 +27,11 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SearchFtTest.class);
@Override
@BeforeEach
public void beforeDisableResultReuse() {
public void before() throws Exception {
super.before();
myStorageSettings.setHibernateSearchIndexFullText(true);
myStorageSettings.setReuseCachedSearchResultsForMillis(null);
}

View File

@ -10,6 +10,7 @@ import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,6 +23,14 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
@Autowired
private IFulltextSearchSvc mySearchDao;
@Override
@BeforeEach
public void before() throws Exception {
super.before();
myStorageSettings.setHibernateSearchIndexFullText(true);
}
@Test
public void testContentSearch() {
Long id1;

View File

@ -1014,6 +1014,8 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
@Test
public void testEverythingInstanceWithContentFilter() {
myStorageSettings.setHibernateSearchIndexFullText(true);
Patient pt1 = new Patient();
pt1.addName().addFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();

View File

@ -34,8 +34,12 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchFtTest.class);
@Override
@BeforeEach
public void beforeDisableResultReuse() {
public void before() throws Exception {
super.before();
myStorageSettings.setHibernateSearchIndexFullText(true);
myStorageSettings.setReuseCachedSearchResultsForMillis(null);
}

View File

@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Patient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,7 +23,15 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
@Autowired
private IFulltextSearchSvc mySearchDao;
@Override
@BeforeEach
public void before() throws Exception {
super.before();
myStorageSettings.setHibernateSearchIndexFullText(true);
}
@Test
public void testContentSearch() {
Long id1;

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.entity.StorageSettings;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -186,9 +187,9 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
IIdType obsId = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless();
ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, res.getIndexStatus());
res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, res.getIndexStatus());
SearchParameter fooSp = new SearchParameter();
fooSp.addBase("Patient");

View File

@ -1348,6 +1348,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
@Test
public void testEmptySearch() {
myStorageSettings.setHibernateSearchIndexFullText(true);
Bundle responseBundle;
responseBundle = myClient.search().forResource(Patient.class).returnBundle(Bundle.class).execute();
@ -1487,6 +1489,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
@Test
public void testEverythingInstanceWithContentFilter() {
myStorageSettings.setHibernateSearchIndexFullText(true);
Patient pt1 = new Patient();
pt1.addName().setFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
@ -2168,6 +2172,8 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
@SuppressWarnings("unused")
@Test
public void testFullTextSearch() throws Exception {
myStorageSettings.setHibernateSearchIndexFullText(true);
Observation obs1 = new Observation();
obs1.getCode().setText("Systolic Blood Pressure");
obs1.setStatus(ObservationStatus.FINAL);

View File

@ -206,7 +206,7 @@ public class BulkDataErrorAbuseTest extends BaseResourceProviderR4Test {
// we either do this, or shutdown the completion service in an
// "inelegant" manner, dropping all threads (which we aren't doing)
ourLog.error("Failed after checking " + count + " futures");
errors.add(ex.getMessage());
errors.add(ex.toString());
}
}

View File

@ -14,6 +14,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.submit.interceptor.SearchParamValidatingInterceptor;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.HapiExtensions;
import com.helger.commons.lang.StackTraceHelper;
@ -50,8 +51,13 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
protected int myPartitionId3;
protected int myPartitionId4;
private boolean myHaveDroppedForcedIdUniqueConstraint;
@Autowired
private IPartitionLookupSvc myPartitionConfigSvc;
@Autowired
private SearchParamValidatingInterceptor mySearchParamValidatingInterceptor;
private boolean mySearchParamValidatingInterceptorAddded;
@AfterEach
public void after() {
@ -68,6 +74,10 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(new JpaStorageSettings().isAutoCreatePlaceholderReferenceTargets());
myStorageSettings.setMassIngestionMode(new JpaStorageSettings().isMassIngestionMode());
myStorageSettings.setMatchUrlCacheEnabled(new JpaStorageSettings().getMatchUrlCache());
if (mySearchParamValidatingInterceptorAddded) {
myInterceptorRegistry.unregisterInterceptor(mySearchParamValidatingInterceptor);
}
}
protected void assertNoRemainingPartitionIds() {
@ -112,6 +122,10 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
myPartitionConfigSvc.getPartitionById(i);
}
if (myInterceptorRegistry.getAllRegisteredInterceptors().stream().noneMatch(t -> t instanceof SearchParamValidatingInterceptor)) {
myInterceptorRegistry.registerInterceptor(mySearchParamValidatingInterceptor);
mySearchParamValidatingInterceptorAddded = true;
}
}
protected void registerPartitionInterceptor() {

View File

@ -1,13 +1,13 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.batch2.api.IJobCoordinator;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexAppCtx;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters;
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
import ca.uhn.fhir.context.ComboSearchParamType;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboStringUnique;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -58,8 +58,6 @@ import java.util.UUID;
import java.util.stream.Collectors;
import static ca.uhn.fhir.batch2.jobs.reindex.ReindexUtils.JOB_REINDEX;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.INDEX_STATUS_INDEXED;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -427,7 +425,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testHashesCalculated() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueIndexPatientIdentifier();
Patient pt = new Patient();
@ -585,7 +583,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
}
private Pair<String, String> prepareDoubleMatchingSearchParameterAndPatient() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueIndexPatientIdentifier();
Patient pt = new Patient();
@ -1026,9 +1024,8 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
// 1 patient, 1 coverage, 3 search parameters
assertEquals(5, resources.size(), resourceIds);
for (int i = 0; i < resources.size(); i++) {
int indexStatus = resources.get(i).getIndexStatus().intValue();
assertEquals(INDEX_STATUS_INDEXED, indexStatus, "Expected resource " + i + " to have index status INDEXED but was " +
(indexStatus == INDEX_STATUS_INDEXING_FAILED ? "FAILED" : "UNKNOWN(" + indexStatus + ")"));
EntityIndexStatusEnum indexStatus = resources.get(i).getIndexStatus();
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, indexStatus, "Expected resource " + i + " to have index status INDEXED but was " + indexStatus.name());
}
});
@ -1225,7 +1222,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testOrQuery() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueGenderFamilyComboSp();
Patient pt1 = new Patient();
@ -1264,7 +1261,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testSearchSynchronousUsingUniqueComposite() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueGenderFamilyComboSp();
Patient pt1 = new Patient();
@ -1410,7 +1407,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testUniqueValuesAreIndexed_Reference_UsingModifierSyntax() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueNameAndManagingOrganizationSps();
Organization org = new Organization();
@ -1829,7 +1826,7 @@ public class FhirResourceDaoR4ComboUniqueParamTest extends BaseComboParamsR4Test
@Test
public void testReplaceOneWithAnother() {
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
createUniqueGenderFamilyComboSp();
Patient pt1 = new Patient();

View File

@ -40,11 +40,15 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchFtTest.class);
@Override
@BeforeEach
public void beforeDisableResultReuse() {
public void before() throws Exception {
super.before();
myStorageSettings.setReuseCachedSearchResultsForMillis(null);
myStorageSettings.setAllowContainsSearches(true);
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexFullText(true);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
}
/**

View File

@ -13,6 +13,7 @@ import ca.uhn.fhir.jpa.dao.JpaResourceDao;
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
@ -290,7 +291,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(myResourceIndexedSearchParamTokenDao.countForResourceId(id1.getIdPartAsLong())).isGreaterThan(0);
Optional<ResourceTable> tableOpt = myResourceTableDao.findById(id1.getIdPartAsLong());
assertTrue(tableOpt.isPresent());
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, tableOpt.get().getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, tableOpt.get().getIndexStatus());
});
runInTransaction(() -> {
@ -313,7 +314,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
runInTransaction(() -> {
Optional<ResourceTable> tableOpt = myResourceTableDao.findById(id1.getIdPartAsLong());
assertTrue(tableOpt.isPresent());
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, tableOpt.get().getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, tableOpt.get().getIndexStatus());
assertThat(myResourceIndexedSearchParamTokenDao.countForResourceId(id1.getIdPartAsLong())).isLessThanOrEqualTo(0);
});
}
@ -400,7 +401,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(myResourceIndexedSearchParamTokenDao.countForResourceId(id1.getIdPartAsLong())).isGreaterThan(0);
Optional<ResourceTable> tableOpt = myResourceTableDao.findById(id1.getIdPartAsLong());
assertTrue(tableOpt.isPresent());
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, tableOpt.get().getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, tableOpt.get().getIndexStatus());
});
/*
@ -423,7 +424,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
runInTransaction(() -> {
Optional<ResourceTable> tableOpt = myResourceTableDao.findById(id1.getIdPartAsLong());
assertTrue(tableOpt.isPresent());
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, tableOpt.get().getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, tableOpt.get().getIndexStatus());
assertThat(myResourceIndexedSearchParamTokenDao.countForResourceId(id1.getIdPartAsLong())).isLessThanOrEqualTo(0);
});
@ -3698,7 +3699,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
@Test
public void testSortByString01() {
myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.ENABLED);
myStorageSettings.setAdvancedHSearchIndexing(false);
myStorageSettings.setHibernateSearchIndexSearchParams(false);
Patient p = new Patient();
String string = "testSortByString01";

View File

@ -45,12 +45,15 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test implements IR4SearchIndex
@Autowired
private DataSource myDataSource;
@Override
@BeforeEach
public void before() throws Exception {
super.before();
SearchBuilder.setMaxPageSizeForTest(10);
myStorageSettings.setHibernateSearchIndexFullText(true);
}
@AfterEach
public void after() {
SearchBuilder.setMaxPageSizeForTest(null);

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
@ -576,13 +577,13 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
sleepUntilTimeChange();
ResourceTable entity = new TransactionTemplate(myTxManager).execute(t -> myEntityManager.find(ResourceTable.class, id.getIdPartAsLong()));
assertEquals(Long.valueOf(1), entity.getIndexStatus());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, entity.getIndexStatus());
Long jobId = myResourceReindexingSvc.markAllResourcesForReindexing();
myResourceReindexingSvc.forceReindexingPass();
entity = new TransactionTemplate(myTxManager).execute(t -> myEntityManager.find(ResourceTable.class, id.getIdPartAsLong()));
assertEquals(Long.valueOf(1), entity.getIndexStatus());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, entity.getIndexStatus());
// Just make sure this doesn't cause a choke
myResourceReindexingSvc.forceReindexingPass();
@ -619,7 +620,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
myResourceReindexingSvc.forceReindexingPass();
entity = new TransactionTemplate(myTxManager).execute(theStatus -> myEntityManager.find(ResourceTable.class, id.getIdPartAsLong()));
assertEquals(Long.valueOf(2), entity.getIndexStatus());
assertEquals(EntityIndexStatusEnum.INDEXING_FAILED, entity.getIndexStatus());
}

View File

@ -16,6 +16,7 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTag;
@ -29,6 +30,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTag;
import ca.uhn.fhir.jpa.model.entity.SearchParamPresentEntity;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.submit.interceptor.SearchParamValidatingInterceptor;
import ca.uhn.fhir.jpa.util.SqlQuery;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@ -3334,8 +3336,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
myResourceReindexingSvc.forceReindexingPass();
runInTransaction(() -> {
assertNotEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED, myResourceTableDao.findById(patientIdNull.getIdPartAsLong()).get().getIndexStatus());
assertNotEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED, myResourceTableDao.findById(patientId1.getIdPartAsLong()).get().getIndexStatus());
assertNotEquals(EntityIndexStatusEnum.INDEXING_FAILED, myResourceTableDao.findById(patientIdNull.getIdPartAsLong()).get().getIndexStatus());
assertNotEquals(EntityIndexStatusEnum.INDEXING_FAILED, myResourceTableDao.findById(patientId1.getIdPartAsLong()).get().getIndexStatus());
});
}

View File

@ -16,6 +16,7 @@ import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -29,6 +30,14 @@ public class DeleteExpungeJobTest extends BaseJpaR4Test {
@Autowired
private Batch2JobHelper myBatch2JobHelper;
@Override
@BeforeEach
public void before() throws Exception {
super.before();
myStorageSettings.setHibernateSearchIndexFullText(true);
}
@Test
public void testDeleteExpunge() {
// setup

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
@ -224,9 +225,9 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
runInTransaction(() -> {
ResourceTable res = myResourceTableDao.findById(patId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, res.getIndexStatus());
res = myResourceTableDao.findById(obsId.getIdPartAsLong()).orElseThrow(IllegalStateException::new);
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, res.getIndexStatus());
});
SearchParameter fooSp = new SearchParameter();

View File

@ -200,6 +200,8 @@ public class ResourceProviderR4EverythingTest extends BaseResourceProviderR4Test
@Test
public void testEverythingInstanceWithContentFilter() {
myStorageSettings.setHibernateSearchIndexFullText(true);
Patient pt1 = new Patient();
pt1.addName().setFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
@ -977,6 +979,8 @@ public class ResourceProviderR4EverythingTest extends BaseResourceProviderR4Test
@Test
public void testFulltextEverythingWithIdAndContent() throws IOException {
myStorageSettings.setHibernateSearchIndexFullText(true);
Patient p = new Patient();
p.setId("FOO");
p.addName().setFamily("FAMILY");

View File

@ -2043,6 +2043,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
@Test
public void testEmptySearch() {
myStorageSettings.setHibernateSearchIndexFullText(true);
Bundle responseBundle;
responseBundle = myClient.search().forResource(Patient.class).returnBundle(Bundle.class).execute();
@ -2145,6 +2147,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
@SuppressWarnings("unused")
@Test
public void testFullTextSearch() throws Exception {
myStorageSettings.setHibernateSearchIndexFullText(true);
IParser parser = myFhirContext.newJsonParser();
Observation obs1 = new Observation();
@ -2178,6 +2182,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
@Test
public void testFulltextSearchWithIdAndContent() throws IOException {
myStorageSettings.setHibernateSearchIndexFullText(true);
Patient p = new Patient();
p.setId("FOO");
p.addName().setFamily("FAMILY");
@ -2201,6 +2207,43 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
assertThat(ids).isEmpty();
}
@ParameterizedTest
@ValueSource(strings = {
"/Patient?_text=HELLO",
"/Patient?_content=HELLO",
"/Patient?_content=HELLO&_text=HELLO",
"/Patient?_id=FOO&_content=HELLO",
"/Patient/A/$everything?_content=HELLO"
})
public void testFullTextIndexingDisabled(String theUri) throws IOException {
// Setup
myStorageSettings.setHibernateSearchIndexFullText(false);
createPatient(withId("A"), withActiveTrue());
// Test
HttpGet get = new HttpGet(myServerBase + theUri);
try (CloseableHttpResponse response = ourHttpClient.execute(get)) {
// Verify
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
assertEquals(400, response.getStatusLine().getStatusCode(), resp);
String expectedParams = null;
if (theUri.contains("_content")) {
expectedParams = "_content";
}
if (theUri.contains("_text")) {
if (expectedParams != null) {
expectedParams += ", _text";
} else {
expectedParams = "_text";
}
}
assertThat(resp).contains("Fulltext searching is not enabled on this server, can not support the parameter(s): " + expectedParams);
}
}
@Test
public void testGetResourceCountsOperation() throws Exception {
String methodName = "testMetaOperations";
@ -2720,8 +2763,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
/**
* See issue #52
*/
* See issue #52
*/
@Test
public void testImagingStudyResources() throws Exception {
IGenericClient client = myClient;
@ -2951,8 +2994,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
/**
* See #793
*/
* See #793
*/
@Test
public void testIncludeCountDoesntIncludeIncludes() {
Organization org = new Organization();

View File

@ -10,6 +10,7 @@ import ca.uhn.fhir.batch2.jobs.reindex.v1.ReindexStepV1;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.WorkChunk;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import org.hl7.fhir.instance.model.api.IIdType;
@ -24,14 +25,13 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.INDEX_STATUS_INDEXED;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@SuppressWarnings("removal")
public class ReindexStepV1Test extends BaseJpaR4Test {
@Autowired
@ -289,10 +289,10 @@ public class ReindexStepV1Test extends BaseJpaR4Test {
runInTransaction(() -> {
ResourceTable table = myResourceTableDao.findById(idPatientToInvalidate).orElseThrow();
assertEquals(INDEX_STATUS_INDEXING_FAILED, table.getIndexStatus());
assertEquals(EntityIndexStatusEnum.INDEXING_FAILED, table.getIndexStatus());
table = myResourceTableDao.findById(id0).orElseThrow();
assertEquals(INDEX_STATUS_INDEXED, table.getIndexStatus());
assertEquals(EntityIndexStatusEnum.INDEXED_RDBMS_ONLY, table.getIndexStatus());
});
}

View File

@ -10,6 +10,7 @@ import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.dao.data.IResourceReindexJobDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity;
import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.apache.commons.lang3.time.DateUtils;
@ -280,7 +281,7 @@ public class ResourceReindexingSvcImplTest {
// verify
assertEquals(0, count);
verify(myResourceTableDao, times(1)).updateIndexStatus(eq(0L), eq(BaseHapiFhirDao.INDEX_STATUS_INDEXING_FAILED));
verify(myResourceTableDao, times(1)).updateIndexStatus(eq(0L), eq(EntityIndexStatusEnum.INDEXING_FAILED));
}
@Test

View File

@ -62,6 +62,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboStringUnique;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
@ -211,6 +212,8 @@ public abstract class BaseJpaTest extends BaseTest {
@Autowired
protected ISearchResultCacheSvc mySearchResultCacheSvc;
@Autowired
protected PartitionSettings myPartitionSettings;
@Autowired
protected ITermCodeSystemDao myTermCodeSystemDao;
@Autowired
protected ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
@ -389,12 +392,19 @@ public abstract class BaseJpaTest extends BaseTest {
if (myFhirInstanceValidator != null) {
myFhirInstanceValidator.invalidateCaches();
}
JpaStorageSettings defaultConfig = new JpaStorageSettings();
myStorageSettings.setAdvancedHSearchIndexing(defaultConfig.isAdvancedHSearchIndexing());
myStorageSettings.setAllowContainsSearches(defaultConfig.isAllowContainsSearches());
myStorageSettings.setIncludeHashIdentityForTokenSearches(defaultConfig.isIncludeHashIdentityForTokenSearches());
myStorageSettings.setMaximumIncludesToLoadPerPage(defaultConfig.getMaximumIncludesToLoadPerPage());
JpaStorageSettings defaultStorageConfig = new JpaStorageSettings();
myStorageSettings.setAllowContainsSearches(defaultStorageConfig.isAllowContainsSearches());
myStorageSettings.setHibernateSearchIndexFullText(defaultStorageConfig.isHibernateSearchIndexFullText());
myStorageSettings.setHibernateSearchIndexSearchParams(defaultStorageConfig.isHibernateSearchIndexSearchParams());
myStorageSettings.setIncludeHashIdentityForTokenSearches(defaultStorageConfig.isIncludeHashIdentityForTokenSearches());
myStorageSettings.setMarkResourcesForReindexingUponSearchParameterChange(defaultStorageConfig.isMarkResourcesForReindexingUponSearchParameterChange());
myStorageSettings.setMaximumIncludesToLoadPerPage(defaultStorageConfig.getMaximumIncludesToLoadPerPage());
myStorageSettings.setPreExpandValueSets(defaultStorageConfig.isPreExpandValueSets());
myStorageSettings.setStoreResourceInHSearchIndex(defaultStorageConfig.isStoreResourceInHSearchIndex());
PartitionSettings defaultPartConfig = new PartitionSettings();
myPartitionSettings.setIncludePartitionInSearchHashes(defaultPartConfig.isIncludePartitionInSearchHashes());
}
@AfterEach

View File

@ -0,0 +1,23 @@
package ca.uhn.fhirtest.config;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public abstract class BaseConfig {
protected void configureLuceneProperties(Properties extraProperties, String fhirLuceneLocation) {
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), fhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
}
}

View File

@ -4,6 +4,9 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
public class CommonJpaStorageSettingsConfigurer {
public CommonJpaStorageSettingsConfigurer(JpaStorageSettings theStorageSettings) {
theStorageSettings.setHibernateSearchIndexFullText(false);
theStorageSettings.setHibernateSearchIndexSearchParams(false);
theStorageSettings.setIndexOnUpliftedRefchains(true);
theStorageSettings.setMarkResourcesForReindexingUponSearchParameterChange(false);
theStorageSettings.setLanguageSearchParameterEnabled(true);

View File

@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.config.HapiJpaConfig;
import ca.uhn.fhir.jpa.config.r4.JpaR4Config;
import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil;
import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
@ -69,6 +70,12 @@ public class TestAuditConfig {
return retVal;
}
@Bean
public SubscriptionSettings subscriptionSettings() {
SubscriptionSettings retVal = new SubscriptionSettings();
return retVal;
}
@Bean(name = "myPersistenceDataSourceR4")
public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource();

View File

@ -7,8 +7,7 @@ import ca.uhn.fhir.jpa.config.JpaDstu2Config;
import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil;
import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
@ -18,9 +17,6 @@ import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import jakarta.persistence.EntityManagerFactory;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -41,13 +37,13 @@ import javax.sql.DataSource;
@Configuration
@Import({CommonConfig.class, JpaDstu2Config.class, HapiJpaConfig.class})
@EnableTransactionManagement()
public class TestDstu2Config {
public class TestDstu2Config extends BaseConfig {
public static final String FHIR_LUCENE_LOCATION_DSTU2 = "fhir.lucene.location.dstu2";
private String myDbUsername = System.getProperty(TestR5Config.FHIR_DB_USERNAME);
private String myDbPassword = System.getProperty(TestR5Config.FHIR_DB_PASSWORD);
private String myFhirLuceneLocation = System.getProperty(FHIR_LUCENE_LOCATION_DSTU2);
private final String myDbUsername = System.getProperty(TestR5Config.FHIR_DB_USERNAME);
private final String myDbPassword = System.getProperty(TestR5Config.FHIR_DB_PASSWORD);
private final String myFhirLuceneLocation = System.getProperty(FHIR_LUCENE_LOCATION_DSTU2);
@Bean
public PublicSecurityInterceptor securityInterceptor() {
@ -106,14 +102,12 @@ public class TestDstu2Config {
retVal.setPassword(myDbPassword);
TestR5Config.applyCommonDatasourceParams(retVal);
DataSource dataSource = ProxyDataSourceBuilder.create(retVal)
return ProxyDataSourceBuilder.create(retVal)
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
.logSlowQueryBySlf4j(10000, TimeUnit.MILLISECONDS)
.afterQuery(new CurrentThreadCaptureQueriesListener())
.countQuery()
.build();
return dataSource;
}
@Primary
@ -142,7 +136,7 @@ public class TestDstu2Config {
if (CommonConfig.isLocalTestMode()) {
extraProperties.put("hibernate.dialect", HapiFhirH2Dialect.class.getName());
} else {
extraProperties.put("hibernate.dialect", HapiFhirPostgres94Dialect.class.getName());
extraProperties.put("hibernate.dialect", HapiFhirPostgresDialect.class.getName());
}
extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false");
@ -153,21 +147,13 @@ public class TestDstu2Config {
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), myFhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
configureLuceneProperties(extraProperties, myFhirLuceneLocation);
return extraProperties;
}
/**
* Bean which validates incoming requests
*
* @param theInstanceValidator
*/
@Bean
@Lazy

View File

@ -9,7 +9,6 @@ import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
@ -19,9 +18,6 @@ import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import jakarta.persistence.EntityManagerFactory;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -42,7 +38,7 @@ import javax.sql.DataSource;
@Configuration
@Import({CommonConfig.class, JpaDstu3Config.class, HapiJpaConfig.class})
@EnableTransactionManagement()
public class TestDstu3Config {
public class TestDstu3Config extends BaseConfig {
public static final String FHIR_LUCENE_LOCATION_DSTU3 = "fhir.lucene.location.dstu3";
private String myDbUsername = System.getProperty(TestR5Config.FHIR_DB_USERNAME);
@ -154,13 +150,7 @@ public class TestDstu3Config {
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), myFhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
configureLuceneProperties(extraProperties, myFhirLuceneLocation);
return extraProperties;
}

View File

@ -5,10 +5,10 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.config.HapiJpaConfig;
import ca.uhn.fhir.jpa.config.r4b.JpaR4BConfig;
import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil;
import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
@ -18,9 +18,7 @@ import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import jakarta.persistence.EntityManagerFactory;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,7 +40,7 @@ import javax.sql.DataSource;
@Configuration
@Import({CommonConfig.class, JpaR4BConfig.class, HapiJpaConfig.class})
@EnableTransactionManagement()
public class TestR4BConfig {
public class TestR4BConfig extends BaseConfig {
public static final String FHIR_DB_USERNAME = "fhir.db.username";
public static final String FHIR_DB_PASSWORD = "fhir.db.password";
public static final String FHIR_LUCENE_LOCATION_R4B = "fhir.lucene.location.r4b";
@ -116,6 +114,16 @@ public class TestR4BConfig {
return retVal;
}
@Bean
public SubscriptionSettings subscriptionSettings() {
SubscriptionSettings retVal = new SubscriptionSettings();
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.WEBSOCKET);
retVal.setWebsocketContextPath("/websocketR4B");
return retVal;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
ConfigurableListableBeanFactory theConfigurableListableBeanFactory,
@ -145,13 +153,7 @@ public class TestR4BConfig {
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), myFhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
configureLuceneProperties(extraProperties, myFhirLuceneLocation);
return extraProperties;
}

View File

@ -14,7 +14,6 @@ import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
@ -24,9 +23,6 @@ import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import jakarta.persistence.EntityManagerFactory;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -47,7 +43,7 @@ import javax.sql.DataSource;
@Configuration
@Import({CommonConfig.class, JpaR4Config.class, HapiJpaConfig.class})
@EnableTransactionManagement()
public class TestR4Config {
public class TestR4Config extends BaseConfig {
public static final String FHIR_LUCENE_LOCATION_R4 = "fhir.lucene.location.r4";
public static final Integer COUNT_SEARCH_RESULTS_UP_TO = 50000;
@ -154,13 +150,8 @@ public class TestR4Config {
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), myFhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
configureLuceneProperties(extraProperties, myFhirLuceneLocation);
return extraProperties;
}

View File

@ -9,7 +9,6 @@ import ca.uhn.fhir.jpa.model.config.SubscriptionSettings;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect;
import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
@ -19,9 +18,6 @@ import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import jakarta.persistence.EntityManagerFactory;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.slf4j.Logger;
@ -44,7 +40,7 @@ import javax.sql.DataSource;
@Configuration
@Import({CommonConfig.class, JpaR5Config.class, HapiJpaConfig.class})
@EnableTransactionManagement()
public class TestR5Config {
public class TestR5Config extends BaseConfig {
public static final String FHIR_DB_USERNAME = "fhir.db.username";
public static final String FHIR_DB_PASSWORD = "fhir.db.password";
public static final String FHIR_LUCENE_LOCATION_R5 = "fhir.lucene.location.r5";
@ -164,13 +160,7 @@ public class TestR5Config {
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put(BackendSettings.backendKey(BackendSettings.TYPE), "lucene");
extraProperties.put(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), "local-filesystem");
extraProperties.put(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), myFhirLuceneLocation);
extraProperties.put(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), "LUCENE_CURRENT");
configureLuceneProperties(extraProperties, myFhirLuceneLocation);
return extraProperties;
}

View File

@ -92,7 +92,7 @@ public class ReindexV1Config {
"Load IDs of resources to reindex",
ResourceIdListWorkChunkJson.class,
myReindexLoadIdsStep)
.addLastStep("reindex-start", "Start the resource reindex", reindexStepV1())
.addLastStep("reindex", "Start the resource reindex", reindexStepV1())
.build();
}

View File

@ -272,7 +272,15 @@ public class JpaStorageSettings extends StorageSettings {
*
* @since 5.6.0
*/
private boolean myAdvancedHSearchIndexing = false;
private boolean myHibernateSearchIndexSearchParams = false;
/**
* Activates hibernate search indexing of fulltext data from resources, which
* is used to support the {@literal _text} and {@literal _content} Search Parameters.
*
* @since 8.0.0
*/
private boolean myHibernateSearchIndexFullText = false;
/**
* @since 5.7.0
@ -2147,13 +2155,33 @@ public class JpaStorageSettings extends StorageSettings {
myHSearchIndexPrefix = thePrefix;
}
/**
* @deprecated Use {@link #isHibernateSearchIndexSearchParams()} instead
*/
@Deprecated(since = "8.0.0", forRemoval = true)
public boolean isAdvancedHSearchIndexing() {
return isHibernateSearchIndexSearchParams();
}
/**
* @deprecated Use {@link #setHibernateSearchIndexSearchParams(boolean)} instead
*/
@Deprecated(since = "8.0.0", forRemoval = true)
public void setAdvancedHSearchIndexing(boolean theAdvancedHSearchIndexing) {
setHibernateSearchIndexSearchParams(theAdvancedHSearchIndexing);
}
/**
* Is HSearch indexing enabled beyond _contains or _text?
*
* <p>
* Note that this property was called "setAdvancedHSearchIndexing" prior to HAPI FHIR 8.0.0
* </p>
*
* @since 5.6.0
*/
public boolean isAdvancedHSearchIndexing() {
return myAdvancedHSearchIndexing;
public boolean isHibernateSearchIndexSearchParams() {
return myHibernateSearchIndexSearchParams;
}
/**
@ -2162,11 +2190,35 @@ public class JpaStorageSettings extends StorageSettings {
* String, token, and reference parameters can be indexed in HSearch.
* This extends token search to support :text searches, as well as supporting
* :contains and :text on string parameters.
* </p>
* <p>
* Note that this property was called "setAdvancedHSearchIndexing" prior to HAPI FHIR 8.0.0
* </p>
*
* @since 5.6.0
*/
public void setAdvancedHSearchIndexing(boolean theAdvancedHSearchIndexing) {
this.myAdvancedHSearchIndexing = theAdvancedHSearchIndexing;
public void setHibernateSearchIndexSearchParams(boolean theAdvancedHSearchIndexing) {
this.myHibernateSearchIndexSearchParams = theAdvancedHSearchIndexing;
}
/**
* Activates hibernate search indexing of fulltext data from resources, which
* is used to support the {@literal _text} and {@literal _content} Search Parameters.
*
* @since 8.0.0
*/
public boolean isHibernateSearchIndexFullText() {
return myHibernateSearchIndexFullText;
}
/**
* Activates hibernate search indexing of fulltext data from resources, which
* is used to support the {@literal _text} and {@literal _content} Search Parameters.
*
* @since 8.0.0
*/
public void setHibernateSearchIndexFullText(boolean theHibernateSearchIndexFullText) {
myHibernateSearchIndexFullText = theHibernateSearchIndexFullText;
}
/**

View File

@ -1241,7 +1241,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<version>2.3.232</version>
</dependency>
<dependency>
<groupId>com.helger.commons</groupId>
@ -2023,7 +2023,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.3</version>
<version>42.7.4</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>