From ea92bc904aca3c449a016b049630233327792b18 Mon Sep 17 00:00:00 2001 From: manoj Date: Fri, 5 Dec 2014 11:11:23 +0530 Subject: [PATCH] DAO Layer Implementation --- .../mgt/core/config/DeviceMgtDBUtil.java | 241 ++++++++++++++++++ .../carbon/device/mgt/core/dao/DeviceDAO.java | 30 +++ .../mgt/core/dao/util/DeviceDAOUtil.java | 121 +++++++++ .../mgt/core/dao/util/ErrorHandler.java | 38 +++ .../internal/DeviceManagerDataHolder.java | 126 +++++++++ 5 files changed, 556 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceMgtDBUtil.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceDAOUtil.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/ErrorHandler.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagerDataHolder.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceMgtDBUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceMgtDBUtil.java new file mode 100644 index 000000000..93a2c994e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceMgtDBUtil.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2014, 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. + * 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.mgt.core.config; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public final class DeviceMgtDBUtil { + + private static final Log log = LogFactory.getLog(DeviceMgtDBUtil.class); + + private static volatile DataSource dataSource = null; + private static final String DB_CHECK_SQL = DeviceManagementConstants.DataSourceProperties.DB_CHECK_QUERY; + + private static final String DB_CONFIG = "Database."; + private static final String DB_DRIVER = DB_CONFIG + "Driver"; + private static final String DB_URL = DB_CONFIG + "URL"; + private static final String DB_USER = DB_CONFIG + "Username"; + private static final String DB_PASSWORD = DB_CONFIG + "Password"; + + private static final String DATA_SOURCE_NAME = "DataSourceName"; + + /** + * Initializes the data source + * + */ + public static void initialize() throws Exception { + if (dataSource != null) { + return; + } + + synchronized (DeviceMgtDBUtil.class) { + if (dataSource == null) { + if (log.isDebugEnabled()) { + log.debug("Initializing data source"); + } + APIManagerConfiguration config = ServiceReferenceHolder.getInstance(). + getAPIManagerConfigurationService().getAPIManagerConfiguration(); + String dataSourceName = config.getFirstProperty(DATA_SOURCE_NAME); + + if (dataSourceName != null) { + try { + Context ctx = new InitialContext(); + dataSource = (DataSource) ctx.lookup(dataSourceName); + } catch (NamingException e) { + throw new APIManagementException("Error while looking up the data " + + "source: " + dataSourceName); + } + } else { + DBConfiguration configuration = getDBConfig(config); + String dbUrl = configuration.getDbUrl(); + String driver = configuration.getDriverName(); + String username = configuration.getUserName(); + String password = configuration.getPassword(); + if (dbUrl == null || driver == null || username == null || password == null) { + log.warn("Required DB configuration parameters unspecified. So API Store and API Publisher " + + "will not work as expected."); + } + + BasicDataSource basicDataSource = new BasicDataSource(); + basicDataSource.setDriverClassName(driver); + basicDataSource.setUrl(dbUrl); + basicDataSource.setUsername(username); + basicDataSource.setPassword(password); + dataSource = basicDataSource; + } + } + setupAPIManagerDatabase(); + } + } + + /** + * Creates the APIManager Database if not created already. + * + * @throws Exception if an error occurs while creating the APIManagerDatabase. + */ + private static void setupAPIManagerDatabase() throws Exception { + + String value = System.getProperty("setup"); + if (value != null) { + LocalDatabaseCreator databaseCreator = new LocalDatabaseCreator(dataSource); + try { + if (!databaseCreator.isDatabaseStructureCreated(DB_CHECK_SQL)) { + databaseCreator.createRegistryDatabase(); + } else { + log.info("APIManager database already exists. Not creating a new database."); + } + } catch (Exception e) { + String msg = "Error in creating the APIManager database"; + throw new Exception(msg, e); + } + } + } + + /** + * Utility method to get a new database connection + * + * @return Connection + * @throws java.sql.SQLException if failed to get Connection + */ + public static Connection getConnection() throws SQLException { + if (dataSource != null) { + return dataSource.getConnection(); + } + throw new SQLException("Data source is not configured properly."); + } + + /** + * Utility method to close the connection streams. + * @param preparedStatement PreparedStatement + * @param connection Connection + * @param resultSet ResultSet + */ + public static void closeAllConnections(PreparedStatement preparedStatement, Connection connection, + ResultSet resultSet) { + closeConnection(connection); + closeResultSet(resultSet); + closeStatement(preparedStatement); + } + + /** + * Close Connection + * @param dbConnection Connection + */ + private static void closeConnection(Connection dbConnection) { + if (dbConnection != null) { + try { + dbConnection.close(); + } catch (SQLException e) { + log.warn("Database error. Could not close database connection. Continuing with " + + "others. - " + e.getMessage(), e); + } + } + } + + /** + * Close ResultSet + * @param resultSet ResultSet + */ + private static void closeResultSet(ResultSet resultSet) { + if (resultSet != null) { + try { + resultSet.close(); + } catch (SQLException e) { + log.warn("Database error. Could not close ResultSet - " + e.getMessage(), e); + } + } + + } + + /** + * Close PreparedStatement + * @param preparedStatement PreparedStatement + */ + private static void closeStatement(PreparedStatement preparedStatement) { + if (preparedStatement != null) { + try { + preparedStatement.close(); + } catch (SQLException e) { + log.warn("Database error. Could not close PreparedStatement. Continuing with" + + " others. - " + e.getMessage(), e); + } + } + + } + + /** + * Return the DBConfiguration + * + * @param config APIManagerConfiguration containing the JDBC settings + * @return DBConfiguration + */ + private static DBConfiguration getDBConfig(APIManagerConfiguration config) { + DBConfiguration dbConfiguration = new DBConfiguration(); + dbConfiguration.setDbUrl(config.getFirstProperty(DB_URL)); + dbConfiguration.setDriverName(config.getFirstProperty(DB_DRIVER)); + dbConfiguration.setUserName(config.getFirstProperty(DB_USER)); + dbConfiguration.setPassword(config.getFirstProperty(DB_PASSWORD)); + return dbConfiguration; + } + + /** + * Function converts IS to String + * Used for handling blobs + * @param is + * @return + */ + public static String getStringFromInputStream(InputStream is) { + BufferedReader br = null; + StringBuilder sb = new StringBuilder(); + + String line; + try { + + br = new BufferedReader(new InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return sb.toString(); + + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java new file mode 100644 index 000000000..b3dae2e43 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014, 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. + * 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.mgt.core.dao; + +import org.wso2.carbon.device.mgt.core.dao.util.DeviceDAOUtil; + +import javax.sql.DataSource; + +public class DeviceDAO { + + private DataSource dataSource; + + public DeviceDAO(DataSource dataSource) { + this.dataSource = ; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceDAOUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceDAOUtil.java new file mode 100644 index 000000000..dc1cbf758 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceDAOUtil.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013, 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.mgt.core.dao.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagerDataHolder; +import org.wso2.carbon.user.api.TenantManager; +import org.wso2.carbon.user.api.UserStoreException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Util class for RSS DAO operations + */ +public class DeviceDAOUtil { + private static final Log log = LogFactory.getLog(DeviceDAOUtil.class); + + /** + * Clean up database resources + * @param resultSet result set to be closed + * @param statement prepared statement to be closed + * @param conn connection to be closed + * @param task occurred when clean up the resources + */ + public static synchronized void cleanupResources(ResultSet resultSet, PreparedStatement statement, + Connection conn, String task) { + if (resultSet != null) { + try { + resultSet.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the result set " + task, e); + } + } + if (statement != null) { + try { + statement.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the statement " + task, e); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the connection "+ task, e); + } + } + } + + /** + * Roll back database updates on error + * + * @param connection database connection + * @param task task which was executing at the error. + */ + public static synchronized void rollback(Connection connection, String task) { + if (connection != null) { + try { + connection.rollback(); + } catch (SQLException e) { + log.error("Rollback failed on " + task, e); + } + } + } + + public synchronized static int getTenantId() throws DeviceManagementException { + CarbonContext ctx = CarbonContext.getThreadLocalCarbonContext(); + int tenantId = ctx.getTenantId(); + if (tenantId != MultitenantConstants.INVALID_TENANT_ID) { + return tenantId; + } + String tenantDomain = ctx.getTenantDomain(); + if (null != tenantDomain) { + try { + TenantManager tenantManager = DeviceManagerDataHolder.getInstance().getTenantManager(); + tenantId = tenantManager.getTenantId(tenantDomain); + } catch (UserStoreException e) { + throw new DeviceManagementException("Error while retrieving the tenant Id for " + + "tenant domain : " + tenantDomain, e); + } + } + return tenantId; + } + + public static synchronized int getTenantId(String tenantDomain) throws DeviceManagementException { + int tenantId = MultitenantConstants.INVALID_TENANT_ID; + if (null != tenantDomain) { + try { + TenantManager tenantManager = DeviceManagerDataHolder.getInstance().getTenantManager(); + tenantId = tenantManager.getTenantId(tenantDomain); + } catch (UserStoreException e) { + throw new DeviceManagementException("Error while retrieving the tenant Id for " + + "tenant domain : " + tenantDomain, e); + } + } + return tenantId; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/ErrorHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/ErrorHandler.java new file mode 100644 index 000000000..d5cb96b3f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/ErrorHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, 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. + * 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.mgt.core.dao.util; + +import org.apache.commons.logging.Log; +import org.wso2.carbon.device.mgt.core.dao.exception.DeviceDAOException; + +import java.sql.SQLException; + +public class ErrorHandler { + + private String errorMsg = ""; + private Log log; + + public ErrorHandler(String msg, Log log) { + errorMsg = msg; + this.log = log; + } + + public void handleDAOException(String msg, SQLException e) throws DeviceDAOException { + + log.error(msg, e); + throw new DeviceDAOException(msg, e); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagerDataHolder.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagerDataHolder.java new file mode 100644 index 000000000..52984f6f8 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagerDataHolder.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2014, 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.mgt.core.internal; + +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.ndatasource.core.DataSourceService; +import org.wso2.carbon.securevault.SecretCallbackHandlerService; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.user.core.tenant.TenantManager; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; +import javax.transaction.TransactionManager; + +public class DeviceManagerDataHolder { + + private DataSourceService dataSourceService; + + private RealmService realmService; + + private TransactionManager transactionManager; + + private SecretCallbackHandlerService secretCallbackHandlerService; + + private TenantManager tenantManager; + + private static DeviceManagerDataHolder thisInstance = new DeviceManagerDataHolder(); + + private DeviceManagerDataHolder() { + } + + public static DeviceManagerDataHolder getInstance() { + return thisInstance; + } + + public DataSourceService getDataSourceService() { + return dataSourceService; + } + + public void setDataSourceService(DataSourceService dataSourceService) { + this.dataSourceService = dataSourceService; + } + + public RealmService getRealmService() { + return realmService; + } + + public void setRealmService(RealmService realmService) { + this.realmService = realmService; + } + + public TransactionManager getTransactionManager() { + return transactionManager; + } + + public void setTransactionManager(TransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + public SecretCallbackHandlerService getSecretCallbackHandlerService() { + return secretCallbackHandlerService; + } + + public void setSecretCallbackHandlerService( + SecretCallbackHandlerService secretCallbackHandlerService) { + this.secretCallbackHandlerService = secretCallbackHandlerService; + } + + public static void setThisInstance(DeviceManagerDataHolder thisInstance) { + DeviceManagerDataHolder.thisInstance = thisInstance; + } + + public TenantManager getTenantManager() throws DeviceManagementException { + RealmService realmService = getRealmService(); + if (realmService == null) { + throw new DeviceManagementException("Realm service is not initialized properly"); + } + return realmService.getTenantManager(); + } + + /** + * Get tenant id of the current tenant + * + * @return tenant id + * @throws DeviceManagementException if error occurred when getting tenant id + */ + public int getTenantId() throws DeviceManagementException { + CarbonContext context = CarbonContext.getThreadLocalCarbonContext(); + int tenantId = context.getTenantId(); + if (tenantId != MultitenantConstants.INVALID_TENANT_ID) { + return tenantId; + } + String tenantDomain = context.getTenantDomain(); + if (tenantDomain == null) { + String msg = "Tenant domain is not properly set and thus, is null"; + throw new DeviceManagementException(msg); + } + TenantManager tenantManager = getTenantManager(); + try { + tenantId = tenantManager.getTenantId(tenantDomain); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving id from the domain of tenant " + + tenantDomain; + throw new DeviceManagementException(msg); + } + return tenantId; + } + +}