Add a new option to CLI run-server called "--lowmem" which puts the

server into low memeory mode
This commit is contained in:
James Agnew 2016-05-10 13:45:30 -04:00
parent 3e77d3e37e
commit 54d0fa0faa
6 changed files with 86 additions and 36 deletions

View File

@ -45,6 +45,7 @@ public class RunServerCommand extends BaseCommand {
Options options = new Options();
addFhirVersionOption(options);
options.addOption(OPTION_P, "port", true, "The port to listen on (default is " + DEFAULT_PORT + ")");
options.addOption(null, "lowmem", false, "If this flag is set, the server will operate in low memory mode (some features disabled)");
return options;
}
@ -60,6 +61,11 @@ public class RunServerCommand extends BaseCommand {
public void run(CommandLine theCommandLine) throws ParseException {
myPort = parseOptionInteger(theCommandLine, OPTION_P, DEFAULT_PORT);
if (theCommandLine.hasOption("lowmem")) {
ourLog.info("Running in low memory mode, some features disabled");
System.setProperty("lowmem", "lowmem");
}
ContextHolder.setCtx(getSpecVersionContext(theCommandLine));
ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort);

View File

@ -0,0 +1,38 @@
package ca.uhn.fhir.jpa.demo;
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FhirDbConfig {
private boolean ourLowMemMode;
@Bean()
public Properties jpaProperties() {
Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.jdbc.batch_size", "20");
extraProperties.put("hibernate.cache.use_query_cache", "false");
extraProperties.put("hibernate.cache.use_second_level_cache", "false");
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put("hibernate.search.default.directory_provider", "filesystem");
extraProperties.put("hibernate.search.default.indexBase", "target/lucenefiles");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
// extraProperties.put("hibernate.search.default.worker.execution", "async");
if (System.getProperty("lowmem") != null) {
extraProperties.put("hibernate.search.autoregister_listeners", "false");
}
return extraProperties;
}
}

View File

@ -9,8 +9,11 @@ import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ -24,6 +27,7 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
@Configuration
@EnableTransactionManagement()
@Import(FhirDbConfig.class)
public class FhirServerConfig extends BaseJavaConfigDstu2 {
/**
@ -55,6 +59,10 @@ public class FhirServerConfig extends BaseJavaConfigDstu2 {
return retVal;
}
@Autowired()
@Qualifier("jpaProperties")
private Properties myJpaProperties;
@Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean();
@ -62,26 +70,10 @@ public class FhirServerConfig extends BaseJavaConfigDstu2 {
retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties());
retVal.setJpaProperties(myJpaProperties);
return retVal;
}
private Properties jpaProperties() {
Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.jdbc.batch_size", "20");
extraProperties.put("hibernate.cache.use_query_cache", "false");
extraProperties.put("hibernate.cache.use_second_level_cache", "false");
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put("hibernate.search.default.directory_provider", "filesystem");
extraProperties.put("hibernate.search.default.indexBase", "target/lucenefiles");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
return extraProperties;
}
/**
* Do some fancy logging to create a nice access log that has details about each incoming request.

View File

@ -9,8 +9,11 @@ import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ -31,6 +34,7 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
*/
@Configuration
@EnableTransactionManagement()
@Import(FhirDbConfig.class)
public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
/**
@ -69,28 +73,14 @@ public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties());
retVal.setJpaProperties(myJpaProperties);
return retVal;
}
private Properties jpaProperties() {
Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.jdbc.batch_size", "20");
extraProperties.put("hibernate.cache.use_query_cache", "false");
extraProperties.put("hibernate.cache.use_second_level_cache", "false");
extraProperties.put("hibernate.cache.use_structured_entries", "false");
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
extraProperties.put("hibernate.search.default.directory_provider", "filesystem");
extraProperties.put("hibernate.search.default.indexBase", "target/lucenefiles");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
// extraProperties.put("hibernate.search.default.worker.execution", "async");
return extraProperties;
}
@Autowired()
@Qualifier("jpaProperties")
private Properties myJpaProperties;
/**
* Do some fancy logging to create a nice access log that has details about each incoming request.
*/

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.rest.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -35,6 +36,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.util.PortUtil;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.PatientProfileDstu2;
@ -83,11 +85,26 @@ public class SearchReturningProfiledResourceDstu2Test {
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertThat(responseContent, not(containsString("html")));
assertThat(responseContent, containsString("<profile value=\"http://foo\"/>"));
assertThat(responseContent, containsString("<profile value=\"http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient\"/>"));
}
@Test
public void testProfilesGetAddedHtml() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=html");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertThat(responseContent, containsString("html"));
assertThat(responseContent, containsString("http://foo"));
assertThat(responseContent, containsString("http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient"));
}
@AfterClass
public static void afterClassClearContext() throws Exception {
ourServer.stop();
@ -102,6 +119,8 @@ public class SearchReturningProfiledResourceDstu2Test {
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer(ourCtx);
servlet.registerInterceptor(new ResponseHighlighterInterceptor());
servlet.setResourceProviders(new DummyPatientResourceProvider());
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");

View File

@ -158,6 +158,11 @@
JPA module failed to index search parameters that mapped to a Timing datatype,
e.g. CarePlan:activitydate
</action>
<action type="add">
Add a new option to the CLI run-server command called <![CDATA[<code>--lowmem</code>]]>.
This option disables some features (e.g. fulltext search) in order to allow the
server to start in memory-constrained environments (e.g Raspberry Pi)
</action>
</release>
<release version="1.5" date="2016-04-20">
<action type="fix" issue="339">