-
Notifications
You must be signed in to change notification settings - Fork 544
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
488 additions
and
11 deletions.
There are no files selected for viewing
155 changes: 155 additions & 0 deletions
155
...so2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistryDAO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package org.wso2.carbon.identity.core.dao; | ||
|
||
import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement; | ||
import org.wso2.carbon.identity.base.IdentityException; | ||
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; | ||
import org.wso2.carbon.identity.core.util.IdentityTenantUtil; | ||
|
||
import java.sql.Connection; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class RegistryDAO { | ||
|
||
private static final String PATH = "PATH"; | ||
private static final String TENANT_ID = "TENANT_ID"; | ||
private static final String REG_NAME = "REG_NAME"; | ||
|
||
public String getPathId(String path, String tenantDomain) throws IdentityException { | ||
|
||
String pathId = null; | ||
try (Connection connection = IdentityDatabaseUtil.getGovernanceDBConnection(false)) { | ||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_PATH_ID)) { | ||
statement.setString(PATH, path); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
if (resultSet.next()) { | ||
pathId = resultSet.getString(1); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry path id.", e); | ||
} | ||
} catch (SQLException | IdentityException e) { | ||
throw new IdentityException("Error while retrieving registry path id.", e); | ||
} | ||
return pathId; | ||
} | ||
|
||
public Map<String, String> getCollectionProperties(int pathId, String tenantDomain) throws IdentityException { | ||
|
||
Map<String, String> properties = new HashMap<>(); | ||
try (Connection connection = IdentityDatabaseUtil.getGovernanceDBConnection(false)) { | ||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_RESOURCE_PROPERTY_COLLECTION)) { | ||
statement.setInt(PATH, pathId); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
while (resultSet.next()) { | ||
String key = resultSet.getString(1); | ||
String value = resultSet.getString(2); | ||
properties.put(key, value); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry resource collection properties.", e); | ||
} | ||
} catch (SQLException | IdentityException e) { | ||
throw new IdentityException("Error while retrieving registry resource collection properties.", e); | ||
} | ||
return properties; | ||
} | ||
|
||
public String[] getCollectionChildren(String path, int pathId, String tenantDomain) throws IdentityException { | ||
|
||
List<String> children = new ArrayList<>(); | ||
try (Connection connection = IdentityDatabaseUtil.getGovernanceDBConnection(false)) { | ||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_NAME_COLLECTION)) { | ||
statement.setInt(PATH, pathId); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
while (resultSet.next()) { | ||
children.add(path + "/" + resultSet.getString(1)); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry resource collection sub resource paths.", | ||
e); | ||
} | ||
|
||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_PATH_COLLECTION)) { | ||
statement.setInt(PATH, pathId); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
while (resultSet.next()) { | ||
String childPathName = resultSet.getString(2).split("/(?!.*\\/)")[1]; | ||
children.add(path + "/" + childPathName); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry resource collection sub paths.", e); | ||
} | ||
} catch (SQLException | IdentityException e) { | ||
throw new IdentityException("Error while retrieving registry resource collection children.", e); | ||
} | ||
return children.toArray(new String[0]); | ||
} | ||
|
||
public Map<String, String> getResourceProperties(int pathId, String resourceName, String tenantDomain) | ||
throws IdentityException { | ||
|
||
Map<String, String> properties = new HashMap<>(); | ||
try (Connection connection = IdentityDatabaseUtil.getGovernanceDBConnection(false)) { | ||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_RESOURCE_PROPERTY_RESOURCE)) { | ||
statement.setInt(PATH, pathId); | ||
statement.setString(REG_NAME, resourceName); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
while (resultSet.next()) { | ||
String key = resultSet.getString(1); | ||
String value = resultSet.getString(2); | ||
properties.put(key, value); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry resource properties.", e); | ||
} | ||
} catch (SQLException | IdentityException e) { | ||
throw new IdentityException("Error while retrieving registry resource properties.", e); | ||
} | ||
return properties; | ||
} | ||
|
||
public byte[] getResourceContent(int pathId, String resourceName, String tenantDomain) | ||
throws IdentityException { | ||
|
||
byte[] content = null; | ||
try (Connection connection = IdentityDatabaseUtil.getGovernanceDBConnection(false)) { | ||
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, | ||
RegistrySQLQueries.GET_REG_CONTENT)) { | ||
statement.setInt(PATH, pathId); | ||
statement.setString(REG_NAME, resourceName); | ||
statement.setInt(TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain)); | ||
try (ResultSet resultSet = statement.executeQuery()) { | ||
if (resultSet.next()) { | ||
content = resultSet.getBytes(1); | ||
} | ||
} | ||
} catch (SQLException e) { | ||
throw new IdentityException("Error while retrieving registry resource content.", e); | ||
} | ||
} catch (SQLException | IdentityException e) { | ||
throw new IdentityException("Error while retrieving registry resource content.", e); | ||
} | ||
return content; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...bon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySQLQueries.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.wso2.carbon.identity.core.dao; | ||
|
||
public class RegistrySQLQueries { | ||
|
||
private RegistrySQLQueries() { | ||
|
||
} | ||
|
||
public static final String GET_REG_PATH_ID = | ||
"SELECT REG_PATH_ID FROM REG_PATH WHERE REG_PATH_VALUE = :PATH; AND REG_TENANT_ID = :TENANT_ID;"; | ||
public static final String GET_REG_RESOURCE_PROPERTY_COLLECTION = | ||
"SELECT REG_NAME, REG_VALUE FROM REG_PROPERTY P, REG_RESOURCE_PROPERTY RP WHERE P.REG_ID=RP.REG_PROPERTY_ID AND RP.REG_PATH_ID = :PATH; AND RP.REG_RESOURCE_NAME IS NULL AND P.REG_TENANT_ID=RP.REG_TENANT_ID AND RP.REG_TENANT_ID = :TENANT_ID; ORDER BY P.REG_ID"; | ||
public static final String GET_REG_RESOURCE_PROPERTY_RESOURCE = | ||
"SELECT REG_NAME, REG_VALUE FROM REG_PROPERTY P, REG_RESOURCE_PROPERTY RP WHERE P.REG_ID=RP.REG_PROPERTY_ID AND RP.REG_PATH_ID = :PATH; AND RP.REG_RESOURCE_NAME = :REG_NAME; AND P.REG_TENANT_ID=RP.REG_TENANT_ID AND RP.REG_TENANT_ID = :TENANT_ID; ORDER BY P.REG_ID"; | ||
public static final String GET_REG_NAME_COLLECTION = | ||
"SELECT REG_NAME FROM REG_RESOURCE WHERE REG_PATH_ID = :PATH; AND REG_TENANT_ID = :TENANT_ID; AND REG_NAME IS NOT NULL;"; | ||
public static final String GET_REG_PATH_COLLECTION = | ||
"SELECT P.REG_PATH_ID, P.REG_PATH_VALUE FROM REG_PATH P, REG_RESOURCE R WHERE P.REG_PATH_PARENT_ID = :PATH; AND P.REG_TENANT_ID = :TENANT_ID; AND R.REG_PATH_ID=P.REG_PATH_ID AND R.REG_NAME IS NULL AND R.REG_TENANT_ID = :TENANT_ID;"; | ||
public static final String GET_REG_CONTENT = | ||
"SELECT REG_CONTENT_DATA FROM REG_CONTENT WHERE REG_CONTENT_ID = (SELECT REG_CONTENT_ID FROM REG_RESOURCE WHERE REG_PATH_ID = :PATH; AND REG_NAME = :REG_NAME; AND REG_TENANT_ID = :TENANT_ID; );"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
194 changes: 194 additions & 0 deletions
194
...c/main/java/org/wso2/carbon/identity/core/persistence/RegistryDataPersistenceManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
/* | ||
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). | ||
* | ||
* WSO2 LLC. 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.identity.core.persistence; | ||
|
||
import org.apache.axiom.om.OMElement; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
import org.wso2.carbon.identity.base.IdentityRuntimeException; | ||
import org.wso2.carbon.identity.core.util.IdentityConfigParser; | ||
import org.wso2.carbon.identity.core.util.IdentityCoreConstants; | ||
|
||
import java.sql.Connection; | ||
import java.sql.SQLException; | ||
|
||
import javax.naming.Context; | ||
import javax.naming.InitialContext; | ||
import javax.naming.NamingException; | ||
import javax.sql.DataSource; | ||
import javax.xml.namespace.QName; | ||
|
||
/** | ||
* This class is used to get the database connection for shared registry. | ||
*/ | ||
public class RegistryDataPersistenceManager { | ||
|
||
public static final String DATA_SOURCE = "DataSource"; | ||
|
||
public static final String NAME = "Name"; | ||
|
||
private static Log log = LogFactory.getLog(RegistryDataPersistenceManager.class); | ||
|
||
private static volatile RegistryDataPersistenceManager instance; | ||
|
||
private DataSource dataSource; | ||
|
||
|
||
private static final String PG_ACTIVE_SQL_TRANSACTION_STATE = "25001"; | ||
|
||
private static final String POSTGRESQL_DATABASE = "PostgreSQL"; | ||
|
||
/** | ||
* Private constructor which will not allow to create objects of this class from outside | ||
*/ | ||
private RegistryDataPersistenceManager() { | ||
|
||
initDataSource(); | ||
} | ||
|
||
/** | ||
* Singleton method | ||
* | ||
* @return RegistryDataPersistenceManager | ||
*/ | ||
public static RegistryDataPersistenceManager getInstance() { | ||
|
||
if (instance == null) { | ||
synchronized (RegistryDataPersistenceManager.class) { | ||
if (instance == null) { | ||
instance = new RegistryDataPersistenceManager(); | ||
} | ||
} | ||
} | ||
return instance; | ||
} | ||
|
||
/** | ||
* Initialize the datasource | ||
*/ | ||
private void initDataSource() { | ||
|
||
OMElement persistenceManagerConfigElem = IdentityConfigParser.getInstance() | ||
.getConfigElement("RegistryDataPersistenceManager"); | ||
try { | ||
if (persistenceManagerConfigElem == null) { | ||
String errorMsg = "Registry Data Persistence Manager configuration is not available in " + | ||
"identity.xml file. Terminating the initialization. This may affect certain functionality."; | ||
throw IdentityRuntimeException.error(errorMsg); | ||
} | ||
|
||
OMElement dataSourceElem = persistenceManagerConfigElem.getFirstChildWithName( | ||
new QName(IdentityCoreConstants.IDENTITY_DEFAULT_NAMESPACE, DATA_SOURCE)); | ||
|
||
if (dataSourceElem == null) { | ||
String errorMsg = "DataSource Element is not available for Registry Data Persistence " + | ||
"Manager in identity.xml file. Terminating the Registry Data Persistence Manager " + | ||
"initialization. This might affect certain features."; | ||
throw IdentityRuntimeException.error(errorMsg); | ||
} | ||
|
||
OMElement dataSourceNameElem = dataSourceElem.getFirstChildWithName( | ||
new QName(IdentityCoreConstants.IDENTITY_DEFAULT_NAMESPACE, NAME)); | ||
|
||
if (dataSourceNameElem != null) { | ||
String dataSourceName = dataSourceNameElem.getText(); | ||
Context ctx = new InitialContext(); | ||
dataSource = (DataSource) ctx.lookup(dataSourceName); | ||
} | ||
} catch (NamingException e) { | ||
String errorMsg = "Error when looking up the Registry Data Source."; | ||
throw IdentityRuntimeException.error(errorMsg, e); | ||
} | ||
} | ||
|
||
/** | ||
* Returns a database connection for shared registry data source. | ||
* | ||
* @param shouldApplyTransaction apply transaction or not | ||
* @return Database connection. | ||
* @throws IdentityRuntimeException Exception occurred when getting the data source. | ||
*/ | ||
public Connection getDBConnection(boolean shouldApplyTransaction) throws IdentityRuntimeException { | ||
|
||
try { | ||
Connection dbConnection = dataSource.getConnection(); | ||
if (shouldApplyTransaction) { | ||
dbConnection.setAutoCommit(false); | ||
try { | ||
dbConnection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); | ||
} catch (SQLException e) { | ||
// Handling startup error for postgresql | ||
// Active SQL Transaction means that connection is not committed. | ||
// Need to commit before setting isolation property. | ||
if (dbConnection.getMetaData().getDriverName().contains(POSTGRESQL_DATABASE) | ||
&& PG_ACTIVE_SQL_TRANSACTION_STATE.equals(e.getSQLState())) { | ||
dbConnection.commit(); | ||
dbConnection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); | ||
} | ||
} | ||
} | ||
return dbConnection; | ||
} catch (SQLException e) { | ||
String errMsg = "Error when getting a database connection object from the Shared data source."; | ||
throw DBConnectionException.error(errMsg, e); | ||
} | ||
} | ||
|
||
/** | ||
* Get the registry datasource. | ||
* | ||
* @return DataSource. | ||
*/ | ||
public DataSource getDataSource() { | ||
|
||
return dataSource; | ||
} | ||
|
||
/** | ||
* Revoke the transaction when catch then sql transaction errors. | ||
* | ||
* @param dbConnection database connection. | ||
*/ | ||
public void rollbackTransaction(Connection dbConnection) { | ||
|
||
try { | ||
if (dbConnection != null) { | ||
dbConnection.rollback(); | ||
} | ||
} catch (SQLException e1) { | ||
log.error("An error occurred while rolling back transactions. ", e1); | ||
} | ||
} | ||
|
||
/** | ||
* Commit the transaction. | ||
* | ||
* @param dbConnection database connection. | ||
*/ | ||
public void commitTransaction(Connection dbConnection) { | ||
|
||
try { | ||
if (dbConnection != null) { | ||
dbConnection.commit(); | ||
} | ||
} catch (SQLException e1) { | ||
log.error("An error occurred while commit transactions. ", e1); | ||
} | ||
} | ||
} |
Oops, something went wrong.