Merge pull request #72 from hapifhir/rel_4_2_0

Start 4.2.0 release branch
This commit is contained in:
James Agnew
2020-02-16 09:40:57 -05:00
committed by GitHub
6 changed files with 413 additions and 386 deletions

View File

@@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>4.1.0</version> <version>4.2.0</version>
</parent> </parent>
<artifactId>hapi-fhir-jpaserver-starter</artifactId> <artifactId>hapi-fhir-jpaserver-starter</artifactId>
@@ -276,7 +276,7 @@
<plugin> <plugin>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId> <artifactId>jetty-maven-plugin</artifactId>
<version>9.4.22.v20191022</version> <version>${jetty_version}</version>
<configuration> <configuration>
<webApp> <webApp>
<contextPath>/hapi-fhir-jpaserver</contextPath> <contextPath>/hapi-fhir-jpaserver</contextPath>

View File

@@ -173,7 +173,13 @@ public class FhirServerConfigCommon {
@Lazy @Lazy
@Bean @Bean
public IBinaryStorageSvc binaryStorageSvc() { public IBinaryStorageSvc binaryStorageSvc() {
return new DatabaseBlobBinaryStorageSvcImpl(); DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
if (HapiProperties.getMaxBinarySize() != null) {
binaryStorageSvc.setMaximumBinarySize(HapiProperties.getMaxBinarySize());
}
return binaryStorageSvc;
} }
@Bean() @Bean()

View File

@@ -19,452 +19,471 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
public class HapiProperties { public class HapiProperties {
static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields"; static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields";
static final String AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS = "auto_create_placeholder_reference_targets"; static final String AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS = "auto_create_placeholder_reference_targets";
static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE = "enforce_referential_integrity_on_write"; static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE = "enforce_referential_integrity_on_write";
static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE = "enforce_referential_integrity_on_delete"; static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE = "enforce_referential_integrity_on_delete";
static final String BINARY_STORAGE_ENABLED = "binary_storage.enabled"; static final String BINARY_STORAGE_ENABLED = "binary_storage.enabled";
static final String ALLOW_EXTERNAL_REFERENCES = "allow_external_references"; static final String ALLOW_EXTERNAL_REFERENCES = "allow_external_references";
static final String ALLOW_MULTIPLE_DELETE = "allow_multiple_delete"; static final String ALLOW_MULTIPLE_DELETE = "allow_multiple_delete";
static final String ALLOW_PLACEHOLDER_REFERENCES = "allow_placeholder_references"; static final String ALLOW_PLACEHOLDER_REFERENCES = "allow_placeholder_references";
static final String REUSE_CACHED_SEARCH_RESULTS_MILLIS = "reuse_cached_search_results_millis"; static final String REUSE_CACHED_SEARCH_RESULTS_MILLIS = "reuse_cached_search_results_millis";
static final String DATASOURCE_DRIVER = "datasource.driver"; static final String DATASOURCE_DRIVER = "datasource.driver";
static final String DATASOURCE_MAX_POOL_SIZE = "datasource.max_pool_size"; static final String DATASOURCE_MAX_POOL_SIZE = "datasource.max_pool_size";
static final String DATASOURCE_PASSWORD = "datasource.password"; static final String DATASOURCE_PASSWORD = "datasource.password";
static final String DATASOURCE_URL = "datasource.url"; static final String DATASOURCE_URL = "datasource.url";
static final String DATASOURCE_USERNAME = "datasource.username"; static final String DATASOURCE_USERNAME = "datasource.username";
static final String DEFAULT_ENCODING = "default_encoding"; static final String DEFAULT_ENCODING = "default_encoding";
static final String DEFAULT_PAGE_SIZE = "default_page_size"; static final String DEFAULT_PAGE_SIZE = "default_page_size";
static final String DEFAULT_PRETTY_PRINT = "default_pretty_print"; static final String DEFAULT_PRETTY_PRINT = "default_pretty_print";
static final String ETAG_SUPPORT = "etag_support"; static final String ETAG_SUPPORT = "etag_support";
static final String FHIR_VERSION = "fhir_version"; static final String FHIR_VERSION = "fhir_version";
static final String ALLOW_CASCADING_DELETES = "allow_cascading_deletes"; static final String ALLOW_CASCADING_DELETES = "allow_cascading_deletes";
static final String HAPI_PROPERTIES = "hapi.properties"; static final String HAPI_PROPERTIES = "hapi.properties";
static final String LOGGER_ERROR_FORMAT = "logger.error_format"; static final String LOGGER_ERROR_FORMAT = "logger.error_format";
static final String LOGGER_FORMAT = "logger.format"; static final String LOGGER_FORMAT = "logger.format";
static final String LOGGER_LOG_EXCEPTIONS = "logger.log_exceptions"; static final String LOGGER_LOG_EXCEPTIONS = "logger.log_exceptions";
static final String LOGGER_NAME = "logger.name"; static final String LOGGER_NAME = "logger.name";
static final String MAX_FETCH_SIZE = "max_fetch_size"; static final String MAX_FETCH_SIZE = "max_fetch_size";
static final String MAX_PAGE_SIZE = "max_page_size"; static final String MAX_PAGE_SIZE = "max_page_size";
static final String SERVER_ADDRESS = "server_address"; static final String SERVER_ADDRESS = "server_address";
static final String SERVER_ID = "server.id"; static final String SERVER_ID = "server.id";
static final String SERVER_NAME = "server.name"; static final String SERVER_NAME = "server.name";
static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled"; static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled";
static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled"; static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled";
static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled"; static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled";
static final String ALLOWED_BUNDLE_TYPES = "allowed_bundle_types"; static final String ALLOWED_BUNDLE_TYPES = "allowed_bundle_types";
static final String TEST_PORT = "test.port"; static final String TEST_PORT = "test.port";
static final String TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS = "tester.config.refuse_to_fetch_third_party_urls"; static final String TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS = "tester.config.refuse_to_fetch_third_party_urls";
static final String CORS_ENABLED = "cors.enabled"; static final String CORS_ENABLED = "cors.enabled";
static final String CORS_ALLOWED_ORIGIN = "cors.allowed_origin"; static final String CORS_ALLOWED_ORIGIN = "cors.allowed_origin";
static final String CORS_ALLOW_CREDENTIALS = "cors.allowCredentials"; static final String CORS_ALLOW_CREDENTIALS = "cors.allowCredentials";
static final String ALLOW_CONTAINS_SEARCHES = "allow_contains_searches"; static final String ALLOW_CONTAINS_SEARCHES = "allow_contains_searches";
static final String ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS = "allow_override_default_search_params"; static final String ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS = "allow_override_default_search_params";
static final String EMAIL_FROM = "email.from"; static final String EMAIL_FROM = "email.from";
private static final String VALIDATE_REQUESTS_ENABLED = "validation.requests.enabled"; static final String VALIDATE_REQUESTS_ENABLED = "validation.requests.enabled";
private static final String VALIDATE_RESPONSES_ENABLED = "validation.responses.enabled"; static final String VALIDATE_RESPONSES_ENABLED = "validation.responses.enabled";
private static final String FILTER_SEARCH_ENABLED = "filter_search.enabled"; static final String FILTER_SEARCH_ENABLED = "filter_search.enabled";
private static final String GRAPHQL_ENABLED = "graphql.enabled"; static final String GRAPHQL_ENABLED = "graphql.enabled";
private static final String BULK_EXPORT_ENABLED = "bulk.export.enabled"; static final String BULK_EXPORT_ENABLED = "bulk.export.enabled";
public static final String EXPIRE_SEARCH_RESULTS_AFTER_MINS = "retain_cached_searches_mins"; static final String EXPIRE_SEARCH_RESULTS_AFTER_MINS = "retain_cached_searches_mins";
static final String MAX_BINARY_SIZE = "max_binary_size";
private static Properties ourProperties; private static Properties ourProperties;
public static boolean isElasticSearchEnabled() { public static boolean isElasticSearchEnabled() {
return HapiProperties.getPropertyBoolean("elasticsearch.enabled", false); return HapiProperties.getPropertyBoolean("elasticsearch.enabled", false);
}
/*
* Force the configuration to be reloaded
*/
public static void forceReload() {
ourProperties = null;
getProperties();
}
/**
* This is mostly here for unit tests. Use the actual properties file
* to set values
*/
@VisibleForTesting
public static void setProperty(String theKey, String theValue) {
getProperties().setProperty(theKey, theValue);
}
public static Properties getJpaProperties() {
Properties retVal = loadProperties();
if (isElasticSearchEnabled()) {
ElasticsearchHibernatePropertiesBuilder builder = new ElasticsearchHibernatePropertiesBuilder();
builder.setRequiredIndexStatus(getPropertyEnum("elasticsearch.required_index_status", ElasticsearchIndexStatus.class, ElasticsearchIndexStatus.YELLOW));
builder.setRestUrl(getProperty("elasticsearch.rest_url"));
builder.setUsername(getProperty("elasticsearch.username"));
builder.setPassword(getProperty("elasticsearch.password"));
builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strategy", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
builder.apply(retVal);
} }
/* return retVal;
* Force the configuration to be reloaded }
*/
public static void forceReload() {
ourProperties = null;
getProperties();
}
/**
* This is mostly here for unit tests. Use the actual properties file
* to set values
*/
@VisibleForTesting
public static void setProperty(String theKey, String theValue) {
getProperties().setProperty(theKey, theValue);
}
public static Properties getJpaProperties() { private static Properties getProperties() {
Properties retVal = loadProperties(); if (ourProperties == null) {
Properties properties = loadProperties();
if (isElasticSearchEnabled()) { HapiProperties.ourProperties = properties;
ElasticsearchHibernatePropertiesBuilder builder = new ElasticsearchHibernatePropertiesBuilder();
builder.setRequiredIndexStatus(getPropertyEnum("elasticsearch.required_index_status", ElasticsearchIndexStatus.class, ElasticsearchIndexStatus.YELLOW));
builder.setRestUrl(getProperty("elasticsearch.rest_url"));
builder.setUsername(getProperty("elasticsearch.username"));
builder.setPassword(getProperty("elasticsearch.password"));
builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strategy", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
builder.apply(retVal);
}
return retVal;
} }
private static Properties getProperties() { return ourProperties;
if (ourProperties == null) { }
Properties properties = loadProperties();
HapiProperties.ourProperties = properties;
}
return ourProperties; @NotNull
private static Properties loadProperties() {
// Load the configurable properties file
Properties properties;
try (InputStream in = HapiProperties.class.getClassLoader().getResourceAsStream(HAPI_PROPERTIES)) {
properties = new Properties();
properties.load(in);
} catch (Exception e) {
throw new ConfigurationException("Could not load HAPI properties", e);
} }
@NotNull Properties overrideProps = loadOverrideProperties();
private static Properties loadProperties() { if (overrideProps != null) {
// Load the configurable properties file properties.putAll(overrideProps);
Properties properties;
try (InputStream in = HapiProperties.class.getClassLoader().getResourceAsStream(HAPI_PROPERTIES)) {
properties = new Properties();
properties.load(in);
} catch (Exception e) {
throw new ConfigurationException("Could not load HAPI properties", e);
}
Properties overrideProps = loadOverrideProperties();
if (overrideProps != null) {
properties.putAll(overrideProps);
}
return properties;
} }
return properties;
}
/** /**
* If a configuration file path is explicitly specified via -Dhapi.properties=<path>, the properties there will * If a configuration file path is explicitly specified via -Dhapi.properties=<path>, the properties there will
* be used to override the entries in the default hapi.properties file (currently under WEB-INF/classes) * be used to override the entries in the default hapi.properties file (currently under WEB-INF/classes)
* *
* @return properties loaded from the explicitly specified configuraiton file if there is one, or null otherwise. * @return properties loaded from the explicitly specified configuraiton file if there is one, or null otherwise.
*/ */
private static Properties loadOverrideProperties() { private static Properties loadOverrideProperties() {
String confFile = System.getProperty(HAPI_PROPERTIES); String confFile = System.getProperty(HAPI_PROPERTIES);
if (confFile != null) { if (confFile != null) {
try { try {
Properties props = new Properties(); Properties props = new Properties();
props.load(new FileInputStream(confFile)); props.load(new FileInputStream(confFile));
return props; return props;
} catch (Exception e) { } catch (Exception e) {
throw new ConfigurationException("Could not load HAPI properties file: " + confFile, e); throw new ConfigurationException("Could not load HAPI properties file: " + confFile, e);
} }
}
return null;
} }
private static String getProperty(String propertyName) { return null;
String env = "HAPI_" + propertyName.toUpperCase(Locale.US); }
env = env.replace(".", "_");
env = env.replace("-", "_");
String propertyValue = System.getenv(env); private static String getProperty(String propertyName) {
if (propertyValue != null) { String env = "HAPI_" + propertyName.toUpperCase(Locale.US);
return propertyValue; env = env.replace(".", "_");
} env = env.replace("-", "_");
Properties properties = HapiProperties.getProperties(); String propertyValue = System.getenv(env);
if (properties != null) { if (propertyValue != null) {
propertyValue = properties.getProperty(propertyName); return propertyValue;
}
return propertyValue;
} }
private static String getProperty(String propertyName, String defaultValue) { Properties properties = HapiProperties.getProperties();
String value = getProperty(propertyName); if (properties != null) {
propertyValue = properties.getProperty(propertyName);
if (value != null && value.length() > 0) {
return value;
}
return defaultValue;
} }
private static Boolean getBooleanProperty(String propertyName, Boolean defaultValue) { return propertyValue;
String value = HapiProperties.getProperty(propertyName); }
if (value == null || value.length() == 0) { private static String getProperty(String propertyName, String defaultValue) {
return defaultValue; String value = getProperty(propertyName);
}
return Boolean.parseBoolean(value); if (value != null && value.length() > 0) {
return value;
} }
private static boolean getBooleanProperty(String propertyName, boolean defaultValue) { return defaultValue;
return getBooleanProperty(propertyName, Boolean.valueOf(defaultValue)); }
}
private static Integer getIntegerProperty(String propertyName, Integer defaultValue) {
String value = HapiProperties.getProperty(propertyName);
if (value == null || value.length() == 0) { private static Boolean getBooleanProperty(String propertyName, Boolean defaultValue) {
return defaultValue; String value = HapiProperties.getProperty(propertyName);
}
return Integer.parseInt(value); if (value == null || value.length() == 0) {
return defaultValue;
} }
public static FhirVersionEnum getFhirVersion() { return Boolean.parseBoolean(value);
String fhirVersionString = HapiProperties.getProperty(FHIR_VERSION); }
if (fhirVersionString != null && fhirVersionString.length() > 0) { private static boolean getBooleanProperty(String propertyName, boolean defaultValue) {
return FhirVersionEnum.valueOf(fhirVersionString); return getBooleanProperty(propertyName, Boolean.valueOf(defaultValue));
} }
return FhirVersionEnum.DSTU3; private static Integer getIntegerProperty(String propertyName, Integer defaultValue) {
} String value = HapiProperties.getProperty(propertyName);
public static boolean isBinaryStorageEnabled() { if (value == null || value.length() == 0) {
return HapiProperties.getBooleanProperty(BINARY_STORAGE_ENABLED, true); return defaultValue;
} }
public static ETagSupportEnum getEtagSupport() { return Integer.parseInt(value);
String etagSupportString = HapiProperties.getProperty(ETAG_SUPPORT); }
if (etagSupportString != null && etagSupportString.length() > 0) { public static FhirVersionEnum getFhirVersion() {
return ETagSupportEnum.valueOf(etagSupportString); String fhirVersionString = HapiProperties.getProperty(FHIR_VERSION);
}
return ETagSupportEnum.ENABLED; if (fhirVersionString != null && fhirVersionString.length() > 0) {
return FhirVersionEnum.valueOf(fhirVersionString);
} }
public static EncodingEnum getDefaultEncoding() { return FhirVersionEnum.DSTU3;
String defaultEncodingString = HapiProperties.getProperty(DEFAULT_ENCODING); }
if (defaultEncodingString != null && defaultEncodingString.length() > 0) { public static boolean isBinaryStorageEnabled() {
return EncodingEnum.valueOf(defaultEncodingString); return HapiProperties.getBooleanProperty(BINARY_STORAGE_ENABLED, true);
} }
return EncodingEnum.JSON; public static ETagSupportEnum getEtagSupport() {
} String etagSupportString = HapiProperties.getProperty(ETAG_SUPPORT);
public static Boolean getDefaultPrettyPrint() { if (etagSupportString != null && etagSupportString.length() > 0) {
return HapiProperties.getBooleanProperty(DEFAULT_PRETTY_PRINT, true); return ETagSupportEnum.valueOf(etagSupportString);
} }
public static String getServerAddress() { return ETagSupportEnum.ENABLED;
return HapiProperties.getProperty(SERVER_ADDRESS); }
}
public static Integer getDefaultPageSize() { public static EncodingEnum getDefaultEncoding() {
return HapiProperties.getIntegerProperty(DEFAULT_PAGE_SIZE, 20); String defaultEncodingString = HapiProperties.getProperty(DEFAULT_ENCODING);
}
public static Integer getMaximumPageSize() {
return HapiProperties.getIntegerProperty(MAX_PAGE_SIZE, 200);
}
public static Integer getMaximumFetchSize() {
return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE);
}
public static String getLoggerName() { if (defaultEncodingString != null && defaultEncodingString.length() > 0) {
return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access"); return EncodingEnum.valueOf(defaultEncodingString);
} }
public static String getLoggerFormat() { return EncodingEnum.JSON;
return HapiProperties.getProperty(LOGGER_FORMAT, "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]"); }
}
public static String getLoggerErrorFormat() { public static Boolean getDefaultPrettyPrint() {
return HapiProperties.getProperty(LOGGER_ERROR_FORMAT, "ERROR - ${requestVerb} ${requestUrl}"); return HapiProperties.getBooleanProperty(DEFAULT_PRETTY_PRINT, true);
} }
public static Boolean getLoggerLogExceptions() { public static String getServerAddress() {
return HapiProperties.getBooleanProperty(LOGGER_LOG_EXCEPTIONS, true); return HapiProperties.getProperty(SERVER_ADDRESS);
} }
public static String getDataSourceDriver() {
return HapiProperties.getProperty(DATASOURCE_DRIVER, "org.apache.derby.jdbc.EmbeddedDriver");
}
public static Integer getDataSourceMaxPoolSize() { public static Integer getDefaultPageSize() {
return HapiProperties.getIntegerProperty(DATASOURCE_MAX_POOL_SIZE, 10); return HapiProperties.getIntegerProperty(DEFAULT_PAGE_SIZE, 20);
} }
public static String getDataSourceUrl() { public static Integer getMaximumPageSize() {
return HapiProperties.getProperty(DATASOURCE_URL, "jdbc:derby:directory:target/jpaserver_derby_files;create=true"); return HapiProperties.getIntegerProperty(MAX_PAGE_SIZE, 200);
} }
public static String getDataSourceUsername() { public static Integer getMaximumFetchSize() {
return HapiProperties.getProperty(DATASOURCE_USERNAME); return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE);
} }
public static String getDataSourcePassword() { public static String getLoggerName() {
return HapiProperties.getProperty(DATASOURCE_PASSWORD); return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access");
} }
public static Boolean getAllowMultipleDelete() { public static String getLoggerFormat() {
return HapiProperties.getBooleanProperty(ALLOW_MULTIPLE_DELETE, false); return HapiProperties.getProperty(LOGGER_FORMAT, "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]");
} }
public static Boolean getAllowCascadingDeletes() { public static String getLoggerErrorFormat() {
return HapiProperties.getBooleanProperty(ALLOW_CASCADING_DELETES, false); return HapiProperties.getProperty(LOGGER_ERROR_FORMAT, "ERROR - ${requestVerb} ${requestUrl}");
} }
public static Boolean getAllowExternalReferences() { public static Boolean getLoggerLogExceptions() {
return HapiProperties.getBooleanProperty(ALLOW_EXTERNAL_REFERENCES, false); return HapiProperties.getBooleanProperty(LOGGER_LOG_EXCEPTIONS, true);
} }
public static Boolean getExpungeEnabled() { public static String getDataSourceDriver() {
return HapiProperties.getBooleanProperty("expunge_enabled", true); return HapiProperties.getProperty(DATASOURCE_DRIVER, "org.apache.derby.jdbc.EmbeddedDriver");
} }
public static Integer getTestPort() { public static Integer getDataSourceMaxPoolSize() {
return HapiProperties.getIntegerProperty(TEST_PORT, 0); return HapiProperties.getIntegerProperty(DATASOURCE_MAX_POOL_SIZE, 10);
} }
public static Boolean getTesterConfigRefustToFetchThirdPartyUrls() { public static String getDataSourceUrl() {
return HapiProperties.getBooleanProperty(TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS, false); return HapiProperties.getProperty(DATASOURCE_URL, "jdbc:derby:directory:target/jpaserver_derby_files;create=true");
} }
public static Boolean getCorsEnabled() { public static String getDataSourceUsername() {
return HapiProperties.getBooleanProperty(CORS_ENABLED, true); return HapiProperties.getProperty(DATASOURCE_USERNAME);
} }
public static String getCorsAllowedOrigin() { public static String getDataSourcePassword() {
return HapiProperties.getProperty(CORS_ALLOWED_ORIGIN, "*"); return HapiProperties.getProperty(DATASOURCE_PASSWORD);
} }
public static String getAllowedBundleTypes() { public static Boolean getAllowMultipleDelete() {
return HapiProperties.getProperty(ALLOWED_BUNDLE_TYPES, ""); return HapiProperties.getBooleanProperty(ALLOW_MULTIPLE_DELETE, false);
} }
@Nonnull public static Boolean getAllowCascadingDeletes() {
public static Set<String> getSupportedResourceTypes() { return HapiProperties.getBooleanProperty(ALLOW_CASCADING_DELETES, false);
String[] types = defaultString(getProperty("supported_resource_types")).split(","); }
return Arrays.stream(types)
.map(t -> trim(t))
.filter(t -> isNotBlank(t))
.collect(Collectors.toSet());
}
public static String getServerName() { public static Boolean getAllowExternalReferences() {
return HapiProperties.getProperty(SERVER_NAME, "Local Tester"); return HapiProperties.getBooleanProperty(ALLOW_EXTERNAL_REFERENCES, false);
} }
public static String getServerId() { public static Boolean getExpungeEnabled() {
return HapiProperties.getProperty(SERVER_ID, "home"); return HapiProperties.getBooleanProperty("expunge_enabled", true);
} }
public static Boolean getAllowPlaceholderReferences() { public static Integer getTestPort() {
return HapiProperties.getBooleanProperty(ALLOW_PLACEHOLDER_REFERENCES, true); return HapiProperties.getIntegerProperty(TEST_PORT, 0);
} }
public static Boolean getSubscriptionEmailEnabled() { public static Boolean getTesterConfigRefustToFetchThirdPartyUrls() {
return HapiProperties.getBooleanProperty(SUBSCRIPTION_EMAIL_ENABLED, false); return HapiProperties.getBooleanProperty(TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS, false);
} }
public static Boolean getSubscriptionRestHookEnabled() { public static Boolean getCorsEnabled() {
return HapiProperties.getBooleanProperty(SUBSCRIPTION_RESTHOOK_ENABLED, false); return HapiProperties.getBooleanProperty(CORS_ENABLED, true);
} }
public static Boolean getSubscriptionWebsocketEnabled() { public static String getCorsAllowedOrigin() {
return HapiProperties.getBooleanProperty(SUBSCRIPTION_WEBSOCKET_ENABLED, false); return HapiProperties.getProperty(CORS_ALLOWED_ORIGIN, "*");
} }
public static Boolean getAllowContainsSearches() { public static String getAllowedBundleTypes() {
return HapiProperties.getBooleanProperty(ALLOW_CONTAINS_SEARCHES, true); return HapiProperties.getProperty(ALLOWED_BUNDLE_TYPES, "");
} }
public static Boolean getAllowOverrideDefaultSearchParams() { @Nonnull
return HapiProperties.getBooleanProperty(ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS, true); public static Set<String> getSupportedResourceTypes() {
} String[] types = defaultString(getProperty("supported_resource_types")).split(",");
return Arrays.stream(types)
public static String getEmailFrom() { .map(t -> trim(t))
return HapiProperties.getProperty(EMAIL_FROM, "some@test.com"); .filter(t -> isNotBlank(t))
} .collect(Collectors.toSet());
}
public static Boolean getEmailEnabled() {
return HapiProperties.getBooleanProperty("email.enabled", false); public static String getServerName() {
} return HapiProperties.getProperty(SERVER_NAME, "Local Tester");
}
public static String getEmailHost() {
return HapiProperties.getProperty("email.host"); public static String getServerId() {
} return HapiProperties.getProperty(SERVER_ID, "home");
}
public static Integer getEmailPort() {
return HapiProperties.getIntegerProperty("email.port", 0); public static Boolean getAllowPlaceholderReferences() {
} return HapiProperties.getBooleanProperty(ALLOW_PLACEHOLDER_REFERENCES, true);
}
public static String getEmailUsername() {
return HapiProperties.getProperty("email.username"); public static Boolean getSubscriptionEmailEnabled() {
} return HapiProperties.getBooleanProperty(SUBSCRIPTION_EMAIL_ENABLED, false);
}
public static String getEmailPassword() {
return HapiProperties.getProperty("email.password"); public static Boolean getSubscriptionRestHookEnabled() {
} return HapiProperties.getBooleanProperty(SUBSCRIPTION_RESTHOOK_ENABLED, false);
}
// Defaults from https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
public static Boolean getEmailAuth() { return HapiProperties.getBooleanProperty("email.auth", false); } public static Boolean getSubscriptionWebsocketEnabled() {
public static Boolean getEmailStartTlsEnable() { return HapiProperties.getBooleanProperty("email.starttls.enable", false); } return HapiProperties.getBooleanProperty(SUBSCRIPTION_WEBSOCKET_ENABLED, false);
public static Boolean getEmailStartTlsRequired() { return HapiProperties.getBooleanProperty("email.starttls.required", false); } }
public static Boolean getEmailQuitWait() { return HapiProperties.getBooleanProperty("email.quitwait", true); }
public static Boolean getAllowContainsSearches() {
public static Long getReuseCachedSearchResultsMillis() { return HapiProperties.getBooleanProperty(ALLOW_CONTAINS_SEARCHES, true);
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000"); }
return Long.valueOf(value);
} public static Boolean getAllowOverrideDefaultSearchParams() {
return HapiProperties.getBooleanProperty(ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS, true);
public static Long getExpireSearchResultsAfterMins() { }
String value = HapiProperties.getProperty(EXPIRE_SEARCH_RESULTS_AFTER_MINS, "60");
return Long.valueOf(value); public static String getEmailFrom() {
} return HapiProperties.getProperty(EMAIL_FROM, "some@test.com");
}
public static Boolean getCorsAllowedCredentials() {
return HapiProperties.getBooleanProperty(CORS_ALLOW_CREDENTIALS, false); public static Boolean getEmailEnabled() {
} return HapiProperties.getBooleanProperty("email.enabled", false);
}
public static boolean getValidateRequestsEnabled() {
return HapiProperties.getBooleanProperty(VALIDATE_REQUESTS_ENABLED, false); public static String getEmailHost() {
} return HapiProperties.getProperty("email.host");
}
public static boolean getValidateResponsesEnabled() {
return HapiProperties.getBooleanProperty(VALIDATE_RESPONSES_ENABLED, false); public static Integer getEmailPort() {
} return HapiProperties.getIntegerProperty("email.port", 0);
}
public static boolean getFilterSearchEnabled() {
return HapiProperties.getBooleanProperty(FILTER_SEARCH_ENABLED, true); public static String getEmailUsername() {
} return HapiProperties.getProperty("email.username");
}
public static boolean getGraphqlEnabled() {
return HapiProperties.getBooleanProperty(GRAPHQL_ENABLED, true); public static String getEmailPassword() {
} return HapiProperties.getProperty("email.password");
}
public static boolean getEnforceReferentialIntegrityOnDelete() {
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE, true); // Defaults from https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
} public static Boolean getEmailAuth() {
return HapiProperties.getBooleanProperty("email.auth", false);
public static boolean getEnforceReferentialIntegrityOnWrite() { }
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE, true);
} public static Boolean getEmailStartTlsEnable() {
return HapiProperties.getBooleanProperty("email.starttls.enable", false);
public static boolean getAutoCreatePlaceholderReferenceTargets() { }
return HapiProperties.getBooleanProperty(AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS, true);
} public static Boolean getEmailStartTlsRequired() {
return HapiProperties.getBooleanProperty("email.starttls.required", false);
public static boolean getEnableIndexMissingFields() { }
return HapiProperties.getBooleanProperty(ENABLE_INDEX_MISSING_FIELDS, false);
} public static Boolean getEmailQuitWait() {
private static boolean getPropertyBoolean(String thePropertyName, boolean theDefaultValue) { return HapiProperties.getBooleanProperty("email.quitwait", true);
String value = getProperty(thePropertyName, Boolean.toString(theDefaultValue)); }
return Boolean.parseBoolean(value);
} public static Long getReuseCachedSearchResultsMillis() {
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
private static <T extends Enum> T getPropertyEnum(String thePropertyName, Class<T> theEnumType, T theDefaultValue) { return Long.valueOf(value);
String value = getProperty(thePropertyName, theDefaultValue.name()); }
return (T) Enum.valueOf(theEnumType, value);
} public static Long getExpireSearchResultsAfterMins() {
String value = HapiProperties.getProperty(EXPIRE_SEARCH_RESULTS_AFTER_MINS, "60");
public static boolean getBulkExportEnabled() { return Long.valueOf(value);
return HapiProperties.getBooleanProperty(BULK_EXPORT_ENABLED, true); }
}
public static Boolean getCorsAllowedCredentials() {
return HapiProperties.getBooleanProperty(CORS_ALLOW_CREDENTIALS, false);
}
public static boolean getValidateRequestsEnabled() {
return HapiProperties.getBooleanProperty(VALIDATE_REQUESTS_ENABLED, false);
}
public static boolean getValidateResponsesEnabled() {
return HapiProperties.getBooleanProperty(VALIDATE_RESPONSES_ENABLED, false);
}
public static boolean getFilterSearchEnabled() {
return HapiProperties.getBooleanProperty(FILTER_SEARCH_ENABLED, true);
}
public static boolean getGraphqlEnabled() {
return HapiProperties.getBooleanProperty(GRAPHQL_ENABLED, true);
}
public static boolean getEnforceReferentialIntegrityOnDelete() {
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE, true);
}
public static boolean getEnforceReferentialIntegrityOnWrite() {
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE, true);
}
public static boolean getAutoCreatePlaceholderReferenceTargets() {
return HapiProperties.getBooleanProperty(AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS, true);
}
public static boolean getEnableIndexMissingFields() {
return HapiProperties.getBooleanProperty(ENABLE_INDEX_MISSING_FIELDS, false);
}
public static Integer getMaxBinarySize() {
return getIntegerProperty(MAX_BINARY_SIZE, null);
}
private static boolean getPropertyBoolean(String thePropertyName, boolean theDefaultValue) {
String value = getProperty(thePropertyName, Boolean.toString(theDefaultValue));
return Boolean.parseBoolean(value);
}
private static <T extends Enum> T getPropertyEnum(String thePropertyName, Class<T> theEnumType, T theDefaultValue) {
String value = getProperty(thePropertyName, theDefaultValue.name());
return (T) Enum.valueOf(theEnumType, value);
}
public static boolean getBulkExportEnabled() {
return HapiProperties.getBooleanProperty(BULK_EXPORT_ENABLED, true);
}
} }

