Skip to content
7 changes: 5 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -293,16 +293,19 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>elasticsearch</artifactId>
<artifactId>testcontainers-elasticsearch</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import ca.uhn.fhir.jpa.starter.annotations.OnCorsPresent;
import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent;
import ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory;
import ca.uhn.fhir.jpa.starter.elastic.ElasticsearchBootSvcImpl;
import ca.uhn.fhir.jpa.starter.ig.ExtendedPackageInstallationSpec;
import ca.uhn.fhir.jpa.starter.ig.IImplementationGuideOperationProvider;
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
Expand Down Expand Up @@ -149,6 +150,7 @@ public ResourceCountCache resourceCountsCache(IFhirSystemDao<?, ?> theSystemDao)
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
Optional<ElasticsearchBootSvcImpl> elasticsearchSvc,
JpaProperties theJpaProperties,
DataSource myDataSource,
ConfigurableListableBeanFactory myConfigurableListableBeanFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ public class ElasticsearchBootSvcImpl implements IElasticsearchSvc {

private static final String OBSERVATION_RESOURCE_NAME = "Observation";

private final ElasticsearchClient myRestHighLevelClient;
private final ElasticsearchClient elasticsearchClient;

private final FhirContext myContext;

public ElasticsearchBootSvcImpl(ElasticsearchClient client, FhirContext fhirContext) {

myContext = fhirContext;
myRestHighLevelClient = client;
elasticsearchClient = client;

try {
createObservationIndexIfMissing();
Expand Down Expand Up @@ -100,15 +100,15 @@ private void createObservationCodeIndexIfMissing() throws IOException {
}

private boolean createIndex(String theIndexName, String theMapping) throws IOException {
return myRestHighLevelClient
return elasticsearchClient
.indices()
.create(cir -> cir.index(theIndexName).withJson(new StringReader(theMapping)))
.acknowledged();
}

private boolean indexExists(String theIndexName) throws IOException {
ExistsRequest request = new ExistsRequest.Builder().index(theIndexName).build();
return myRestHighLevelClient.indices().exists(request).value();
return elasticsearchClient.indices().exists(request).value();
}

@Override
Expand All @@ -121,7 +121,7 @@ public List<IBaseResource> getObservationResources(Collection<? extends IResourc
SearchRequest searchRequest = buildObservationResourceSearchRequest(thePids);
try {
SearchResponse<ObservationJson> observationDocumentResponse =
myRestHighLevelClient.search(searchRequest, ObservationJson.class);
elasticsearchClient.search(searchRequest, ObservationJson.class);
List<Hit<ObservationJson>> observationDocumentHits =
observationDocumentResponse.hits().hits();
IParser parser = TolerantJsonParser.createWithLenientErrorHandling(myContext, null);
Expand Down Expand Up @@ -158,6 +158,6 @@ private SearchRequest buildObservationResourceSearchRequest(Collection<? extends

@VisibleForTesting
public void refreshIndex(String theIndexName) throws IOException {
myRestHighLevelClient.indices().refresh(fn -> fn.index(theIndexName));
elasticsearchClient.indices().refresh(fn -> fn.index(theIndexName));
}
}
50 changes: 50 additions & 0 deletions src/main/resources/application-elastic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
spring:
elasticsearch:
uris: http://localhost:9200
username: elastic
password: elastic

autoconfigure:
# This empty exclude is needed to override the default exclusion of the Elasticsearch configuration.
exclude:

jpa:
properties:
hibernate:
# --- Hibernate Search (Lucene/Elasticsearch) ---
# Note: the following values should be kept in sync with ca.uhn.fhir.jpa.search.elastic.ElasticsearchHibernatePropertiesBuilder
search:
schema_management:
strategy: CREATE
enabled: true
backend:
layout:
strategy: ca.uhn.fhir.jpa.search.elastic.IndexNamePrefixLayoutStrategy
type: elasticsearch
protocol: http
analysis:
configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiElasticsearchAnalysisConfigurer
scroll_timeout: 60
schema_management:
settings_file: ca/uhn/fhir/jpa/elastic/index-settings.json
minimal_required_status_wait_timeout: 10000
minimal_required_status: YELLOW

dynamic_mapping: true
indexing:
plan:
synchronization:
strategy: async

# -------------------------------------------------------------------------------------
# HAPI FHIR — grouped by domain
# -------------------------------------------------------------------------------------
hapi:
fhir:
# -------------------------------------------------------------------------------
# D. Search & Indexing
# -------------------------------------------------------------------------------
# NOTE: Extended Lucene/Elasticsearch indexing is experimental.
# See https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html
advanced_lucene_indexing: true
search_index_full_text_enabled: true
37 changes: 29 additions & 8 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ management:
enabled: true

spring:
# elasticsearch:
# uris: http://localhost:9200
# username: elastic
# password: elastic
# -------------------------------------------------------------------------------
# A. Spring AI — Model Context Protocol (MCP)
# -------------------------------------------------------------------------------
Expand Down Expand Up @@ -123,8 +127,10 @@ spring:
use_minimal_puts: false

# --- Hibernate Search (Lucene/Elasticsearch) ---
search:
enabled: false
#search:
# schema_management:
# strategy: CREATE
# enabled: true
# Lucene backend (default example)
# backend:
# type: lucene
Expand All @@ -135,10 +141,25 @@ spring:
# root: target/lucenefiles
# lucene_version: lucene_current
# Elasticsearch backend (alternative) — see also hapi.fhir.elasticsearch section in docs
# backend:
# type: elasticsearch
# analysis:
# configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiElasticAnalysisConfigurer
# backend:
# layout:
# strategy: ca.uhn.fhir.jpa.search.elastic.IndexNamePrefixLayoutStrategy
# type: elasticsearch
# protocol: http
# analysis:
# configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiElasticsearchAnalysisConfigurer
# scroll_timeout: 60
# schema_management:
# settings_file: ca/uhn/fhir/jpa/elastic/index-settings.json
# minimal_required_status_wait_timeout: 10000
# minimal_required_status: YELLOW
#
# dynamic_mapping: true
# indexing:
# plan:
# synchronization:
# strategy: async


# -------------------------------------------------------------------------------------
# HAPI FHIR — grouped by domain
Expand Down Expand Up @@ -242,8 +263,8 @@ hapi:
# -------------------------------------------------------------------------------
# NOTE: Extended Lucene/Elasticsearch indexing is experimental.
# See https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html
advanced_lucene_indexing: false
search_index_full_text_enabled: false
# advanced_lucene_indexing: true
# search_index_full_text_enabled: true
# language_search_parameter_enabled: true
# upliftedRefchains_enabled: true
# index_storage_optimized: false
Expand Down
Loading
Loading