blob: 43dc58e38f2e95353bb5270e600ba368c679c106 [file] [log] [blame]
package org.eclipse.basyx.components.sqlprovider;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.eclipse.basyx.components.provider.BaseConfiguredProvider;
import org.eclipse.basyx.components.sqlprovider.driver.SQLDriver;
import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLQuery;
import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLRunner;
import org.eclipse.basyx.components.sqlprovider.query.DynamicSQLUpdate;
import org.eclipse.basyx.vab.modelprovider.lambda.VABLambdaHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Asset administration shell sub model provider that connects to SQL database
*
* @author kuhn
*
*/
public class SQLPreconfiguredSubModelProvider extends BaseConfiguredProvider {
/**
* Initiates a logger using the current class
*/
private static final Logger logger = LoggerFactory.getLogger(SQLPreconfiguredSubModelProvider.class);
/**
* SQL database user name
*/
protected String sqlUser = null;
/**
* SQL database password
*/
protected String sqlPass = null;
/**
* SQL database path
*/
protected String sqlURL = null;
/**
* SQL database driver
*/
protected String sqlDriver = null;
/**
* SQL database query prefix
*/
protected String sqlPrefix = null;
/**
* SQL property connections
*/
protected Set<String> sqlPropertyConnections = new HashSet<>();
/**
* SQL operation connections
*/
protected Set<String> sqlOperationConnections = new HashSet<>();
/**
* Run queries to access properties via 'get' operation
*/
protected Map<String, DynamicSQLRunner> propertyGetQueries = new HashMap<>();
/**
* Run SQL update to access properties via 'set' operation
*/
protected Map<String, DynamicSQLRunner> propertySetQueries = new HashMap<>();
/**
* Run SQL update to access properties via 'create' operation
*/
protected Map<String, DynamicSQLRunner> propertyCreateQueries = new HashMap<>();
/**
* Run SQL update to access properties via 'delete' operation
*/
protected Map<String, DynamicSQLRunner> propertyDeleteQueries = new HashMap<>();
/**
* SQL operations
*/
protected Map<String, DynamicSQLRunner> operations = new HashMap<>();
/**
* SQL operations that run as update operations. Not contained operations are query operations.
*/
protected Set<String> updateOperations = new HashSet<>();
/**
* An SQL driver instance to connect to the database
*/
protected SQLDriver driver;
public static final String DBUSER = "dbuser";
public static final String DBPASS = "dbpass";
public static final String DBURL = "dburl";
public static final String DRIVER = "driver";
public static final String PREFIX = "prefix";
public static final String PROPERTIES = "properties";
public static final String OPERATIONS = "operations";
/**
* Constructor
*/
public SQLPreconfiguredSubModelProvider(Properties cfgValues) {
// Call base constructor
super(cfgValues);
// Create sub model
submodelData = createSubModel(cfgValues);
// Load predefined elements from sub model
try {
setModelPropertyValue("", submodelData);
} catch (Exception e) {
e.printStackTrace();
}
// Extract SQL properties
sqlUser = cfgValues.getProperty(buildSqlCfgName(DBUSER));
sqlPass = cfgValues.getProperty(buildSqlCfgName(DBPASS));
sqlURL = cfgValues.getProperty(buildSqlCfgName(DBURL));
// Extract SQL driver properties
sqlDriver = cfgValues.getProperty(buildSqlCfgName(DRIVER));
sqlPrefix = cfgValues.getProperty(buildSqlCfgName(PREFIX));
// Create a SQL driver instance
driver = new SQLDriver(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver);
// Load and parse SQL property and operation connections
sqlPropertyConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(PROPERTIES))));
sqlOperationConnections.addAll(splitString(cfgValues.getProperty(buildSqlCfgName(OPERATIONS))));
// Add properties
for (String propertyName: sqlPropertyConnections) createSQLProperty(propertyName, cfgValues);
/*
// Try to parse parameter
propertyGetQueries.put(propertyName, createSQLOperation(propertyName+".get", cfgValues));
propertySetQueries.put(propertyName, createSQLOperation(propertyName+".set", cfgValues));
propertyCreateQueries.put(propertyName, createSQLOperation(propertyName+".create", cfgValues));
propertyDeleteQueries.put(propertyName, createSQLOperation(propertyName+".delete", cfgValues));
Map<String, Object> mapAccessors = VABLambdaProviderHelper.createMap((Supplier<?>) () -> {
return propertyMap_val;
}, (Consumer<Map<String, Object>>) (map) -> {
propertyMap_val = map;
}, (BiConsumer<String, Object>) (key, value) -> {
propertyMap_val.put(key, value);
}, (Consumer<Object>) (o) -> {
propertyMap_val.remove(o);
});
}*/
// Add operations
//for (String operationName: sqlOperationConnections) createSQLOperation(operationName, cfgValues);
/*{
// Create operation
operations.put(operationName, createSQLOperation(operationName, cfgValues));
// Mark operation as update operation depending on operations/<operationName>_kind property value
try {
if (cfgValues.getProperty(operationName+"_kind").trim().equalsIgnoreCase("update")) {
updateOperations.add(operationName);
}
} catch (Exception e) {}
}*/
}
/**
* Create an SQL property
*/
protected void createSQLProperty(String name, Properties cfgValues) {
// Create Map with lambdas that hold SQL operations
Map<String, Object> value = new HashMap<>();
// Get operation
{
// Get parameter
String queryString = cfgValues.getProperty(name+".get");
String resultFilterOp = cfgValues.getProperty(name+".get.result");
// Trim query string and resultFilterOp (remove '"' at beginning and end)
queryString = queryString.substring(1, queryString.length()-1);
try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
// Create dynamic SQL query
value.put(VABLambdaHandler.VALUE_GET_SUFFIX, new DynamicSQLQuery(driver, queryString, resultFilterOp));
}
// Set operation
{
// Get parameter
String updateString = cfgValues.getProperty(name+".set");
// Trim query string and resultFilterOp (remove '"' at beginning and end)
updateString = updateString.substring(1, updateString.length()-1);
// Create dynamic SQL query
value.put(VABLambdaHandler.VALUE_SET_SUFFIX, new DynamicSQLUpdate(driver, updateString));
}
// Delete operation
{
// Get parameter
String updateString = cfgValues.getProperty(name+".delete");
// Trim query string and resultFilterOp (remove '"' at beginning and end)
updateString = updateString.substring(1, updateString.length()-1);
// Create dynamic SQL query
value.put(VABLambdaHandler.VALUE_REMOVEKEY_SUFFIX, new DynamicSQLUpdate(driver, updateString));
value.put(VABLambdaHandler.VALUE_REMOVEOBJ_SUFFIX, new DynamicSQLUpdate(driver, updateString));
}
// Create operation
{
// Get parameter
String updateString = cfgValues.getProperty(name+".create");
// Trim query string and resultFilterOp (remove '"' at beginning and end)
updateString = updateString.substring(1, updateString.length()-1);
// Create dynamic SQL query
value.put(VABLambdaHandler.VALUE_INSERT_SUFFIX, new DynamicSQLUpdate(driver, updateString));
}
logger.debug("Putting SQL:"+name);
// Add property as map of lambdas
submodelData.getProperties().put(name, createSubmodelElement(name, value, cfgValues));
}
/**
* Create a dynamic SQL operation
*/
protected DynamicSQLRunner createSQLOperation(String propertyName, Properties cfgValues) {/*
// Check parameter presence
if (!cfgValues.containsKey(propertyName)) return null;
// Get parameter count and parameter count
int parameterCount = Integer.parseInt(cfgValues.getProperty(propertyName+".parameter"));
String queryString = cfgValues.getProperty(propertyName);
String resultFilterOp = cfgValues.getProperty(propertyName+".result");
// Trim query string and resultFilterOp (remove '"' at beginning and end)
queryString = queryString.substring(1, queryString.length()-1);
try {resultFilterOp = resultFilterOp.substring(1, resultFilterOp.length()-1);} catch (NullPointerException | StringIndexOutOfBoundsException e) {}
// Create dynamic SQL query
DynamicSQLRunner sqlQuery = new DynamicSQLRunner(sqlURL, sqlUser, sqlPass, sqlPrefix, sqlDriver, parameterCount, queryString, resultFilterOp);
// Return created query
return sqlQuery;*/
return null;
}
/**
* Split a whitespace delimited string
*/
protected Collection<String> splitString(String input) {
// Return value
HashSet<String> result = new HashSet<>();
// Split string into segments
for (String inputStr: input.split(" ")) result.add(inputStr.trim());
// Return result
return result;
}
/**
* Create a key list for an SQL statement
*//*
protected String sqlCreateKeys(Collection<String> keys) {
// Return value builder
StringBuilder result = new StringBuilder();
// Process keys
// - Flag that handles the first key
boolean isFirst = true;
// - Process keys
for (String key: keys) {if (!isFirst) result.append(","); else isFirst=false; result.append(key);}
// Return string
return result.toString();
}*/
/**
* Extract a list of values from a map
*//*
protected String sqlCreateValues(Collection<Object> values) {
// Return value builder
StringBuilder result = new StringBuilder();
// Process keys
// - Flag that handles the first key
boolean isFirst = true;
// - Process keys
for (Object key: values) {if (!isFirst) result.append(","); else isFirst=false; result.append("'"+key+"'");}
// Return string
return result.toString();
}*/
/**
* Create (insert) a value into the SQL table
*//*
@Override @SuppressWarnings("unchecked")
public void createValue(String propertyName, Object arg1) throws Exception {
// Set query
DynamicSQLRunner query = propertyCreateQueries.get(propertyName);
// Null pointer check
if (query == null) return;
// Create parameter array
Object[] parameter = new Object[2];
parameter[0] = sqlCreateKeys(((Map<String, Object>) arg1).keySet());
parameter[1] = sqlCreateValues(((Map<String, Object>) arg1).values());
// Execute query and return result
query.runUpdate(parameter);
}*/
/**
* Delete a value from the SQL table
*//*
@Override
public void deleteValue(String arg0) throws Exception {
// This is not implemented
}*/
/**
* Delete a value from the SQL table
*//*
@Override @SuppressWarnings("unchecked")
public void deleteValue(String propertyName, Object arg1) throws Exception {
// Set query
DynamicSQLRunner query = propertyDeleteQueries.get(propertyName);
// Null pointer check
if (query == null) return;
// Cast argument to collection
Collection<Object> parameterList = (Collection<Object>) arg1;
// Create parameter array
Object[] parameter = new Object[parameterList.size()];
// - Copy parameter
int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
// Execute query and return result
query.runUpdate(parameter);
}*/
/*
@Override
public Map<String, IElementReference> getContainedElements(String arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getElementScope(String arg0) {
logger.debug("GetScope:"+arg0);
// TODO Auto-generated method stub
return null;
}
*/
/**
* Query the SQL database
*//*
@Override
public Object getModelPropertyValue(String propertyName) {
// Get query
DynamicSQLRunner query = propertyGetQueries.get(propertyName);
// Null pointer check
if (query == null) return null;
// Execute query and return result
return query.runQuery();
}*/
/**
* Invoke operation with given parameter list
*//*
@Override
public Object invokeOperation(String propertyName, Object[] parameter) throws Exception {
// Set query
DynamicSQLRunner query = operations.get(propertyName);
// Null pointer check
if (query == null) return null;
// Execute query and return result
if (updateOperations.contains(propertyName)) {
query.runUpdate(parameter);
return null;
} else {
return query.runQuery(parameter);
}
}*/
/**
* Invoke set operation with given parameter
*//*
@Override @SuppressWarnings("unchecked")
public void setModelPropertyValue(String propertyName, Object arg1) throws Exception {
// Set query
DynamicSQLRunner query = propertySetQueries.get(propertyName);
// Null pointer check
if (query == null) return;
logger.debug("LENC:"+arg1);
// Create parameter array
Object[] parameter = null;
// - Process collections
if (arg1 instanceof Collection) {
// Cast to collection
Collection<Object> parameterList = (Collection<Object>) arg1;
// Create parameter array and copy parameter
parameter = new Object[parameterList.size()];
int counter = 0; for (Object par: parameterList) parameter[counter++] = par;
} else {
// Create parameter array and copy parameter
parameter = new Object[1];
parameter[0] = arg1;
}
// Execute query and return result
query.runUpdate(parameter);
}*/
/**
* Invoke set operation with given parameter list
*//*
@Override
public void setModelPropertyValue(String propertyName, Object... parameter) throws Exception {
// Set query
DynamicSQLRunner query = propertySetQueries.get(propertyName);
// Null pointer check
if (query == null) return;
logger.debug("LEN:"+parameter.length);
logger.debug("LEN-0:"+parameter[0]);
// Execute query and return result
query.runUpdate(parameter);
}*/
public static String buildSqlCfgName(String valueName) {
return BaseConfiguredProvider.buildCfgName("basyx.sql", valueName);
}
}