Refactored Application-Mgt Database access layer.

4.x.x
Harshan Liyanage 8 years ago
parent 2c1500818d
commit 9dde786705

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.application.mgt.common.exception;
public class DBConnectionException extends Exception {
private static final long serialVersionUID = -3151279331929070297L;
public DBConnectionException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public DBConnectionException(String message, Throwable cause) {
super(message, cause);
}
public DBConnectionException(String msg) {
super(msg);
}
public DBConnectionException() {
super();
}
public DBConnectionException(Throwable cause) {
super(cause);
}
}

@ -20,182 +20,39 @@ package org.wso2.carbon.device.application.mgt.core.dao.common;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.exception.IllegalTransactionStateException;
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.UnsupportedDatabaseEngineException;
import org.wso2.carbon.device.application.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.application.mgt.core.config.datasource.JNDILookupDefinition;
import org.wso2.carbon.device.application.mgt.core.dao.impl.GenericAppManagementDAO;
import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagerConstants;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil.DatabaseType;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.List;
public class ApplicationManagementDAOFactory {
public static final String H2 = "H2";
private DatabaseType databaseType;
private static DataSource dataSource;
private static String databaseEngine;
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<Connection>();
private static final Log log = LogFactory.getLog(ApplicationManagementDAOFactory.class);
public ApplicationManagementDAOFactory(DataSourceConfig dataSourceConfig) {
dataSource = ConnectionManagerUtil.resolveDataSource(dataSourceConfig);
ConnectionManagerUtil.setDataSource(dataSource);
String databaseEngine = H2;
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
this.databaseType = DatabaseType.lookup(databaseEngine);
}
public ApplicationManagementDAO getApplicationManagementDAO(){
switch (databaseType) {
default:
return new GenericAppManagementDAO();
public static ApplicationManagementDAO getApplicationManagementDAO(){
if (databaseEngine != null) {
switch (databaseEngine) {
case ApplicationManagerConstants.DataBaseTypes.DB_TYPE_H2:
case ApplicationManagerConstants.DataBaseTypes.DB_TYPE_MYSQL:
return new GenericAppManagementDAO();
default:
throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine);
}
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
public static void init(DataSourceConfig config) {
dataSource = resolveDataSource(config);
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
ConnectionManagerUtil.resolveDataSource(config);
databaseEngine = ConnectionManagerUtil.getDatabaseType();
}
public static void init(DataSource dtSource) {
dataSource = dtSource;
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
public static void beginTransaction() throws TransactionManagementException {
Connection conn = currentConnection.get();
if (conn != null) {
throw new IllegalTransactionStateException("A transaction is already active within the context of " +
"this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " +
"transaction is already active is a sign of improper transaction handling");
}
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
currentConnection.set(conn);
} catch (SQLException e) {
throw new TransactionManagementException("Error occurred while retrieving config.datasource connection", e);
}
}
public static void openConnection() throws SQLException {
Connection conn = currentConnection.get();
if (conn != null) {
throw new IllegalTransactionStateException("A transaction is already active within the context of " +
"this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " +
"transaction is already active is a sign of improper transaction handling");
}
conn = dataSource.getConnection();
currentConnection.set(conn);
}
public static Connection getConnection() throws SQLException {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
return conn;
}
public static void commitTransaction() {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
try {
conn.commit();
} catch (SQLException e) {
log.error("Error occurred while committing the transaction", e);
}
}
public static void rollbackTransaction() {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
try {
conn.rollback();
} catch (SQLException e) {
log.warn("Error occurred while roll-backing the transaction", e);
}
}
public static void closeConnection() {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
try {
conn.close();
} catch (SQLException e) {
log.warn("Error occurred while close the connection");
}
currentConnection.remove();
}
/**
* Resolve data source from the data source definition
*
* @param config data source configuration
* @return data source resolved from the data source definition
*/
private static DataSource resolveDataSource(DataSourceConfig config) {
DataSource dataSource = null;
if (config == null) {
throw new RuntimeException(
"Device Management Repository data source configuration " + "is null and " +
"thus, is not initialized");
}
JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition();
if (jndiConfig != null) {
if (log.isDebugEnabled()) {
log.debug("Initializing Device Management Repository data source using the JNDI " +
"Lookup Definition");
}
List<JNDILookupDefinition.JNDIProperty> jndiPropertyList =
jndiConfig.getJndiProperties();
if (jndiPropertyList != null) {
Hashtable<Object, Object> jndiProperties = new Hashtable<Object, Object>();
for (JNDILookupDefinition.JNDIProperty prop : jndiPropertyList) {
jndiProperties.put(prop.getName(), prop.getValue());
}
dataSource = ApplicationManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), jndiProperties);
} else {
dataSource = ApplicationManagementDAOUtil.lookupDataSource(jndiConfig.getJndiName(), null);
}
}
return dataSource;
ConnectionManagerUtil.setDataSource(dtSource);
databaseEngine = ConnectionManagerUtil.getDatabaseType();
}
}

@ -25,6 +25,8 @@ import org.json.JSONException;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.Platform;
import org.wso2.carbon.device.application.mgt.common.Category;
import org.wso2.carbon.device.application.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.application.mgt.core.config.datasource.JNDILookupDefinition;
import javax.naming.InitialContext;
import javax.sql.DataSource;
@ -103,17 +105,4 @@ public class ApplicationManagementDAOUtil {
}
return list;
}
public static DataSource lookupDataSource(String dataSourceName,
final Hashtable<Object, Object> jndiProperties) {
try {
if (jndiProperties == null || jndiProperties.isEmpty()) {
return (DataSource) InitialContext.doLookup(dataSourceName);
}
final InitialContext context = new InitialContext(jndiProperties);
return (DataSource) context.lookup(dataSourceName);
} catch (Exception e) {
throw new RuntimeException("Error in looking up data source: " + e.getMessage(), e);
}
}
}
}

