aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Tabedzki <richard.tabedzki@att.com>2019-03-22 11:01:50 -0400
committerRich Tabedzki <richard.tabedzki@att.com>2019-03-22 15:21:13 -0400
commit88c5e41c5d3115521b24800b7be4e8bd77a27fc1 (patch)
tree22f31f0ceacd8083d5ae90ebfc2e3d0b7dd05d2f
parent8957d8eadb42547acdc4235cbfcf7468b4e2e876 (diff)
Support system variables in property values
Changes made: * Added code in DBResourceManager to replace with its value * Expanded debug statement by adding processing time Change-Id: I22748daed50063e8e0ac7201e88d69a2609c1788 Issue-ID: CCSDK-1133 Signed-off-by: Rich Tabedzki <richard.tabedzki@att.com>
-rwxr-xr-xdblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/CachedDataSource.java41
-rwxr-xr-xdblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/DBResourceManager.java104
-rwxr-xr-xdblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/TerminatingCachedDataSource.java7
3 files changed, 127 insertions, 25 deletions
diff --git a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/CachedDataSource.java b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/CachedDataSource.java
index bc466d93..b9a0f071 100755
--- a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/CachedDataSource.java
+++ b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/CachedDataSource.java
@@ -33,6 +33,7 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Observer;
import javax.sql.DataSource;
@@ -59,7 +60,7 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
private static final Logger LOGGER = LoggerFactory.getLogger(CachedDataSource.class);
private static final String SQL_FAILURE = "SQL FAILURE. time(ms): ";
- private static final String FAILED_TO_EXECUTE = "> failed to execute: ";
+ private static final String FAILED_TO_EXECUTE = "> Failed to execute: ";
private static final String WITH_ARGUMENTS = " with arguments: ";
private static final String WITH_NO_ARGUMENTS = " with no arguments. ";
private static final String DATA_SOURCE_CONNECT_SUCCESS = "SQL DataSource < {} > connected to {}, read-only is {}, tested successfully";
@@ -82,12 +83,13 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
private long nextErrorReportTime = 0L;
private String globalHostName = null;
+ private final int index;
private boolean isDerby = false;
public CachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException {
ds = configure(jdbcElem);
-
+ index = initializeIndex(jdbcElem);
if ("org.apache.derby.jdbc.EmbeddedDriver".equals(jdbcElem.getDriverName())) {
isDerby = true;
}
@@ -97,6 +99,16 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
protected abstract DataSource configure(BaseDBConfiguration jdbcElem) throws DBConfigException;
protected abstract int getAvailableConnections();
+ protected int initializeIndex(BaseDBConfiguration jdbcElem) {
+ if(jdbcElem.containsKey(BaseDBConfiguration.DATABASE_HOSTS)) {
+ String hosts = jdbcElem.getProperty(BaseDBConfiguration.DATABASE_HOSTS);
+ String name = jdbcElem.getProperty(BaseDBConfiguration.CONNECTION_NAME);
+ List<String> numbers = Arrays.asList(hosts.split(","));
+ return numbers.indexOf(name);
+ } else
+ return -1;
+ }
+
/*
* (non-Javadoc)
*
@@ -104,7 +116,14 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
*/
@Override
public Connection getConnection() throws SQLException {
+ LapsedTimer lt = new LapsedTimer();
+ try {
return ds.getConnection();
+ } finally {
+ if(LOGGER.isTraceEnabled()) {
+ LOGGER.trace(String.format("SQL Connection aquisition time : %s", lt.lapsedTime()));
+ }
+ }
}
public CachedRowSet getData(String statement, List<Object> arguments) throws SQLException {
@@ -397,6 +416,10 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
monitor.deleteObserver(observer);
}
+ public int getIndex() {
+ return index;
+ }
+
@Override
public long getInterval() {
return interval;
@@ -487,9 +510,9 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
isSlave = true;
}
if (isSlave) {
- LOGGER.debug("SQL SLAVE : {} on server {}, pool {}", connectionName, hostname, getAvailableConnections());
+ LOGGER.debug("SQL SLAVE : {} on server {}, pool {}", connectionName, getDbConnectionName(), getAvailableConnections());
} else {
- LOGGER.debug("SQL MASTER : {} on server {}, pool {}", connectionName, hostname, getAvailableConnections());
+ LOGGER.debug("SQL MASTER : {} on server {}, pool {}", connectionName, getDbConnectionName(), getAvailableConnections());
}
return isSlave;
}
@@ -557,4 +580,14 @@ public abstract class CachedDataSource implements DataSource, SQLExecutionMonito
public String getGlobalHostName() {
return globalHostName;
}
+
+ static class LapsedTimer {
+ private final long msTime = System.currentTimeMillis();
+
+ public String lapsedTime() {
+ double timediff = System.currentTimeMillis() - msTime;
+ timediff = timediff/1000;
+ return String.valueOf( timediff)+"s";
+ }
+ }
}
diff --git a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/DBResourceManager.java b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/DBResourceManager.java
index 236bce6e..7c71bcc8 100755
--- a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/DBResourceManager.java
+++ b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/DBResourceManager.java
@@ -35,6 +35,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Map;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Observable;
@@ -44,6 +45,7 @@ import java.util.SortedSet;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.stream.Collectors;
import javax.sql.DataSource;
import javax.sql.rowset.CachedRowSet;
@@ -66,7 +68,8 @@ import org.slf4j.LoggerFactory;
* Rich Tabedzki
*/
public class DBResourceManager implements DataSource, DataAccessor, DBResourceObserver, DbLibService {
- private static Logger LOGGER = LoggerFactory.getLogger(DBResourceManager.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DBResourceManager.class);
+ private static final String DATABASE_URL = "org.onap.ccsdk.sli.jdbc.url";
transient boolean terminating = false;
transient protected long retryInterval = 10000L;
@@ -92,8 +95,8 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
}
public DBResourceManager(final Properties properties) {
- this.configProps = properties;
-
+ this.configProps = processSystemVariables(properties);
+
// TODO : hack to force classloader to cache mariadb driver. This shouldnt be necessary,
// but for some reason it is (without this, dblib throws ClassNotFound on mariadb driver
// and fails to load).
@@ -102,26 +105,26 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
dvr = null;
// get retry interval value
- retryInterval = getLongFromProperties(properties, "org.onap.dblib.connection.retry", 10000L);
+ retryInterval = getLongFromProperties(configProps, "org.onap.dblib.connection.retry", 10000L);
// get recovery mode flag
- recoveryMode = getBooleanFromProperties(properties, "org.onap.dblib.connection.recovery", true);
+ recoveryMode = getBooleanFromProperties(configProps, "org.onap.dblib.connection.recovery", true);
if(!recoveryMode)
{
recoveryMode = false;
LOGGER.info("Recovery Mode disabled");
}
// get time out value for thread cleanup
- terminationTimeOut = getLongFromProperties(properties, "org.onap.dblib.termination.timeout", 300000L);
+ terminationTimeOut = getLongFromProperties(configProps, "org.onap.dblib.termination.timeout", 300000L);
// get properties for monitoring
- monitorDbResponse = getBooleanFromProperties(properties, "org.onap.dblib.connection.monitor", false);
- monitoringInterval = getLongFromProperties(properties, "org.onap.dblib.connection.monitor.interval", 1000L);
- monitoringInitialDelay = getLongFromProperties(properties, "org.onap.dblib.connection.monitor.startdelay", 5000L);
- expectedCompletionTime = getLongFromProperties(properties, "org.onap.dblib.connection.monitor.expectedcompletiontime", 5000L);
- unprocessedFailoverThreshold = getLongFromProperties(properties, "org.onap.dblib.connection.monitor.unprocessedfailoverthreshold", 3L);
+ monitorDbResponse = getBooleanFromProperties(configProps, "org.onap.dblib.connection.monitor", false);
+ monitoringInterval = getLongFromProperties(configProps, "org.onap.dblib.connection.monitor.interval", 1000L);
+ monitoringInitialDelay = getLongFromProperties(configProps, "org.onap.dblib.connection.monitor.startdelay", 5000L);
+ expectedCompletionTime = getLongFromProperties(configProps, "org.onap.dblib.connection.monitor.expectedcompletiontime", 5000L);
+ unprocessedFailoverThreshold = getLongFromProperties(configProps, "org.onap.dblib.connection.monitor.unprocessedfailoverthreshold", 3L);
// initialize performance monitor
- PollingWorker.createInistance(properties);
+ PollingWorker.createInistance(configProps);
// initialize recovery thread
worker = new RecoveryMgr();
@@ -130,13 +133,49 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
worker.start();
try {
- this.config(properties);
+ this.config(configProps);
} catch (final Exception e) {
// TODO: config throws <code>Exception</code> which is poor practice. Eliminate this in a separate patch.
LOGGER.error("Fatal Exception encountered while configuring DBResourceManager", e);
}
}
+ public static Properties processSystemVariables(Properties properties) {
+ Map<Object, Object> hmap = new Properties();
+ hmap.putAll(properties);
+
+ Map<Object, Object> result = hmap.entrySet().stream()
+ .filter(map -> map.getValue().toString().startsWith("${"))
+ .filter(map -> map.getValue().toString().endsWith("}"))
+ .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
+
+ result.forEach((name, propEntries) -> {
+ hmap.put(name, replace(propEntries.toString()));
+ });
+
+ if(hmap.containsKey(DATABASE_URL) && hmap.get(DATABASE_URL).toString().contains("${")) {
+ String url = hmap.get(DATABASE_URL).toString();
+ String[] innerChunks = url.split("\\$\\{");
+ for(String chunk : innerChunks) {
+ if(chunk.contains("}")) {
+ String subChunk = chunk.substring(0, chunk.indexOf("}"));
+ String varValue = System.getenv(subChunk);
+ url = url.replace("${"+subChunk+"}", varValue);
+ }
+ }
+ hmap.put(DATABASE_URL, url);
+ }
+ return Properties.class.cast(hmap);
+ }
+
+
+ private static String replace(String value) {
+ String globalVariable = value.substring(2, value.length() -1);
+ String varValue = System.getenv(globalVariable);
+ return (varValue != null) ? varValue : value;
+ }
+
+
private void config(Properties configProps) throws Exception {
final ConcurrentLinkedQueue<CachedDataSource> semaphore = new ConcurrentLinkedQueue<>();
final DbConfigPool dbConfig = DBConfigFactory.createConfig(configProps);
@@ -204,11 +243,33 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
return -1;
}
- if(!left.isSlave())
+ boolean leftMaster = !left.isSlave();
+ if(leftMaster) {
+ if(left.getIndex() <= right.getIndex())
+ return -1;
+ else {
+ boolean rightMaster = !right.isSlave();
+ if(rightMaster) {
+ if(left.getIndex() <= right.getIndex())
+ return -1;
+// if(left.getIndex() > right.getIndex())
+ else {
+ return 1;
+ }
+ } else {
return -1;
+ }
+ }
+ }
if(!right.isSlave())
return 1;
+ if(left.getIndex() <= right.getIndex())
+ return -1;
+ if(left.getIndex() > right.getIndex())
+ return 1;
+
+
} catch (Throwable e) {
LOGGER.warn("", e);
}
@@ -440,12 +501,12 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
}
}
lastException = exc;
- LOGGER.error("Generated alarm: "+active.getDbConnectionName(), exc);
+ LOGGER.error("Generated alarm: {}", active.getDbConnectionName(), exc);
handleGetConnectionException(active, exc);
} finally {
if(LOGGER.isDebugEnabled()){
time = System.currentTimeMillis() - time;
- LOGGER.debug("getData processing time : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ LOGGER.debug("getData processing time : {} {} miliseconds.", active.getDbConnectionName(), time);
}
}
}
@@ -490,7 +551,7 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
String message = exc.getMessage();
if(message == null)
message = exc.getClass().getName();
- LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ LOGGER.error("Generated alarm: {} - {}",active.getDbConnectionName(), message);
if(exc instanceof SQLException)
throw (SQLException)exc;
else {
@@ -501,7 +562,7 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
} finally {
if(LOGGER.isDebugEnabled()){
time = System.currentTimeMillis() - time;
- LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ LOGGER.debug(">> getData : {} {} miliseconds.", active.getDbConnectionName(), time);
}
}
}
@@ -570,12 +631,12 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
String message = exc.getMessage();
if(message == null)
message = exc.getClass().getName();
- LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ LOGGER.error("Generated alarm: {} - {}", active.getDbConnectionName(), message);
if(exc instanceof SQLException) {
SQLException sqlExc = SQLException.class.cast(exc);
// handle read-only exception
if(sqlExc.getErrorCode() == 1290 && "HY000".equals(sqlExc.getSQLState())) {
- LOGGER.warn("retrying due to: " + sqlExc.getMessage());
+ LOGGER.warn("retrying due to: {}", sqlExc.getMessage());
this.findMaster();
if(retryAllowed){
retryAllowed = false;
@@ -592,7 +653,7 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
} finally {
if(LOGGER.isDebugEnabled()){
time = System.currentTimeMillis() - time;
- LOGGER.debug("writeData processing time : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ LOGGER.debug("writeData processing time : {} {} miliseconds.", active.getDbConnectionName(), time);
}
}
}
@@ -626,6 +687,7 @@ public class DBResourceManager implements DataSource, DataAccessor, DBResourceOb
if(!active.isFabric()) {
if(this.dsQueue.size() > 1 && active.isSlave()) {
+ LOGGER.debug("Forcing reorder on: {}", dsQueue.toString());
CachedDataSource master = findMaster();
if(master != null) {
active = master;
diff --git a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/TerminatingCachedDataSource.java b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/TerminatingCachedDataSource.java
index 884f8882..852dda3c 100755
--- a/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/TerminatingCachedDataSource.java
+++ b/dblib/provider/src/main/java/org/onap/ccsdk/sli/core/dblib/TerminatingCachedDataSource.java
@@ -30,6 +30,7 @@ import org.onap.ccsdk.sli.core.dblib.pm.SQLExecutionMonitorObserver;
public class TerminatingCachedDataSource extends CachedDataSource implements SQLExecutionMonitorObserver {
private static final int DEFAULT_AVAILABLE_CONNECTIONS = 0;
+ private static final int DEFAULT_INDEX = -1;
public TerminatingCachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException {
super(jdbcElem);
@@ -49,4 +50,10 @@ public class TerminatingCachedDataSource extends CachedDataSource implements SQL
protected int getAvailableConnections() {
return DEFAULT_AVAILABLE_CONNECTIONS;
}
+
+ @Override
+ protected int initializeIndex(BaseDBConfiguration jdbcElem) {
+ return DEFAULT_INDEX;
+ }
+
}