From 96f93b0253f2efddecefa94c43dcb9e11c7015d7 Mon Sep 17 00:00:00 2001 From: UdeshAthukorala Date: Fri, 20 Oct 2023 18:08:55 +0530 Subject: [PATCH 1/2] Add method to delete all the resources belongs to a given resource type in a tenant. --- .../mgt/core/ConfigurationManager.java | 11 +++++++ .../mgt/core/ConfigurationManagerImpl.java | 10 ++++++ .../mgt/core/constant/SQLConstants.java | 2 ++ .../mgt/core/dao/ConfigurationDAO.java | 12 +++++++ .../impl/CachedBackedConfigurationDAO.java | 18 +++++++++++ .../core/dao/impl/ConfigurationDAOImpl.java | 32 +++++++++++++++++++ .../mgt/core/ConfigurationManagerTest.java | 21 ++++++++++++ 7 files changed, 106 insertions(+) diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java index cd82fecebf1e..1b663e73d25c 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java @@ -328,4 +328,15 @@ void deleteFileById(String resourceType, String resourceName, String fileId) * @throws ConfigurationManagementException Configuration management exception. */ void replaceResource(Resource resource) throws ConfigurationManagementException; + + /** + * This function is used to delete all the resources belongs to given resource type in the current tenant. + * + * @param resourceType Request to delete the resources for the given {@link ResourceType}. + * @throws ConfigurationManagementException Configuration management exception. + */ + default void deleteResourcesByType(String resourceType) throws ConfigurationManagementException { + + throw new NotImplementedException("This functionality is not implemented."); + } } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java index 56dee5914fab..0d06a663179f 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java @@ -451,6 +451,16 @@ private void validateSearchRequest(Condition condition) throws ConfigurationMana } } + @Override + public void deleteResourcesByType (String resourceTypeName) throws ConfigurationManagementException { + + ResourceType resourceType = getResourceType(resourceTypeName); + this.getConfigurationDAO().deleteResourcesByType(getTenantId(), resourceType.getId()); + if (log.isDebugEnabled()) { + log.debug("Resources belongs to Resource Type : " + resourceTypeName + " is deleted successfully."); + } + } + private void validateResourceRetrieveRequest(String resourceTypeName, String resourceName) throws ConfigurationManagementException { diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/SQLConstants.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/SQLConstants.java index 3cfa1508de1c..b1f9f6cb2c9a 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/SQLConstants.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/SQLConstants.java @@ -500,4 +500,6 @@ public class SQLConstants { + "MODIFIED, IDN_CONFIG_RESOURCE.CREATED_TIME, IDN_CONFIG_RESOURCE.HAS_FILE, IDN_CONFIG_RESOURCE" + ".HAS_ATTRIBUTE FROM IDN_CONFIG_RESOURCE WHERE IDN_CONFIG_RESOURCE." + "TYPE_ID = ? and IDN_CONFIG_RESOURCE.TENANT_ID = ?"; + public static final String DELETE_RESOURCES_BY_RESOURCE_TYPE_ID_SQL = + "DELETE FROM IDN_CONFIG_RESOURCE WHERE TYPE_ID = ? and TENANT_ID = ?"; } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java index 682e9dbb7518..d13932992fe0 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java @@ -312,4 +312,16 @@ List getResourcesByType(int tenantId, String resourceTypeId) * @throws ConfigurationManagementException if an error occurs while validating the resourceId. */ boolean isExistingResource(int tenantId, String resourceId) throws ConfigurationManagementException; + + /** + * Delete all the resources by the given resource type in the given tenant. + * + * @param tenantId Id of the tenant + * @param resourceTypeId Id of the {@link ResourceType}. + * @throws ConfigurationManagementException Configuration Management Exception. + */ + default void deleteResourcesByType(int tenantId, String resourceTypeId) throws ConfigurationManagementException { + + throw new ConfigurationManagementException("This method is not implemented", null); + } } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java index c1a87ea41d28..abc154de6364 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java @@ -40,6 +40,8 @@ import java.io.InputStream; import java.util.List; +import static org.wso2.carbon.identity.configuration.mgt.core.util.ConfigurationUtils.handleClientException; + /** * This is a wrapper data access object to the default data access object to provide caching functionalities. */ @@ -273,6 +275,22 @@ public boolean isExistingResource(int tenantId, String resourceId) throws Config return configurationDAO.isExistingResource(tenantId, resourceId); } + @Override + public void deleteResourcesByType(int tenantId, String resourceTypeId) throws ConfigurationManagementException { + + List resourceList = configurationDAO.getResourcesByType(tenantId, resourceTypeId); + if (resourceList.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("No resource found for the resourceTypeId: " + resourceTypeId); + } + throw handleClientException(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS, null); + } + configurationDAO.deleteResourcesByType(tenantId, resourceTypeId); + for (Resource resource : resourceList) { + deleteResourceFromCache(resource); + } + } + private Resource getResourceFromCacheById(String resourceId, int tenantId) throws ConfigurationManagementException { diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java index a046065f4384..7bb66ef24572 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java @@ -1609,6 +1609,38 @@ public List getResourcesByType(int tenantId, String resourceTypeId) } } + @Override + public void deleteResourcesByType(int tenantId, String resourceTypeId) throws ConfigurationManagementException { + + JdbcTemplate jdbcTemplate = JdbcUtils.getNewTemplate(); + try { + if (isMySQLDB()) { + /** + * Need to first delete files since in MySql Clustering scripts for NDB engine `ON DELETE CASCADE`is no + * longer supported for foreign keys on NDB tables when the child table contains a column that uses any + * of the BLOB or TEXT types. Issue: (https://github.com/wso2/product-is/issues/12167). + */ + List resourceList = getResourcesByType(tenantId, resourceTypeId); + if (resourceList.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("No resource found for the resourceTypeId: " + resourceTypeId); + } + } else { + for (Resource resource : resourceList) { + deleteFiles(resource.getResourceId()); + } + } + } + jdbcTemplate.executeUpdate(SQLConstants.DELETE_RESOURCES_BY_RESOURCE_TYPE_ID_SQL, preparedStatement -> { + int initialParameterIndex = 1; + preparedStatement.setString(initialParameterIndex, resourceTypeId); + preparedStatement.setInt(++initialParameterIndex, tenantId); + }); + } catch (DataAccessException e) { + throw handleServerException(ERROR_CODE_RESOURCES_DOES_NOT_EXISTS, e); + } + } + /** * Get Attributes for the {@link Resource}. * diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java index e203051e6f5c..1841dda27a95 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java @@ -579,6 +579,27 @@ public void testSearchTenantSpecificResources() throws Exception { assertTrue(isTenantSearchConditionMatch(resources)); } + @Test(priority = 33) + public void testDeleteResourcesByType() throws Exception { + + ResourceType resourceType = configurationManager.addResourceType(getSampleResourceType2Add()); + Resource resource1 = configurationManager.addResource(resourceType.getName(), getSampleResource1Add()); + Resource resource2 = configurationManager.addResource(resourceType.getName(), getSampleResource2Add()); + + Resources resourcesByType = configurationManager.getResourcesByType(resourceType.getName()); + Assert.assertTrue("Retrieved resource count should be equal to the added value", + resourcesByType.getResources().size() == 2); + Assert.assertEquals("Created resource name should be equal to the retrieved resource name", + resource1.getResourceName(), resourcesByType.getResources().get(0).getResourceName()); + Assert.assertEquals("Created resource name should be equal to the retrieved resource name", + resource2.getResourceName(), resourcesByType.getResources().get(1).getResourceName()); + + configurationManager.deleteResourcesByType(resourceType.getName()); + resourcesByType = configurationManager.getResourcesByType(resourceType.getName()); + Assert.assertTrue("Retrieved resource count should be equal to the 0", + resourcesByType.getResources().size() == 0); + } + private void removeCreatedTimeColumn() throws DataAccessException { JdbcTemplate jdbcTemplate = JdbcUtils.getNewTemplate(); From 89229d99304bf28cb30b59a43d181d33054a0be6 Mon Sep 17 00:00:00 2001 From: UdeshAthukorala Date: Mon, 23 Oct 2023 12:50:41 +0530 Subject: [PATCH 2/2] Addressing comments --- .../mgt/core/ConfigurationManagerImpl.java | 2 +- .../mgt/core/dao/ConfigurationDAO.java | 3 ++- .../core/dao/impl/CachedBackedConfigurationDAO.java | 4 ++-- .../mgt/core/dao/impl/ConfigurationDAOImpl.java | 6 +----- .../mgt/core/util/ConfigurationUtils.java | 13 +++++++++++++ 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java index 0d06a663179f..76e165504947 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java @@ -452,7 +452,7 @@ private void validateSearchRequest(Condition condition) throws ConfigurationMana } @Override - public void deleteResourcesByType (String resourceTypeName) throws ConfigurationManagementException { + public void deleteResourcesByType(String resourceTypeName) throws ConfigurationManagementException { ResourceType resourceType = getResourceType(resourceTypeName); this.getConfigurationDAO().deleteResourcesByType(getTenantId(), resourceType.getId()); diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java index d13932992fe0..2ec048e948ec 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/ConfigurationDAO.java @@ -17,6 +17,7 @@ package org.wso2.carbon.identity.configuration.mgt.core.dao; import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException; +import org.wso2.carbon.identity.configuration.mgt.core.exception.NotImplementedException; import org.wso2.carbon.identity.configuration.mgt.core.model.Attribute; import org.wso2.carbon.identity.configuration.mgt.core.model.Resource; import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceFile; @@ -322,6 +323,6 @@ List getResourcesByType(int tenantId, String resourceTypeId) */ default void deleteResourcesByType(int tenantId, String resourceTypeId) throws ConfigurationManagementException { - throw new ConfigurationManagementException("This method is not implemented", null); + throw new NotImplementedException("This functionality is not implemented."); } } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java index abc154de6364..4c33fb35e26d 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/CachedBackedConfigurationDAO.java @@ -281,9 +281,9 @@ public void deleteResourcesByType(int tenantId, String resourceTypeId) throws Co List resourceList = configurationDAO.getResourcesByType(tenantId, resourceTypeId); if (resourceList.isEmpty()) { if (log.isDebugEnabled()) { - log.debug("No resource found for the resourceTypeId: " + resourceTypeId); + log.debug("No resource found for the resourceTypeId: " + resourceTypeId + " in tenant: " + tenantId); } - throw handleClientException(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS, null); + throw handleClientException(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS); } configurationDAO.deleteResourcesByType(tenantId, resourceTypeId); for (Resource resource : resourceList) { diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java index 7bb66ef24572..21f6dd533b7b 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/dao/impl/ConfigurationDAOImpl.java @@ -1621,11 +1621,7 @@ public void deleteResourcesByType(int tenantId, String resourceTypeId) throws Co * of the BLOB or TEXT types. Issue: (https://github.com/wso2/product-is/issues/12167). */ List resourceList = getResourcesByType(tenantId, resourceTypeId); - if (resourceList.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("No resource found for the resourceTypeId: " + resourceTypeId); - } - } else { + if (!resourceList.isEmpty()) { for (Resource resource : resourceList) { deleteFiles(resource.getResourceId()); } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/util/ConfigurationUtils.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/util/ConfigurationUtils.java index b7e66709b641..695d7ff8d42b 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/util/ConfigurationUtils.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/util/ConfigurationUtils.java @@ -48,6 +48,19 @@ public class ConfigurationUtils { private static final Log log = LogFactory.getLog(ConfigurationUtils.class); + /** + * This method can be used to generate a ConfigurationManagementClientException from + * ConfigurationConstants.ErrorMessages object when no exception is thrown. + * + * @param error ConfigurationConstants.ErrorMessages. + * @return ConfigurationManagementClientException. + */ + public static ConfigurationManagementClientException handleClientException( + ConfigurationConstants.ErrorMessages error) { + + return new ConfigurationManagementClientException(error.getMessage(), error.getCode()); + } + /** * This method can be used to generate a ConfigurationManagementClientException from * ConfigurationConstants.ErrorMessages object when no exception is thrown.