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..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 @@ -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..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; @@ -312,4 +313,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 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 c1a87ea41d28..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 @@ -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 + " in tenant: " + tenantId); + } + throw handleClientException(ConfigurationConstants.ErrorMessages.ERROR_CODE_RESOURCES_DOES_NOT_EXISTS); + } + 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..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 @@ -1609,6 +1609,34 @@ 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()) { + 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/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. 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();