From c3cc03b51c4322b3006353bd3a02e2c8aa9c1178 Mon Sep 17 00:00:00 2001 From: Mark Hanes Date: Tue, 25 Oct 2016 09:20:20 -0400 Subject: [PATCH] 0002878: Provide for BSH scripting when reading properties files --- .../symmetric/AbstractSymmetricEngine.java | 22 ++- .../db/AbstractSymmetricDialect.java | 2 +- .../impl/AbstractParameterService.java | 152 ++++++++++++++++-- 3 files changed, 154 insertions(+), 22 deletions(-) diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java index 39d5313b43..9116d6257a 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/AbstractSymmetricEngine.java @@ -280,8 +280,10 @@ protected void init() { TypedProperties properties = this.propertiesFactory.reload(); - MDC.put("engineName", properties.get(ParameterConstants.ENGINE_NAME)); - + String engineName = properties.get(ParameterConstants.ENGINE_NAME); + if (!StringUtils.contains(engineName, '`') && !StringUtils.contains(engineName, '(')) { + MDC.put("engineName", engineName); + } this.platform = createDatabasePlatform(properties); this.parameterService = new ParameterService(platform, propertiesFactory, @@ -293,7 +295,17 @@ protected void init() { this.parameterService.setDatabaseHasBeenInitialized(true); this.parameterService.rereadParameters(); } - + + // So that the key properties are initialized in a predictable order + + parameterService.getNodeGroupId(); + parameterService.getExternalId(); + parameterService.getEngineName(); + parameterService.getSyncUrl(); + parameterService.getRegistrationUrl(); + + MDC.put("engineName", parameterService.getEngineName()); + this.platform.setMetadataIgnoreCase(this.parameterService .is(ParameterConstants.DB_METADATA_IGNORE_CASE)); this.platform.setClearCacheModelTimeoutInMs(parameterService @@ -403,7 +415,7 @@ public Properties getProperties() { } public String getEngineName() { - return parameterService.getString(ParameterConstants.ENGINE_NAME); + return parameterService.getEngineName(); } public void setup() { @@ -969,7 +981,7 @@ public IDataExtractorService getDataExtractorService() { public IDataExtractorService getFileSyncExtractorService() { return this.fileSyncExtractorService; } - + public IDataLoaderService getDataLoaderService() { return this.dataLoaderService; } diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java index 10468f6597..79869791b0 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java @@ -659,7 +659,7 @@ public boolean isTransactionIdOverrideSupported() { } public String getEngineName() { - return parameterService.getString(ParameterConstants.ENGINE_NAME); + return parameterService.getEngineName(); } public boolean supportsOpenCursorsAcrossCommit() { diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/AbstractParameterService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/AbstractParameterService.java index c1f64fd410..1df7d5178c 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/AbstractParameterService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/AbstractParameterService.java @@ -37,6 +37,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import bsh.EvalError; +import bsh.Interpreter; + abstract public class AbstractParameterService { protected final Logger log = LoggerFactory.getLogger(getClass()); @@ -53,6 +56,16 @@ abstract public class AbstractParameterService { protected boolean databaseHasBeenInitialized = false; + protected String externalId=null; + + protected String engineName=null; + + protected String nodeGroupId=null; + + protected String syncUrl=null; + + protected String registrationUrl=null; + public AbstractParameterService() { this.systemProperties = (Properties) System.getProperties().clone(); } @@ -177,37 +190,85 @@ public Date getLastTimeParameterWereCached() { return new Date(lastTimeParameterWereCached); } + public String getExternalId() { - return substituteVariables(ParameterConstants.EXTERNAL_ID); + if (externalId==null) { + String value = getString(ParameterConstants.EXTERNAL_ID); + value = substituteScripts(value); + externalId = substituteVariablesFromValue(value); + if (log.isDebugEnabled()) { + log.debug("External Id eval results in: {}",externalId); + } + } + return externalId; } public String getSyncUrl() { - return substituteVariables(ParameterConstants.SYNC_URL); + if (syncUrl==null) { + String value = getString(ParameterConstants.SYNC_URL); + value = substituteScripts(value); + value = substituteVariablesFromValue(value); + if (value != null) { + value = value.trim(); + } + syncUrl = value; + if (log.isDebugEnabled()) { + log.debug("Sync URL eval results in: {}",syncUrl); + } + } + return syncUrl; } public String getNodeGroupId() { - return getString(ParameterConstants.NODE_GROUP_ID); + if (nodeGroupId==null) { + String value = getString(ParameterConstants.NODE_GROUP_ID); + value = substituteScripts(value); + nodeGroupId = substituteVariablesFromValue(value); + if (log.isDebugEnabled()) { + log.debug("Node Group Id eval results in: {}",nodeGroupId); + } + } + return nodeGroupId; } public String getRegistrationUrl() { - String url = substituteVariables(ParameterConstants.REGISTRATION_URL); - if (url != null) { - url = url.trim(); + if (registrationUrl==null) { + String value = getString(ParameterConstants.REGISTRATION_URL); + value = substituteScripts(value); + value = substituteVariablesFromValue(value); + if (value != null) { + value = value.trim(); + } + registrationUrl=value; + if (log.isDebugEnabled()) { + log.debug("Registration URL eval results in: {}",registrationUrl); + } + } + return registrationUrl; + } + + public String getEngineName() { + if (engineName==null) { + String value = getString(ParameterConstants.ENGINE_NAME,"SymmetricDS"); + value = substituteScripts(value); + engineName = substituteVariablesFromValue(value); + if (log.isDebugEnabled()) { + log.debug("Engine Name eval results in: {}",engineName); + } } - return url; + return engineName; } public Map getReplacementValues() { Map replacementValues = new HashMap(2); - replacementValues.put("externalId", getExternalId()); replacementValues.put("nodeGroupId", getNodeGroupId()); + replacementValues.put("externalId", getExternalId()); + replacementValues.put("engineName", getEngineName()); + replacementValues.put("syncUrl", getSyncUrl()); + replacementValues.put("registrationUrl", getRegistrationUrl()); return replacementValues; } - - public String getEngineName() { - return getString(ParameterConstants.ENGINE_NAME, "SymmetricDS"); - } - + public void setDatabaseHasBeenInitialized(boolean databaseHasBeenInitialized) { if (this.databaseHasBeenInitialized != databaseHasBeenInitialized) { this.databaseHasBeenInitialized = databaseHasBeenInitialized; @@ -232,9 +293,8 @@ protected TypedProperties rereadDatabaseParameters(Properties p) { return new TypedProperties(); } } - - protected String substituteVariables(String paramKey) { - String value = getString(paramKey); + + protected String substituteVariablesFromValue(String value) { if (!StringUtils.isBlank(value)) { if (value.contains("hostName")) { value = FormatUtils.replace("hostName", AppUtils.getHostName(), value); @@ -248,6 +308,18 @@ protected String substituteVariables(String paramKey) { if (value.contains("engineName")) { value = FormatUtils.replace("engineName", getEngineName(), value); } + if (value.contains("nodeGroupId")) { + value = FormatUtils.replace("nodeGroupId", getNodeGroupId(), value); + } + if (value.contains("externalId")) { + value = FormatUtils.replace("externalId", getExternalId(), value); + } + if (value.contains("syncUrl")) { + value = FormatUtils.replace("syncUrl", getSyncUrl(), value); + } + if (value.contains("registrationUrl")) { + value = FormatUtils.replace("registrationUrl", getRegistrationUrl(), value); + } } return value; } @@ -256,4 +328,52 @@ public void setExtensionService(IExtensionService extensionService) { this.extensionService = extensionService; } + + protected String substituteScripts(String value) { + if (log.isDebugEnabled()) { + log.debug("substituteScripts starting value is: {}",value); + } + int startTick = StringUtils.indexOf(value, '`'); + if (startTick!=-1) { + int endTick = StringUtils.lastIndexOf(value, '`'); + if (endTick!=-1 && startTick!=endTick) { + // there's a bean shell script present in this case + String script = StringUtils.substring(value, startTick+1,endTick); + if (log.isDebugEnabled()) { + log.debug("Script found. Script is is: {}",script); + } + + Interpreter interpreter = new Interpreter(); + try { + interpreter.set("hostName", AppUtils.getHostName()); + interpreter.set("log", log); + interpreter.set("nodeGroupId", nodeGroupId); + interpreter.set("syncUrl", syncUrl); + interpreter.set("registrationUrl", registrationUrl); + interpreter.set("externalId", externalId); + interpreter.set("engineName", engineName); + + Object scriptResult = interpreter.eval(script); + + if (scriptResult==null) { + scriptResult =""; + } + + if (log.isDebugEnabled()) { + log.debug("Script output is: {}",scriptResult); + } + value = StringUtils.substring(value, 0,startTick) + scriptResult.toString() + + StringUtils.substring(value, endTick+1); + } catch (EvalError e) { + throw new RuntimeException(e.getMessage(),e); + } + + if (log.isDebugEnabled()) { + log.debug("substituteScripts return value is {}",value); + } + } + } + return value; + } + } \ No newline at end of file