From a0f3e8c717f74669e500e1e3c73194555b76405d Mon Sep 17 00:00:00 2001 From: Eugene Lubarsky Date: Thu, 13 Jul 2017 01:03:05 +1000 Subject: [PATCH] CLI: command-line option to turn off or configure reuse of search results --- .../ca/uhn/fhir/cli/RunServerCommand.java | 27 ++++++++++++++++++- .../ca/uhn/fhir/jpa/demo/ContextHolder.java | 13 +++++++++ .../ca/uhn/fhir/jpa/demo/JpaServerDemo.java | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java b/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java index 2e70ad9ad9e..7e89d0d816f 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java +++ b/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java @@ -21,6 +21,7 @@ import org.springframework.web.context.ContextLoader; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.demo.ContextHolder; import ca.uhn.fhir.jpa.demo.FhirServerConfig; import ca.uhn.fhir.jpa.demo.FhirServerConfigDstu3; @@ -30,6 +31,7 @@ public class RunServerCommand extends BaseCommand { private static final String OPTION_DISABLE_REFERENTIAL_INTEGRITY = "disable-referential-integrity"; private static final String OPTION_LOWMEM = "lowmem"; private static final String OPTION_ALLOW_EXTERNAL_REFS = "allow-external-refs"; + private static final String OPTION_REUSE_SEARCH_RESULTS_MILLIS = "reuse-search-results-milliseconds"; private static final int DEFAULT_PORT = 8080; private static final String OPTION_P = "p"; @@ -51,6 +53,10 @@ public class RunServerCommand extends BaseCommand { options.addOption(null, OPTION_LOWMEM, false, "If this flag is set, the server will operate in low memory mode (some features disabled)"); options.addOption(null, OPTION_ALLOW_EXTERNAL_REFS, false, "If this flag is set, the server will allow resources to be persisted contaning external resource references"); options.addOption(null, OPTION_DISABLE_REFERENTIAL_INTEGRITY, false, "If this flag is set, the server will not enforce referential integrity"); + + Long defaultReuseSearchResults = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS; + String defaultReuseSearchResultsStr = defaultReuseSearchResults == null ? "off" : String.valueOf(defaultReuseSearchResults); + options.addOption(null, OPTION_REUSE_SEARCH_RESULTS_MILLIS, true, "The time in milliseconds within which the same results will be returned for multiple identical searches, or \"off\" (default is " + defaultReuseSearchResultsStr + ")"); return options; } @@ -58,7 +64,7 @@ public class RunServerCommand extends BaseCommand { try { return Integer.parseInt(theCommandLine.getOptionValue(opt, Integer.toString(defaultPort))); } catch (NumberFormatException e) { - throw new ParseException("Invalid value '" + theCommandLine.getOptionValue(opt) + " (must be numeric)"); + throw new ParseException("Invalid value '" + theCommandLine.getOptionValue(opt) + "' (must be numeric)"); } } @@ -81,6 +87,25 @@ public class RunServerCommand extends BaseCommand { ContextHolder.setDisableReferentialIntegrity(true); } + String reuseSearchResults = theCommandLine.getOptionValue(OPTION_REUSE_SEARCH_RESULTS_MILLIS); + if (reuseSearchResults != null) { + if (reuseSearchResults.equals("off")) { + ourLog.info("Server is configured to not reuse search results"); + ContextHolder.setReuseCachedSearchResultsForMillis(null); + } else { + try { + long reuseSearchResultsMillis = Long.parseLong(reuseSearchResults); + if (reuseSearchResultsMillis < 0) { + throw new NumberFormatException("expected a positive integer"); + } + ourLog.info("Server is configured to reuse search results for " + String.valueOf(reuseSearchResultsMillis) + " milliseconds"); + ContextHolder.setReuseCachedSearchResultsForMillis(reuseSearchResultsMillis); + } catch (NumberFormatException e) { + throw new ParseException("Invalid value '" + reuseSearchResults + "' (must be a positive integer)"); + } + } + } + ContextHolder.setCtx(getSpecVersionContext(theCommandLine)); ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort); diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java index 5675424db19..345b3259c9d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java @@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.demo; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.Validate; +import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.context.FhirContext; public class ContextHolder { @@ -11,6 +12,11 @@ public class ContextHolder { private static FhirContext ourCtx; private static boolean ourDisableReferentialIntegrity; private static String ourPath; + private static Long ourReuseSearchResultsMillis; + + static { + ourReuseSearchResultsMillis = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS; + } public static FhirContext getCtx() { Validate.notNull(ourPath, "Context not set"); @@ -53,4 +59,11 @@ public class ContextHolder { ourDisableReferentialIntegrity = theDisableReferentialIntegrity; } + public static void setReuseCachedSearchResultsForMillis(Long reuseSearchResultsMillis) { + ourReuseSearchResultsMillis = reuseSearchResultsMillis; + } + + public static Long getReuseCachedSearchResultsForMillis() { + return ourReuseSearchResultsMillis; + } } diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java index 18ccf90f5e3..11407999a08 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java @@ -170,7 +170,7 @@ public class JpaServerDemo extends RestfulServer { daoConfig.setAllowExternalReferences(ContextHolder.isAllowExternalRefs()); daoConfig.setEnforceReferentialIntegrityOnDelete(!ContextHolder.isDisableReferentialIntegrity()); daoConfig.setEnforceReferentialIntegrityOnWrite(!ContextHolder.isDisableReferentialIntegrity()); - + daoConfig.setReuseCachedSearchResultsForMillis(ContextHolder.getReuseCachedSearchResultsForMillis()); } }