View File

@@ -43,6 +43,11 @@ server.name=Local Tester
server.id=home server.id=home
test.port= test.port=
###################################################
# Binary Storage (104857600 = 100mb)
###################################################
max_binary_size=104857600
################################################### ###################################################
# Validation # Validation
################################################### ###################################################

View File

@@ -43,6 +43,8 @@ public class ExampleServerDstu3IT {
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3"); HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3");
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr3"); HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr3");
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true"); HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
HapiProperties.setProperty(HapiProperties.ALLOW_EXTERNAL_REFERENCES, "true");
HapiProperties.setProperty(HapiProperties.ALLOW_PLACEHOLDER_REFERENCES, "true");
ourCtx = FhirContext.forDstu3(); ourCtx = FhirContext.forDstu3();
} }

View File

@@ -14,12 +14,7 @@ import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.Bundle; import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.Patient;
import org.hl7.fhir.r5.model.Subscription;
import org.hl7.fhir.r5.model.Topic;
import org.hl7.fhir.r5.model.codesystems.SubscriptionChannelType;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@@ -80,8 +75,8 @@ public class ExampleServerR5IT {
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent(); Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
channel.getType().addCoding() channel.getType().addCoding()
.setSystem(SubscriptionChannelType.WEBSOCKET.getSystem()) .setSystem("http://terminology.hl7.org/CodeSystem/subscription-channel-type")
.setCode(SubscriptionChannelType.WEBSOCKET.toCode()); .setCode("websocket");
channel.getPayload().setContentType("application/json"); channel.getPayload().setContentType("application/json");
subscription.setChannel(channel); subscription.setChannel(channel);
@@ -111,7 +106,7 @@ public class ExampleServerR5IT {
* Create a matching resource * Create a matching resource
*/ */
Observation obs = new Observation(); Observation obs = new Observation();
obs.setStatus(Observation.ObservationStatus.FINAL); obs.setStatus(Enumerations.ObservationStatus.FINAL);
ourClient.create().resource(obs).execute(); ourClient.create().resource(obs).execute();
// Give some time for the subscription to deliver // Give some time for the subscription to deliver