* Add configurable filesystem binary storage (fix #860) * Refine binary storage configuration handling * Refine binary storage bean wiring * Refine binary storage conditional beans * Add integration coverage for binary storage configs * Exercise binary storage via REST integration tests * Update src/main/resources/application.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Ubuntu <ubuntu@ip-172-31-35-43.eu-west-2.compute.internal> Co-authored-by: Ubuntu <ubuntu@ip-172-31-10-131.eu-west-2.compute.internal> Co-authored-by: Jens Kristian Villadsen <jenskristianvilladsen@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -61,7 +61,15 @@ public class AppProperties {
|
||||
private Boolean filter_search_enabled = true;
|
||||
private Boolean graphql_enabled = false;
|
||||
private Boolean binary_storage_enabled = false;
|
||||
private Integer inline_resource_storage_below_size = 0;
|
||||
|
||||
public enum BinaryStorageMode {
|
||||
DATABASE,
|
||||
FILESYSTEM
|
||||
}
|
||||
|
||||
private BinaryStorageMode binary_storage_mode = BinaryStorageMode.DATABASE;
|
||||
private String binary_storage_filesystem_base_directory;
|
||||
private Integer inline_resource_storage_below_size;
|
||||
private Boolean bulk_export_enabled = false;
|
||||
private Boolean bulk_import_enabled = false;
|
||||
private Boolean default_pretty_print = true;
|
||||
@@ -485,6 +493,22 @@ public class AppProperties {
|
||||
this.binary_storage_enabled = binary_storage_enabled;
|
||||
}
|
||||
|
||||
public BinaryStorageMode getBinary_storage_mode() {
|
||||
return binary_storage_mode;
|
||||
}
|
||||
|
||||
public void setBinary_storage_mode(BinaryStorageMode binary_storage_mode) {
|
||||
this.binary_storage_mode = binary_storage_mode;
|
||||
}
|
||||
|
||||
public String getBinary_storage_filesystem_base_directory() {
|
||||
return binary_storage_filesystem_base_directory;
|
||||
}
|
||||
|
||||
public void setBinary_storage_filesystem_base_directory(String binary_storage_filesystem_base_directory) {
|
||||
this.binary_storage_filesystem_base_directory = binary_storage_filesystem_base_directory;
|
||||
}
|
||||
|
||||
public Integer getInline_resource_storage_below_size() {
|
||||
return inline_resource_storage_below_size;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package ca.uhn.fhir.jpa.starter.common;
|
||||
|
||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||
import ca.uhn.fhir.jpa.binary.api.IBinaryStorageSvc;
|
||||
import ca.uhn.fhir.jpa.binstore.DatabaseBinaryContentStorageSvcImpl;
|
||||
import ca.uhn.fhir.jpa.binstore.FilesystemBinaryStorageSvcImpl;
|
||||
import ca.uhn.fhir.jpa.config.HibernatePropertiesProvider;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings.CrossPartitionReferenceMode;
|
||||
@@ -19,10 +19,12 @@ import com.google.common.base.Strings;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -38,6 +40,7 @@ import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
public class FhirServerConfigCommon {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FhirServerConfigCommon.class);
|
||||
private static final int DEFAULT_FILESYSTEM_INLINE_THRESHOLD = 102_400;
|
||||
|
||||
public FhirServerConfigCommon(AppProperties appProperties) {
|
||||
ourLog.info(
|
||||
@@ -222,8 +225,9 @@ public class FhirServerConfigCommon {
|
||||
jpaStorageSettings.setLastNEnabled(true);
|
||||
}
|
||||
|
||||
if (appProperties.getInline_resource_storage_below_size() != 0) {
|
||||
jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size());
|
||||
Integer inlineResourceThreshold = resolveInlineResourceThreshold(appProperties);
|
||||
if (inlineResourceThreshold != null && inlineResourceThreshold != 0) {
|
||||
jpaStorageSettings.setInlineResourceTextBelowSize(inlineResourceThreshold);
|
||||
}
|
||||
|
||||
jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled());
|
||||
@@ -354,16 +358,50 @@ public class FhirServerConfigCommon {
|
||||
return new JpaHibernatePropertiesProvider(myEntityManagerFactory);
|
||||
}
|
||||
|
||||
@Lazy
|
||||
@Bean
|
||||
public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) {
|
||||
DatabaseBinaryContentStorageSvcImpl binaryStorageSvc = new DatabaseBinaryContentStorageSvcImpl();
|
||||
@ConditionalOnProperty(prefix = "hapi.fhir", name = "binary_storage_mode", havingValue = "FILESYSTEM")
|
||||
public FilesystemBinaryStorageSvcImpl filesystemBinaryStorageSvc(AppProperties appProperties) {
|
||||
String baseDirectory = appProperties.getBinary_storage_filesystem_base_directory();
|
||||
Assert.hasText(
|
||||
baseDirectory,
|
||||
"binary_storage_filesystem_base_directory must be provided when binary_storage_mode=FILESYSTEM");
|
||||
|
||||
if (appProperties.getMax_binary_size() != null) {
|
||||
binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size());
|
||||
FilesystemBinaryStorageSvcImpl filesystemSvc = new FilesystemBinaryStorageSvcImpl(baseDirectory);
|
||||
Integer inlineResourceThreshold = resolveInlineResourceThreshold(appProperties);
|
||||
int minimumBinarySize =
|
||||
inlineResourceThreshold == null ? DEFAULT_FILESYSTEM_INLINE_THRESHOLD : inlineResourceThreshold;
|
||||
filesystemSvc.setMinimumBinarySize(minimumBinarySize);
|
||||
|
||||
Integer maxBinarySize = appProperties.getMax_binary_size();
|
||||
if (maxBinarySize != null) {
|
||||
filesystemSvc.setMaximumBinarySize(maxBinarySize.longValue());
|
||||
}
|
||||
|
||||
return binaryStorageSvc;
|
||||
return filesystemSvc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(
|
||||
prefix = "hapi.fhir",
|
||||
name = "binary_storage_mode",
|
||||
havingValue = "DATABASE",
|
||||
matchIfMissing = true)
|
||||
public DatabaseBinaryContentStorageSvcImpl databaseBinaryStorageSvc(AppProperties appProperties) {
|
||||
DatabaseBinaryContentStorageSvcImpl databaseSvc = new DatabaseBinaryContentStorageSvcImpl();
|
||||
Integer maxBinarySize = appProperties.getMax_binary_size();
|
||||
if (maxBinarySize != null) {
|
||||
databaseSvc.setMaximumBinarySize(maxBinarySize.longValue());
|
||||
}
|
||||
return databaseSvc;
|
||||
}
|
||||
|
||||
private Integer resolveInlineResourceThreshold(AppProperties appProperties) {
|
||||
Integer inlineResourceThreshold = appProperties.getInline_resource_storage_below_size();
|
||||
if (inlineResourceThreshold == null
|
||||
&& appProperties.getBinary_storage_mode() == AppProperties.BinaryStorageMode.FILESYSTEM) {
|
||||
return DEFAULT_FILESYSTEM_INLINE_THRESHOLD;
|
||||
}
|
||||
return inlineResourceThreshold;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -386,6 +386,14 @@ hapi:
|
||||
# max_page_size: 200
|
||||
# retain_cached_searches_mins: 60
|
||||
# reuse_cached_search_results_millis: 60000
|
||||
# validation:
|
||||
# requests_enabled: true
|
||||
# responses_enabled: true
|
||||
# binary_storage_enabled: true
|
||||
# binary_storage_mode: FILESYSTEM
|
||||
# binary_storage_filesystem_base_directory: /binstore
|
||||
# When binary_storage_mode is FILESYSTEM and this value is not set,
|
||||
# the starter defaults to 102400 bytes so smaller binaries stay inline.
|
||||
inline_resource_storage_below_size: 4000
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user