Merge pull request #919 from hapifhir/fix-FilesystemBinaryStorage-interceptor

Fix filesystem binary storage interceptor
This commit is contained in:
Patrick Werner
2026-02-16 12:48:30 +01:00
committed by GitHub
7 changed files with 51 additions and 18 deletions

View File

@@ -69,7 +69,7 @@ public class AppProperties {
private BinaryStorageMode binary_storage_mode = BinaryStorageMode.DATABASE; private BinaryStorageMode binary_storage_mode = BinaryStorageMode.DATABASE;
private String binary_storage_filesystem_base_directory; private String binary_storage_filesystem_base_directory;
private Integer inline_resource_storage_below_size; private Integer binary_storage_minimum_binary_size;
private Boolean bulk_export_enabled = false; private Boolean bulk_export_enabled = false;
private Boolean bulk_import_enabled = false; private Boolean bulk_import_enabled = false;
private Boolean default_pretty_print = true; private Boolean default_pretty_print = true;
@@ -513,12 +513,12 @@ public class AppProperties {
this.binary_storage_filesystem_base_directory = binary_storage_filesystem_base_directory; this.binary_storage_filesystem_base_directory = binary_storage_filesystem_base_directory;
} }
public Integer getInline_resource_storage_below_size() { public Integer getBinary_storage_minimum_binary_size() {
return inline_resource_storage_below_size; return binary_storage_minimum_binary_size;
} }
public void setInline_resource_storage_below_size(Integer inline_resource_storage_below_size) { public void setBinary_storage_minimum_binary_size(Integer binary_storage_minimum_binary_size) {
this.inline_resource_storage_below_size = inline_resource_storage_below_size; this.binary_storage_minimum_binary_size = binary_storage_minimum_binary_size;
} }
public Boolean getBulk_export_enabled() { public Boolean getBulk_export_enabled() {

View File

@@ -0,0 +1,41 @@
package ca.uhn.fhir.jpa.starter.common;
import ca.uhn.fhir.IHapiBootOrder;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.starter.AppProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
public class BinaryStorageInterceptorRegistrar {
private static final Logger ourLog = LoggerFactory.getLogger(BinaryStorageInterceptorRegistrar.class);
private final IInterceptorService myInterceptorService;
private final BinaryStorageInterceptor<?> myBinaryStorageInterceptor;
private final AppProperties myAppProperties;
public BinaryStorageInterceptorRegistrar(
IInterceptorService theInterceptorService,
BinaryStorageInterceptor<?> theBinaryStorageInterceptor,
AppProperties theAppProperties) {
myInterceptorService = theInterceptorService;
myBinaryStorageInterceptor = theBinaryStorageInterceptor;
myAppProperties = theAppProperties;
}
@EventListener(classes = {ContextRefreshedEvent.class})
@Order(IHapiBootOrder.REGISTER_INTERCEPTORS)
public void register() {
if (!myAppProperties.getBinary_storage_enabled()) {
ourLog.debug("Binary storage disabled; skipping BinaryStorageInterceptor registration");
return;
}
ourLog.info("Registering BinaryStorageInterceptor with JPA interceptor service");
myInterceptorService.registerInterceptor(myBinaryStorageInterceptor);
}
}

View File

@@ -227,11 +227,6 @@ public class FhirServerConfigCommon {
jpaStorageSettings.setLastNEnabled(true); jpaStorageSettings.setLastNEnabled(true);
} }
Integer inlineResourceThreshold = resolveInlineResourceThreshold(appProperties);
if (inlineResourceThreshold != null && inlineResourceThreshold != 0) {
jpaStorageSettings.setInlineResourceTextBelowSize(inlineResourceThreshold);
}
jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled());
jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level());
jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource());
@@ -403,7 +398,7 @@ public class FhirServerConfigCommon {
} }
private Integer resolveInlineResourceThreshold(AppProperties appProperties) { private Integer resolveInlineResourceThreshold(AppProperties appProperties) {
Integer inlineResourceThreshold = appProperties.getInline_resource_storage_below_size(); Integer inlineResourceThreshold = appProperties.getBinary_storage_minimum_binary_size();
if (inlineResourceThreshold == null if (inlineResourceThreshold == null
&& appProperties.getBinary_storage_mode() == AppProperties.BinaryStorageMode.FILESYSTEM) { && appProperties.getBinary_storage_mode() == AppProperties.BinaryStorageMode.FILESYSTEM) {
return DEFAULT_FILESYSTEM_INLINE_THRESHOLD; return DEFAULT_FILESYSTEM_INLINE_THRESHOLD;

View File

@@ -15,7 +15,6 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.config.ThreadPoolFactoryConfig; import ca.uhn.fhir.jpa.api.config.ThreadPoolFactoryConfig;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider; import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil; import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil;
import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil;
@@ -323,7 +322,6 @@ public class StarterJpaConfig {
Optional<CorsInterceptor> corsInterceptor, Optional<CorsInterceptor> corsInterceptor,
IInterceptorBroadcaster interceptorBroadcaster, IInterceptorBroadcaster interceptorBroadcaster,
Optional<BinaryAccessProvider> binaryAccessProvider, Optional<BinaryAccessProvider> binaryAccessProvider,
BinaryStorageInterceptor binaryStorageInterceptor,
IValidatorModule validatorModule, IValidatorModule validatorModule,
Optional<GraphQLProvider> graphQLProvider, Optional<GraphQLProvider> graphQLProvider,
BulkDataExportProvider bulkDataExportProvider, BulkDataExportProvider bulkDataExportProvider,
@@ -455,7 +453,6 @@ public class StarterJpaConfig {
// Binary Storage // Binary Storage
if (appProperties.getBinary_storage_enabled() && binaryAccessProvider.isPresent()) { if (appProperties.getBinary_storage_enabled() && binaryAccessProvider.isPresent()) {
fhirServer.registerProvider(binaryAccessProvider.get()); fhirServer.registerProvider(binaryAccessProvider.get());
fhirServer.registerInterceptor(binaryStorageInterceptor);
} }
// Validation // Validation

View File

@@ -430,7 +430,7 @@ hapi:
# binary_storage_filesystem_base_directory: /binstore # binary_storage_filesystem_base_directory: /binstore
# When binary_storage_mode is FILESYSTEM and this value is not set, # When binary_storage_mode is FILESYSTEM and this value is not set,
# the starter defaults to 102400 bytes so smaller binaries stay inline. # the starter defaults to 102400 bytes so smaller binaries stay inline.
inline_resource_storage_below_size: 4000 binary_storage_minimum_binary_size: 4000
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# P. Remote Terminology Service (disabled by default) # P. Remote Terminology Service (disabled by default)

View File

@@ -294,7 +294,7 @@ class BinaryStorageFilesystemDefaultIT extends BaseBinaryStorageIntegrationTest
"hapi.fhir.binary_storage_enabled=true", "hapi.fhir.binary_storage_enabled=true",
"hapi.fhir.binary_storage_mode=FILESYSTEM", "hapi.fhir.binary_storage_mode=FILESYSTEM",
"hapi.fhir.binary_storage_filesystem_base_directory=target/test-binary-storage/filesystem-custom", "hapi.fhir.binary_storage_filesystem_base_directory=target/test-binary-storage/filesystem-custom",
"hapi.fhir.inline_resource_storage_below_size=32768" "hapi.fhir.binary_storage_minimum_binary_size=32768"
} }
) )
class BinaryStorageFilesystemCustomThresholdIT extends BaseBinaryStorageIntegrationTest { class BinaryStorageFilesystemCustomThresholdIT extends BaseBinaryStorageIntegrationTest {

View File

@@ -48,7 +48,7 @@ class FhirServerConfigCommonBinaryStorageTest {
void filesystemModeHonoursExplicitMinimum() throws Exception { void filesystemModeHonoursExplicitMinimum() throws Exception {
AppProperties props = new AppProperties(); AppProperties props = new AppProperties();
props.setBinary_storage_mode(AppProperties.BinaryStorageMode.FILESYSTEM); props.setBinary_storage_mode(AppProperties.BinaryStorageMode.FILESYSTEM);
props.setInline_resource_storage_below_size(4096); props.setBinary_storage_minimum_binary_size(4096);
Path baseDir = tempDir.resolve("fs-min-explicit"); Path baseDir = tempDir.resolve("fs-min-explicit");
Files.createDirectories(baseDir); Files.createDirectories(baseDir);
props.setBinary_storage_filesystem_base_directory(baseDir.toString()); props.setBinary_storage_filesystem_base_directory(baseDir.toString());
@@ -62,7 +62,7 @@ class FhirServerConfigCommonBinaryStorageTest {
void filesystemModeSupportsZeroMinimumWhenExplicit() throws Exception { void filesystemModeSupportsZeroMinimumWhenExplicit() throws Exception {
AppProperties props = new AppProperties(); AppProperties props = new AppProperties();
props.setBinary_storage_mode(AppProperties.BinaryStorageMode.FILESYSTEM); props.setBinary_storage_mode(AppProperties.BinaryStorageMode.FILESYSTEM);
props.setInline_resource_storage_below_size(0); props.setBinary_storage_minimum_binary_size(0);
Path baseDir = tempDir.resolve("fs-zero"); Path baseDir = tempDir.resolve("fs-zero");
Files.createDirectories(baseDir); Files.createDirectories(baseDir);
props.setBinary_storage_filesystem_base_directory(baseDir.toString()); props.setBinary_storage_filesystem_base_directory(baseDir.toString());