@ -21,8 +21,10 @@ package org.wso2.carbon.device.application.mgt.core.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAO;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOException;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOUtil;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
@ -71,7 +73,7 @@ public class GenericAppManagementDAO implements ApplicationManagementDAO {
try {
conn = ConnectionManagerUtil.getCurrentConnection().get();
conn = this.getConnection();
sql += "SELECT SQL_CALC_FOUND_ROWS APP.*, APL.NAME AS APL_NAME, APL.IDENTIFIER AS APL_IDENTIFIER," +
" CAT.NAME AS CAT_NAME ";
@ -130,6 +132,8 @@ public class GenericAppManagementDAO implements ApplicationManagementDAO {
throw new ApplicationManagementDAOException("Error occurred while getting application List", e);
} catch (JSONException e) {
throw new ApplicationManagementDAOException("Error occurred while parsing JSON", e);
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} finally {
ApplicationManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -146,4 +150,8 @@ public class GenericAppManagementDAO implements ApplicationManagementDAO {
public void deleteApplication(Application application) throws ApplicationManagementDAOException {
}
private Connection getConnection() throws DBConnectionException {
return ConnectionManagerUtil.getConnection();
}
}

@ -26,7 +26,6 @@ public class ApplicationManagementDataHolder {
private DeviceManagementProviderService deviceManagementService;
private ApplicationManagementService applicationManagementService;
private ApplicationManagementDAO applicationManagementDAO;
private static final ApplicationManagementDataHolder applicationMgtDataHolder = new ApplicationManagementDataHolder();
@ -46,14 +45,6 @@ public class ApplicationManagementDataHolder {
this.deviceManagementService = deviceManagementService;
}
public ApplicationManagementDAO getApplicationManagementDAO() {
return applicationManagementDAO;
}
public void setApplicationManagementDAO(ApplicationManagementDAO applicationManagementDAO) {
this.applicationManagementDAO = applicationManagementDAO;
}
public ApplicationManagementService getApplicationManagementService() {
return applicationManagementService;
}

@ -56,10 +56,7 @@ public class ApplicationManagementServiceComponent {
DataSourceConfig dataSourceConfig = ApplicationConfigurationManager.getInstance()
.getApplicationManagerConfiguration().getApplicationManagerRepository().getDataSourceConfig();
ApplicationManagementDAO applicationManagementDAO = new ApplicationManagementDAOFactory(dataSourceConfig)
.getApplicationManagementDAO();
ApplicationManagementDataHolder.getInstance()
.setApplicationManagementDAO(applicationManagementDAO);
ApplicationManagementDAOFactory.init(dataSourceConfig);
log.info("ApplicationManagement core bundle has been successfully initialized");

@ -20,15 +20,19 @@ package org.wso2.carbon.device.application.mgt.core.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManagementService;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagerException;
import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAO;
import org.wso2.carbon.device.application.mgt.core.internal.ApplicationManagementDataHolder;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOException;
import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import java.sql.SQLException;
public class ApplicationManagementServiceImpl implements ApplicationManagementService {
private static final Log log = LogFactory.getLog(ApplicationManagementServiceImpl.class);
@ -40,10 +44,17 @@ public class ApplicationManagementServiceImpl implements ApplicationManagementSe
@Override
public ApplicationList getApplications(Filter filter) throws ApplicationManagerException {
ConnectionManagerUtil.openConnection();
ApplicationManagementDAO applicationManagementDAO = ApplicationManagementDataHolder.getInstance().getApplicationManagementDAO();
ApplicationList applications = applicationManagementDAO.getApplications(filter);
ConnectionManagerUtil.closeConnection();
return applications;
try {
ConnectionManagerUtil.openConnection();
ApplicationManagementDAO applicationManagementDAO = ApplicationManagementDAOFactory.getApplicationManagementDAO();
return applicationManagementDAO.getApplications(filter);
} catch (ApplicationManagementDAOException e) {
throw new ApplicationManagerException("Error occurred while obtaining the applications for " +
"the given filter.", e);
} catch (DBConnectionException e) {
throw new ApplicationManagerException("Error occurred while opening a connection to the APPM data source", e);
} finally {
ConnectionManagerUtil.closeConnection();
}
}
}

@ -21,4 +21,16 @@ package org.wso2.carbon.device.application.mgt.core.util;
public class ApplicationManagerConstants {
public static final String APPLICATION_CONFIG_XML_FILE = "application-mgt.xml";
public static final class DataBaseTypes {
private DataBaseTypes() {
throw new AssertionError();
}
public static final String DB_TYPE_MYSQL = "MySQL";
public static final String DB_TYPE_ORACLE = "Oracle";
public static final String DB_TYPE_MSSQL = "Microsoft SQL Server";
public static final String DB_TYPE_DB2 = "DB2";
public static final String DB_TYPE_H2 = "H2";
public static final String DB_TYPE_POSTGRESQL = "PostgreSQL";
}
}

@ -20,19 +20,18 @@ package org.wso2.carbon.device.application.mgt.core.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.common.exception.IllegalTransactionStateException;
import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException;
import org.wso2.carbon.device.application.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.application.mgt.core.config.datasource.JNDILookupDefinition;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagerException;
import org.wso2.carbon.device.application.mgt.common.exception.IllegalTransactionStateException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
public class ConnectionManagerUtil {
@ -42,36 +41,6 @@ public class ConnectionManagerUtil {
CONNECTION_NOT_BORROWED, CONNECTION_BORROWED, CONNECTION_CLOSED
}
public enum DatabaseType {
H2("H2"),
MYSQL("MySQL"),
ORACLE("Oracle"),
POSTGRESQL("PostgreSQL"),
MSSQL("Microsoft SQL Server");
private final String value;
private static final Map<String, DatabaseType> lookup = new HashMap<String, DatabaseType>();
static {
for (DatabaseType databaseType : DatabaseType.values()) {
lookup.put(databaseType.getValue(), databaseType);
}
}
DatabaseType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static DatabaseType lookup(String value) {
return lookup.get(value);
}
}
private static final ThreadLocal<Connection> currentConnection = new ThreadLocal<>();
private static ThreadLocal<TxState> currentTxState = new ThreadLocal<>();
private static DataSource dataSource;
@ -84,7 +53,7 @@ public class ConnectionManagerUtil {
return currentConnection;
}
public static void openConnection() throws ApplicationManagerException {
public static void openConnection() throws DBConnectionException {
Connection conn = currentConnection.get();
if (conn != null) {
throw new IllegalTransactionStateException("A transaction is already active within the context of " +
@ -95,14 +64,23 @@ public class ConnectionManagerUtil {
conn = dataSource.getConnection();
} catch (SQLException e) {
currentTxState.set(TxState.CONNECTION_NOT_BORROWED);
throw new ApplicationManagerException(e.getMessage(), e);
throw new DBConnectionException(e.getMessage(), e);
}
currentConnection.set(conn);
currentTxState.set(TxState.CONNECTION_BORROWED);
}
public static Connection getConnection() throws DBConnectionException {
Connection conn = currentConnection.get();
if (conn == null) {
throw new DBConnectionException("No connection is associated with the current thread. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
}
return conn;
}
public static void beginTransaction() throws ApplicationManagerException {
public static void beginTransaction() throws TransactionManagementException, DBConnectionException {
Connection conn = currentConnection.get();
if (conn != null) {
throw new IllegalTransactionStateException("A transaction is already active within the context of " +
@ -112,7 +90,7 @@ public class ConnectionManagerUtil {
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
throw new ApplicationManagerException("Error occurred while retrieving a data source connection", e);
throw new DBConnectionException("Error occurred while retrieving a data source connection", e);
}
try {
@ -125,7 +103,7 @@ public class ConnectionManagerUtil {
"Transaction has ended pre-maturely", e1);
}
currentTxState.set(TxState.CONNECTION_CLOSED);
throw new ApplicationManagerException("Error occurred while setting auto-commit to false", e);
throw new TransactionManagementException("Error occurred while setting auto-commit to false", e);
}
currentConnection.set(conn);
currentTxState.set(TxState.CONNECTION_BORROWED);
@ -142,8 +120,6 @@ public class ConnectionManagerUtil {
conn.commit();
} catch (SQLException e) {
log.error("Error occurred while committing the transaction", e);
} finally {
closeConnection();
}
}
@ -158,8 +134,6 @@ public class ConnectionManagerUtil {
conn.rollback();
} catch (SQLException e) {
log.warn("Error occurred while roll-backing the transaction", e);
} finally {
closeConnection();
}
}
@ -195,10 +169,9 @@ public class ConnectionManagerUtil {
* Resolve data source from the data source definition.
*
* @param config data source configuration
* @return data source resolved from the data source definition
*
*/
public static DataSource resolveDataSource(DataSourceConfig config) {
DataSource dataSource = null;
public static void resolveDataSource(DataSourceConfig config) {
if (config == null) {
throw new RuntimeException(
"Application Management Repository data source configuration " + "is null and " +
@ -223,7 +196,6 @@ public class ConnectionManagerUtil {
dataSource = lookupDataSource(jndiConfig.getJndiName(), null);
}
}
return dataSource;
}
@ -238,4 +210,13 @@ public class ConnectionManagerUtil {
throw new RuntimeException("Error in looking up data source: " + e.getMessage(), e);
}
}
public static String getDatabaseType() {
try {
return dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
return null;
}
}

Loading…
Cancel
Save