From 739bca08535a39d8d2548e87c745ab1d3712dc86 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 01:12:09 +0530 Subject: [PATCH 01/10] Get discoverable application info --- .../application/OrgApplicationManager.java | 34 ++ .../OrgApplicationManagerImpl.java | 25 ++ .../application/constant/SQLConstants.java | 104 ++++++ .../application/dao/OrgApplicationMgtDAO.java | 37 ++ .../dao/impl/OrgApplicationMgtDAOImpl.java | 324 ++++++++++++++++++ 5 files changed, 524 insertions(+) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index d475623f..13a61e23 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.organization.management.application; +import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo; import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; import org.wso2.carbon.identity.organization.management.service.exception.NotImplementedException; @@ -176,4 +177,37 @@ default Map getChildAppIds(String parentAppId, String parentOrgI throw new NotImplementedException("getChildAppIds method is not implemented in " + this.getClass().getName()); } + + /* + * Get the discoverable application basic info. + * @param limit Maximum no of applications to be returned in the result set (optional). + * @param offset Zero based index of the first application to be returned in the result set (optional). + * @param filter Filter to search for applications (optional). + * @param sortOrder Sort order, ascending or descending (optional). + * @param sortBy Attribute to sort from (optional). + * @param tenantDomain Tenant domain. + * @return List of DiscoverableApplicationBasicInfo of applications matching the given criteria. + * @throws OrganizationManagementException If an error occurred when retrieving the discoverable applications. + */ + default List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + String sortOrder, + String sortBy, String tenantDomain) + throws OrganizationManagementException { + + return null; + } + + /* + * Get the count of discoverable applications. + * @param filter Filter to search for applications (optional). + * @param tenantDomain Tenant domain. + * @return Count of discoverable applications matching given filter. + * @throws OrganizationManagementException If an error occurred when retrieving the count of + * discoverable applications. + */ + default int getCountOfDiscoverableApplications(String filter, String tenantDomain) + throws OrganizationManagementException { + + return 0; + } } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java index 45bc8ec0..3494efd9 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java @@ -26,6 +26,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; +import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo; import org.wso2.carbon.identity.application.common.model.AuthenticationStep; import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.model.IdentityProvider; @@ -59,6 +60,7 @@ import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; import org.wso2.carbon.identity.organization.management.ext.Constants; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; +import org.wso2.carbon.identity.organization.management.service.OrganizationManagerImpl; import org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementClientException; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; @@ -709,6 +711,29 @@ public Map getChildAppIds(String parentAppId, String parentOrgId return Collections.emptyMap(); } + @Override + public List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + String sortOrder, String sortBy, + String tenantDomain) + throws OrganizationManagementException { + + OrganizationManagerImpl organizationManager = new OrganizationManagerImpl(); + String rootOrgId = organizationManager.getPrimaryOrganizationId(tenantDomain); + + return getOrgApplicationMgtDAO().getDiscoverableApplicationBasicInfo(limit, offset, filter, sortOrder, + sortBy, tenantDomain, rootOrgId); + } + + @Override + public int getCountOfDiscoverableApplications(String filter, String tenantDomain) + throws OrganizationManagementException { + + OrganizationManagerImpl organizationManager = new OrganizationManagerImpl(); + String rootOrgId = organizationManager.getPrimaryOrganizationId(tenantDomain); + + return getOrgApplicationMgtDAO().getCountOfDiscoverableApplications(filter, tenantDomain, rootOrgId); + } + /** * Returns whether the given application is a main application. * diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java index f2f3fd2f..8227d097 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java @@ -73,6 +73,110 @@ public class SQLConstants { SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_OWNER_ORG_ID + "; AND SHARED_ORG_ID IN (" + SQLPlaceholders.SHARED_ORG_ID_LIST_PLACEHOLDER + ")"; + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + + "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + + "rn = 1 ORDER BY ID DESC LIMIT ?, ?"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + + "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + + "rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY " + + "sa.APP_NAME ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn " + + "FROM SP_APP sa JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + + "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + + "rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + + "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + + "rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + + "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + + "rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC LIMIT ?, ?"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + + "DiscoverableApps WHERE rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + + public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX = + "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; + + public static final String LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT = + "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT count(UUID) " + + "FROM DiscoverableApps WHERE rn = 1"; + + public static final String LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT = + "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME ORDER BY CASE " + + "WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa JOIN " + + "SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + + "SELECT count(UUID) FROM DiscoverableApps WHERE rn = 1"; + private SQLConstants() { } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java index 1f5ffb9a..b137fd59 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.organization.management.application.dao; +import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo; import org.wso2.carbon.identity.organization.management.application.model.MainApplicationDO; import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; import org.wso2.carbon.identity.organization.management.service.exception.NotImplementedException; @@ -138,4 +139,40 @@ default List getSharedApplications(String mainAppId, String throw new NotImplementedException( "getSharedApplications method is not implemented in " + this.getClass().getName()); } + + /** + * Returns the basic information of the shared applications + * @param limit Maximum no of applications to be returned in the result set (optional). + * @param offset Zero based index of the first application to be returned in the result set (optional). + * @param filter Filter to search for applications (optional). + * @param sortOrder Sort order, ascending or descending (optional). + * @param sortBy Attribute to sort from (optional). + * @param tenantDomain Tenant domain. + * @param rootOrgId Root organization ID. + * @return List of DiscoverableApplicationBasicInfo of applications matching the given criteria. + * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the + * discoverable applications. + */ + default List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + String sortOrder, String sortBy, + String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + return null; + } + + /* + * Returns the count of discoverable applications matching given filter. + * @param filter Filter to search for applications (optional). + * @param tenantDomain Tenant domain. + * @param rootOrgId Root organization ID. + * @return Count of discoverable applications matching given filter. + * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the + * discoverable applications count. + */ + default int getCountOfDiscoverableApplications(String filter, String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + return 0; + } } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java index 2a7c7b5d..0a5f3a9e 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java @@ -19,22 +19,43 @@ package org.wso2.carbon.identity.organization.management.application.dao.impl; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate; +import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement; import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; import org.wso2.carbon.database.utils.jdbc.exceptions.TransactionException; +import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo; +import org.wso2.carbon.identity.application.common.model.User; +import org.wso2.carbon.identity.application.mgt.ApplicationConstants; +import org.wso2.carbon.identity.application.mgt.ApplicationMgtUtil; +import org.wso2.carbon.identity.core.URLBuilderException; +import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.JdbcUtils; import org.wso2.carbon.identity.organization.management.application.dao.OrgApplicationMgtDAO; import org.wso2.carbon.identity.organization.management.application.model.MainApplicationDO; import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementClientException; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementServerException; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.INVALID_OFFSET; +import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Error.SORTING_NOT_IMPLEMENTED; +import static org.wso2.carbon.identity.application.mgt.ApplicationMgtUtil.getConsoleAccessUrlFromServerConfig; +import static org.wso2.carbon.identity.application.mgt.ApplicationMgtUtil.getMyAccountAccessUrlFromServerConfig; import static org.wso2.carbon.identity.organization.management.application.constant.OrgApplicationMgtConstants.IS_FRAGMENT_APP; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.GET_FILTERED_SHARED_APPLICATIONS; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.GET_MAIN_APPLICATION; @@ -45,6 +66,18 @@ import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.INSERT_SHARED_APP; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.IS_FRAGMENT_APPLICATION; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.IS_FRAGMENT_APPLICATION_H2; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_MAIN_APP_ID; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_METADATA_NAME; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_METADATA_VALUE; @@ -72,6 +105,9 @@ */ public class OrgApplicationMgtDAOImpl implements OrgApplicationMgtDAO { + private Log log = LogFactory.getLog(OrgApplicationMgtDAOImpl.class); + private static final String ASTERISK = "*"; + @Override public void addSharedApplication(String mainAppId, String ownerOrgId, String sharedAppId, String sharedOrgId, boolean shareWithAllChildren) throws OrganizationManagementException { @@ -264,6 +300,144 @@ public List getSharedApplications(String mainAppId, String } } + @Override + public List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + String sortOrder, String sortBy, + String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + validateForUnImplementedSortingAttributes(sortOrder, sortBy); + validateAttributesForPagination(offset, limit); + + // TODO: 17/9/24 : Enforce a max limit + if (StringUtils.isBlank(filter) || ASTERISK.equals(filter)) { + return getDiscoverableApplicationBasicInfo(limit, offset, tenantDomain, rootOrgId); + } + + String filterResolvedForSQL = resolveSQLFilter(filter); + + List applicationBasicInfoList = new ArrayList<>(); + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + String databaseVendorType = connection.getMetaData().getDatabaseProductName(); + + try (NamedPreparedStatement statement = + new NamedPreparedStatement(connection, + getDBVendorSpecificDiscoverableAppRetrievalQueryByAppName(databaseVendorType))) { + statement.setString(1, tenantDomain); + statement.setString(2, filterResolvedForSQL); + statement.setString(3, rootOrgId); + statement.setInt(4, offset); + statement.setInt(5, limit); + + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + applicationBasicInfoList.add(buildApplicationBasicInfo(resultSet)); + } + } + } + } catch (SQLException e) { + throw new OrganizationManagementException("Error while getting application basic information" + + " for discoverable applications in tenantDomain: " + tenantDomain, e); + } + + return Collections.unmodifiableList(applicationBasicInfoList); + } + + @Override + public int getCountOfDiscoverableApplications(String filter, String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + if (log.isDebugEnabled()) { + log.debug("Getting count of discoverable applications matching filter: " + filter + " in tenantDomain: " + + tenantDomain); + } + + if (StringUtils.isBlank(filter) || ASTERISK.equals(filter)) { + return getCountOfDiscoverableApplications(tenantDomain, rootOrgId); + } + + int count = 0; + String filterResolvedForSQL = resolveSQLFilter(filter); + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + + try (NamedPreparedStatement statement = + new NamedPreparedStatement(connection, + LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT)) { + statement.setString(1, tenantDomain); + statement.setString(2, filterResolvedForSQL); + statement.setString(3, rootOrgId); + + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + count = resultSet.getInt(1); + } + } + } + } catch (SQLException e) { + throw new OrganizationManagementServerException("Error while getting count of discoverable " + + "applications matching filter:" + filter + " in tenantDomain: " + tenantDomain); + } + + return count; + } + + private int getCountOfDiscoverableApplications(String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + int count; + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + + try (NamedPreparedStatement statement = + new NamedPreparedStatement(connection, + LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT)) { + statement.setString(1, tenantDomain); + statement.setString(2, rootOrgId); + + try (ResultSet resultSet = statement.executeQuery()) { + resultSet.next(); + count = resultSet.getInt(1); + } + } + } catch (SQLException e) { + throw new OrganizationManagementServerException("Error while getting count of discoverable " + + "applications in tenantDomain: " + tenantDomain); + } + + return count; + } + + private List getDiscoverableApplicationBasicInfo(int limit, int offset, + String tenantDomain, String rootOrgId) + throws OrganizationManagementException { + + List applicationBasicInfoList = new ArrayList<>(); + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + String databaseVendorType = connection.getMetaData().getDatabaseProductName(); + + try (NamedPreparedStatement statement = + new NamedPreparedStatement(connection, + getDBVendorSpecificDiscoverableAppRetrievalQuery(databaseVendorType))) { + statement.setString(1, tenantDomain); + statement.setString(2, rootOrgId); + statement.setInt(3, offset); + statement.setInt(4, limit); + + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + applicationBasicInfoList.add(buildApplicationBasicInfo(resultSet)); + } + } + } + } catch (SQLException e) { + throw new OrganizationManagementException("Error while getting application basic information" + + " for discoverable applications in tenantDomain: " + tenantDomain, e); + } + + return Collections.unmodifiableList(applicationBasicInfoList); + } + /** * Get the value for the shareWithAllChildren column according to the db type. * @@ -279,4 +453,154 @@ private String getShareWithAllChildrenValue(boolean shareWithAllChildren) } return String.valueOf(shareWithAllChildren); } + + private void validateForUnImplementedSortingAttributes(String sortOrder, String sortBy) + throws OrganizationManagementServerException { + + if (StringUtils.isNotBlank(sortBy) || StringUtils.isNotBlank(sortOrder)) { + throw new OrganizationManagementServerException(SORTING_NOT_IMPLEMENTED.getCode(), + "Sorting not supported."); + } + } + + /** + * Validates the offset and limit values for pagination. + * + * @param offset Starting index. + * @param limit Count value. + * @throws OrganizationManagementClientException + */ + private void validateAttributesForPagination(int offset, int limit) + throws OrganizationManagementClientException { + + if (offset < 0) { + throw new OrganizationManagementClientException("Invalid offset requested.", + "Invalid offset requested. Offset value should be zero or greater than zero.", + INVALID_OFFSET.getCode()); + } + + if (limit <= 0) { + throw new OrganizationManagementClientException("Invalid limit requested.", + "Invalid limit requested. Limit value should be greater than zero.", + INVALID_OFFSET.getCode()); + } + } + + private ApplicationBasicInfo buildApplicationBasicInfo(ResultSet appNameResultSet) + throws SQLException, OrganizationManagementException { + + /* + * If you add a new value to basicInfo here, please consider to add it in the + * buildApplicationBasicInfoWithInboundConfig() function also. + */ + ApplicationBasicInfo basicInfo = new ApplicationBasicInfo(); + basicInfo.setApplicationId(appNameResultSet.getInt(ApplicationConstants.ApplicationTableColumns.ID)); + basicInfo.setApplicationName(appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.APP_NAME)); + basicInfo.setDescription(appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.DESCRIPTION)); + + basicInfo.setApplicationResourceId(appNameResultSet.getString(ApplicationConstants + .ApplicationTableColumns.UUID)); + basicInfo.setImageUrl(appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.IMAGE_URL)); + + try { + basicInfo.setAccessUrl(appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.ACCESS_URL)); + if (ApplicationMgtUtil.isConsoleOrMyAccount(basicInfo.getApplicationName())) { + basicInfo.setAccessUrl(ApplicationMgtUtil.resolveOriginUrlFromPlaceholders( + appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.ACCESS_URL), + basicInfo.getApplicationName())); + } + } catch (URLBuilderException e) { + throw new OrganizationManagementException( + "Error occurred when resolving origin of the access URL with placeholders", e); + } + String tenantDomain = IdentityTenantUtil.getTenantDomain(appNameResultSet.getInt( + ApplicationConstants.ApplicationTableColumns.TENANT_ID)); + if (ApplicationMgtUtil.isConsole(basicInfo.getApplicationName())) { + String consoleAccessUrl = getConsoleAccessUrlFromServerConfig(tenantDomain); + if (StringUtils.isNotBlank(consoleAccessUrl)) { + basicInfo.setAccessUrl(consoleAccessUrl); + } + } + if (ApplicationMgtUtil.isMyAccount(basicInfo.getApplicationName())) { + String myAccountAccessUrl = getMyAccountAccessUrlFromServerConfig(tenantDomain); + if (StringUtils.isNotBlank(myAccountAccessUrl)) { + basicInfo.setAccessUrl(myAccountAccessUrl); + } + } + + String username = appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.USERNAME); + String userStoreDomain = appNameResultSet.getString(ApplicationConstants.ApplicationTableColumns.USER_STORE); + int tenantId = appNameResultSet.getInt(ApplicationConstants.ApplicationTableColumns.TENANT_ID); + + if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(userStoreDomain) + && !(tenantId == MultitenantConstants.INVALID_TENANT_ID)) { + User appOwner = new User(); + appOwner.setUserStoreDomain(userStoreDomain); + appOwner.setUserName(username); + appOwner.setTenantDomain(IdentityTenantUtil.getTenantDomain(tenantId)); + + basicInfo.setAppOwner(appOwner); + } + + return basicInfo; + } + + private String resolveSQLFilter(String filter) { + + //To avoid any issues when the filter string is blank or null, assigning "%" to SQLFilter. + String sqlfilter = "SP_APP.APP_NAME LIKE '%'"; + if (StringUtils.isNotBlank(filter)) { + sqlfilter = filter.trim() + .replace(ASTERISK, "%") + .replace("?", "_"); + } + + if (log.isDebugEnabled()) { + log.debug("Input filter: " + filter + " resolved for SQL filter: " + sqlfilter); + } + + return sqlfilter; + } + + private String getDBVendorSpecificDiscoverableAppRetrievalQuery(String dbVendorType) + throws OrganizationManagementServerException { + + if ("MySQL".equals(dbVendorType) || "MariaDB".equals(dbVendorType) + || "H2".equals(dbVendorType) + || "DB2".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL; + } else if ("Oracle".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE; + } else if ("PostgreSQL".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES; + } else if ("Microsoft SQL Server".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL; + } else if ("INFORMIX".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX; + } + + throw new OrganizationManagementServerException("Error while loading discoverable applications from " + + "DB. Database driver for " + dbVendorType + "could not be identified or not supported."); + } + + private String getDBVendorSpecificDiscoverableAppRetrievalQueryByAppName(String dbVendorType) + throws OrganizationManagementServerException { + + if ("MySQL".equals(dbVendorType) || "MariaDB".equals(dbVendorType) + || "H2".equals(dbVendorType) + || "DB2".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL; + } else if ("Oracle".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE; + } else if ("PostgreSQL".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; + } else if ("Microsoft SQL Server".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL; + } else if ("INFORMIX".equals(dbVendorType)) { + return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; + } + + throw new OrganizationManagementServerException("Error while loading discoverable applications from " + + "DB. Database driver for " + dbVendorType + "could not be identified or not supported."); + } } From e9cc3e62a4b6e2113b2c9779776f6ed36b5fe009 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 01:21:18 +0530 Subject: [PATCH 02/10] update the comment --- .../management/application/OrgApplicationManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index 13a61e23..8d6fdf82 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -199,8 +199,8 @@ default List getDiscoverableApplicationBasicInfo(int limit /* * Get the count of discoverable applications. - * @param filter Filter to search for applications (optional). - * @param tenantDomain Tenant domain. + * @param filter Filter to search for applications (optional). + * @param tenantDomain Tenant domain. * @return Count of discoverable applications matching given filter. * @throws OrganizationManagementException If an error occurred when retrieving the count of * discoverable applications. From 77c7640e82d69bb296ed31bafa4f2a6584cbbba2 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 11:57:39 +0530 Subject: [PATCH 03/10] update the method name --- .../application/OrgApplicationManager.java | 4 +- .../OrgApplicationManagerImpl.java | 15 ++-- .../application/constant/SQLConstants.java | 24 +++--- .../application/dao/OrgApplicationMgtDAO.java | 14 +--- .../dao/impl/OrgApplicationMgtDAOImpl.java | 74 +++++++++---------- 5 files changed, 61 insertions(+), 70 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index 8d6fdf82..8b8f5444 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -189,7 +189,7 @@ default Map getChildAppIds(String parentAppId, String parentOrgI * @return List of DiscoverableApplicationBasicInfo of applications matching the given criteria. * @throws OrganizationManagementException If an error occurred when retrieving the discoverable applications. */ - default List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + default List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String filter, String sortOrder, String sortBy, String tenantDomain) throws OrganizationManagementException { @@ -205,7 +205,7 @@ default List getDiscoverableApplicationBasicInfo(int limit * @throws OrganizationManagementException If an error occurred when retrieving the count of * discoverable applications. */ - default int getCountOfDiscoverableApplications(String filter, String tenantDomain) + default int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain) throws OrganizationManagementException { return 0; diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java index 3494efd9..73c0f06d 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java @@ -60,7 +60,6 @@ import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; import org.wso2.carbon.identity.organization.management.ext.Constants; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; -import org.wso2.carbon.identity.organization.management.service.OrganizationManagerImpl; import org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementClientException; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; @@ -712,26 +711,24 @@ public Map getChildAppIds(String parentAppId, String parentOrgId } @Override - public List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + public List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String filter, String sortOrder, String sortBy, String tenantDomain) throws OrganizationManagementException { - OrganizationManagerImpl organizationManager = new OrganizationManagerImpl(); - String rootOrgId = organizationManager.getPrimaryOrganizationId(tenantDomain); + String rootOrgId = getOrganizationManager().getParentOrganizationId(tenantDomain); - return getOrgApplicationMgtDAO().getDiscoverableApplicationBasicInfo(limit, offset, filter, sortOrder, + return getOrgApplicationMgtDAO().getDiscoverableSharedApplicationBasicInfo(limit, offset, filter, sortOrder, sortBy, tenantDomain, rootOrgId); } @Override - public int getCountOfDiscoverableApplications(String filter, String tenantDomain) + public int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain) throws OrganizationManagementException { - OrganizationManagerImpl organizationManager = new OrganizationManagerImpl(); - String rootOrgId = organizationManager.getPrimaryOrganizationId(tenantDomain); + String rootOrgId = getOrganizationManager().getParentOrganizationId(tenantDomain); - return getOrgApplicationMgtDAO().getCountOfDiscoverableApplications(filter, tenantDomain, rootOrgId); + return getOrgApplicationMgtDAO().getCountOfDiscoverableSharedApplications(filter, tenantDomain, rootOrgId); } /** diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java index 8227d097..6d85a8e9 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java @@ -73,7 +73,7 @@ public class SQLConstants { SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_OWNER_ORG_ID + "; AND SHARED_ORG_ID IN (" + SQLPlaceholders.SHARED_ORG_ID_LIST_PLACEHOLDER + ")"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MYSQL = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -82,7 +82,7 @@ public class SQLConstants { "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + "rn = 1 ORDER BY ID DESC LIMIT ?, ?"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_POSTGRES = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -91,7 +91,7 @@ public class SQLConstants { "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + "rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_ORACLE = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY " + "sa.APP_NAME ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn " + @@ -100,7 +100,7 @@ public class SQLConstants { "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + "rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MSSQL = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -109,7 +109,7 @@ public class SQLConstants { "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + "rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_INFORMIX = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -118,7 +118,7 @@ public class SQLConstants { "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + "rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MYSQL = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -127,7 +127,7 @@ public class SQLConstants { "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC LIMIT ?, ?"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -136,7 +136,7 @@ public class SQLConstants { "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_ORACLE = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -145,7 +145,7 @@ public class SQLConstants { "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + "DiscoverableApps WHERE rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MSSQL = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -154,7 +154,7 @@ public class SQLConstants { "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; - public static final String LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX = + public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_INFORMIX = "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + @@ -163,14 +163,14 @@ public class SQLConstants { "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; - public static final String LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT = + public static final String LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_TENANT = "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT count(UUID) " + "FROM DiscoverableApps WHERE rn = 1"; - public static final String LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT = + public static final String LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_APP_NAME_AND_TENANT = "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME ORDER BY CASE " + "WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa JOIN " + "SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java index b137fd59..f055a3e8 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java @@ -153,13 +153,10 @@ default List getSharedApplications(String mainAppId, String * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the * discoverable applications. */ - default List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String filter, String sortOrder, String sortBy, String tenantDomain, String rootOrgId) - throws OrganizationManagementException { - - return null; - } + throws OrganizationManagementException; /* * Returns the count of discoverable applications matching given filter. @@ -170,9 +167,6 @@ default List getDiscoverableApplicationBasicInfo(int limit * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the * discoverable applications count. */ - default int getCountOfDiscoverableApplications(String filter, String tenantDomain, String rootOrgId) - throws OrganizationManagementException { - - return 0; - } + int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain, String rootOrgId) + throws OrganizationManagementException; } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java index 0a5f3a9e..f86099eb 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java @@ -66,18 +66,18 @@ import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.INSERT_SHARED_APP; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.IS_FRAGMENT_APPLICATION; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.IS_FRAGMENT_APPLICATION_H2; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT; -import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MSSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MYSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_ORACLE; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_INFORMIX; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MSSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MYSQL; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_ORACLE; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_POSTGRES; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_APP_NAME_AND_TENANT; +import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_TENANT; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_MAIN_APP_ID; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_METADATA_NAME; import static org.wso2.carbon.identity.organization.management.application.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_METADATA_VALUE; @@ -301,7 +301,7 @@ public List getSharedApplications(String mainAppId, String } @Override - public List getDiscoverableApplicationBasicInfo(int limit, int offset, String filter, + public List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String filter, String sortOrder, String sortBy, String tenantDomain, String rootOrgId) throws OrganizationManagementException { @@ -311,7 +311,7 @@ public List getDiscoverableApplicationBasicInfo(int limit, // TODO: 17/9/24 : Enforce a max limit if (StringUtils.isBlank(filter) || ASTERISK.equals(filter)) { - return getDiscoverableApplicationBasicInfo(limit, offset, tenantDomain, rootOrgId); + return getDiscoverableSharedApplicationBasicInfo(limit, offset, tenantDomain, rootOrgId); } String filterResolvedForSQL = resolveSQLFilter(filter); @@ -323,7 +323,7 @@ public List getDiscoverableApplicationBasicInfo(int limit, try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - getDBVendorSpecificDiscoverableAppRetrievalQueryByAppName(databaseVendorType))) { + getDBVendorSpecificDiscoverableSharedAppRetrievalQueryByAppName(databaseVendorType))) { statement.setString(1, tenantDomain); statement.setString(2, filterResolvedForSQL); statement.setString(3, rootOrgId); @@ -345,16 +345,16 @@ public List getDiscoverableApplicationBasicInfo(int limit, } @Override - public int getCountOfDiscoverableApplications(String filter, String tenantDomain, String rootOrgId) + public int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain, String rootOrgId) throws OrganizationManagementException { if (log.isDebugEnabled()) { - log.debug("Getting count of discoverable applications matching filter: " + filter + " in tenantDomain: " - + tenantDomain); + log.debug("Getting count of discoverable shared applications matching filter: " + filter + " in " + + "tenantDomain: " + tenantDomain); } if (StringUtils.isBlank(filter) || ASTERISK.equals(filter)) { - return getCountOfDiscoverableApplications(tenantDomain, rootOrgId); + return getCountOfDiscoverableSharedApplications(tenantDomain, rootOrgId); } int count = 0; @@ -363,7 +363,7 @@ public int getCountOfDiscoverableApplications(String filter, String tenantDomain try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - LOAD_DISCOVERABLE_APP_COUNT_BY_APP_NAME_AND_TENANT)) { + LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_APP_NAME_AND_TENANT)) { statement.setString(1, tenantDomain); statement.setString(2, filterResolvedForSQL); statement.setString(3, rootOrgId); @@ -382,7 +382,7 @@ public int getCountOfDiscoverableApplications(String filter, String tenantDomain return count; } - private int getCountOfDiscoverableApplications(String tenantDomain, String rootOrgId) + private int getCountOfDiscoverableSharedApplications(String tenantDomain, String rootOrgId) throws OrganizationManagementException { int count; @@ -390,7 +390,7 @@ private int getCountOfDiscoverableApplications(String tenantDomain, String rootO try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - LOAD_DISCOVERABLE_APP_COUNT_BY_TENANT)) { + LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_TENANT)) { statement.setString(1, tenantDomain); statement.setString(2, rootOrgId); @@ -401,13 +401,13 @@ private int getCountOfDiscoverableApplications(String tenantDomain, String rootO } } catch (SQLException e) { throw new OrganizationManagementServerException("Error while getting count of discoverable " + - "applications in tenantDomain: " + tenantDomain); + "shared applications in tenantDomain: " + tenantDomain); } return count; } - private List getDiscoverableApplicationBasicInfo(int limit, int offset, + private List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String tenantDomain, String rootOrgId) throws OrganizationManagementException { @@ -418,7 +418,7 @@ private List getDiscoverableApplicationBasicInfo(int limit try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - getDBVendorSpecificDiscoverableAppRetrievalQuery(databaseVendorType))) { + getDBVendorSpecificDiscoverableSharedAppRetrievalQuery(databaseVendorType))) { statement.setString(1, tenantDomain); statement.setString(2, rootOrgId); statement.setInt(3, offset); @@ -562,42 +562,42 @@ private String resolveSQLFilter(String filter) { return sqlfilter; } - private String getDBVendorSpecificDiscoverableAppRetrievalQuery(String dbVendorType) + private String getDBVendorSpecificDiscoverableSharedAppRetrievalQuery(String dbVendorType) throws OrganizationManagementServerException { if ("MySQL".equals(dbVendorType) || "MariaDB".equals(dbVendorType) || "H2".equals(dbVendorType) || "DB2".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_MYSQL; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MYSQL; } else if ("Oracle".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_ORACLE; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_ORACLE; } else if ("PostgreSQL".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_POSTGRES; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_POSTGRES; } else if ("Microsoft SQL Server".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_MSSQL; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MSSQL; } else if ("INFORMIX".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_INFORMIX; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_INFORMIX; } throw new OrganizationManagementServerException("Error while loading discoverable applications from " + "DB. Database driver for " + dbVendorType + "could not be identified or not supported."); } - private String getDBVendorSpecificDiscoverableAppRetrievalQueryByAppName(String dbVendorType) + private String getDBVendorSpecificDiscoverableSharedAppRetrievalQueryByAppName(String dbVendorType) throws OrganizationManagementServerException { if ("MySQL".equals(dbVendorType) || "MariaDB".equals(dbVendorType) || "H2".equals(dbVendorType) || "DB2".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MYSQL; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MYSQL; } else if ("Oracle".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_ORACLE; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_ORACLE; } else if ("PostgreSQL".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL; } else if ("Microsoft SQL Server".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_MSSQL; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MSSQL; } else if ("INFORMIX".equals(dbVendorType)) { - return LOAD_DISCOVERABLE_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; + return LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_INFORMIX; } throw new OrganizationManagementServerException("Error while loading discoverable applications from " + From 587097661a15777838ef2978a1533c5ed0f883d3 Mon Sep 17 00:00:00 2001 From: Asha Sulaiman <165079T@uom.lk> Date: Wed, 18 Sep 2024 12:02:25 +0530 Subject: [PATCH 04/10] Update log to final varialble --- .../application/dao/impl/OrgApplicationMgtDAOImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java index f86099eb..990afda1 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java @@ -105,7 +105,7 @@ */ public class OrgApplicationMgtDAOImpl implements OrgApplicationMgtDAO { - private Log log = LogFactory.getLog(OrgApplicationMgtDAOImpl.class); + private static final Log log = LogFactory.getLog(OrgApplicationMgtDAOImpl.class); private static final String ASTERISK = "*"; @Override From c5ea811dce5d58d83f13faa98f5d3c1c06baea64 Mon Sep 17 00:00:00 2001 From: Asha Sulaiman <165079T@uom.lk> Date: Wed, 18 Sep 2024 13:21:12 +0530 Subject: [PATCH 05/10] Get roorOrg ID --- .../management/application/OrgApplicationManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java index 73c0f06d..a9b97381 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java @@ -716,7 +716,7 @@ public List getDiscoverableSharedApplicationBasicInfo(int String tenantDomain) throws OrganizationManagementException { - String rootOrgId = getOrganizationManager().getParentOrganizationId(tenantDomain); + String rootOrgId = getOrganizationManager().getPrimaryOrganizationId(tenantDomain); return getOrgApplicationMgtDAO().getDiscoverableSharedApplicationBasicInfo(limit, offset, filter, sortOrder, sortBy, tenantDomain, rootOrgId); @@ -726,7 +726,7 @@ public List getDiscoverableSharedApplicationBasicInfo(int public int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain) throws OrganizationManagementException { - String rootOrgId = getOrganizationManager().getParentOrganizationId(tenantDomain); + String rootOrgId = getOrganizationManager().getPrimaryOrganizationId(tenantDomain); return getOrgApplicationMgtDAO().getCountOfDiscoverableSharedApplications(filter, tenantDomain, rootOrgId); } From cf890c07196dd9bcb9e02513024c4543b29fc75b Mon Sep 17 00:00:00 2001 From: Asha Sulaiman <165079T@uom.lk> Date: Wed, 18 Sep 2024 13:23:08 +0530 Subject: [PATCH 06/10] Remove additional line --- .../management/application/OrgApplicationManagerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java index a9b97381..d6c325a5 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java @@ -717,7 +717,6 @@ public List getDiscoverableSharedApplicationBasicInfo(int throws OrganizationManagementException { String rootOrgId = getOrganizationManager().getPrimaryOrganizationId(tenantDomain); - return getOrgApplicationMgtDAO().getDiscoverableSharedApplicationBasicInfo(limit, offset, filter, sortOrder, sortBy, tenantDomain, rootOrgId); } @@ -727,7 +726,6 @@ public int getCountOfDiscoverableSharedApplications(String filter, String tenant throws OrganizationManagementException { String rootOrgId = getOrganizationManager().getPrimaryOrganizationId(tenantDomain); - return getOrgApplicationMgtDAO().getCountOfDiscoverableSharedApplications(filter, tenantDomain, rootOrgId); } From 40b0a775d092834e8dad0c9cd3c4fce52f16ecf4 Mon Sep 17 00:00:00 2001 From: Asha Sulaiman <165079T@uom.lk> Date: Wed, 18 Sep 2024 13:25:06 +0530 Subject: [PATCH 07/10] Remove additional line. --- .../application/dao/impl/OrgApplicationMgtDAOImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java index 990afda1..159c779e 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java @@ -558,7 +558,6 @@ private String resolveSQLFilter(String filter) { if (log.isDebugEnabled()) { log.debug("Input filter: " + filter + " resolved for SQL filter: " + sqlfilter); } - return sqlfilter; } From 42f31504bfc7e763fa788ff74fac2d2423745776 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 13:33:19 +0530 Subject: [PATCH 08/10] update the comments --- .../application/OrgApplicationManager.java | 22 +++++++++------- .../application/dao/OrgApplicationMgtDAO.java | 26 ++++++++++--------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index 8b8f5444..a9406e68 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -178,13 +178,14 @@ default Map getChildAppIds(String parentAppId, String parentOrgI throw new NotImplementedException("getChildAppIds method is not implemented in " + this.getClass().getName()); } - /* + /** * Get the discoverable application basic info. - * @param limit Maximum no of applications to be returned in the result set (optional). - * @param offset Zero based index of the first application to be returned in the result set (optional). - * @param filter Filter to search for applications (optional). - * @param sortOrder Sort order, ascending or descending (optional). - * @param sortBy Attribute to sort from (optional). + * + * @param limit Maximum no of applications to be returned in the result set (optional). + * @param offset Zero based index of the first application to be returned in the result set (optional). + * @param filter Filter to search for applications (optional). + * @param sortOrder Sort order, ascending or descending (optional). + * @param sortBy Attribute to sort from (optional). * @param tenantDomain Tenant domain. * @return List of DiscoverableApplicationBasicInfo of applications matching the given criteria. * @throws OrganizationManagementException If an error occurred when retrieving the discoverable applications. @@ -197,13 +198,14 @@ default List getDiscoverableSharedApplicationBasicInfo(int return null; } - /* + /** * Get the count of discoverable applications. - * @param filter Filter to search for applications (optional). - * @param tenantDomain Tenant domain. + * + * @param filter Filter to search for applications (optional). + * @param tenantDomain Tenant domain. * @return Count of discoverable applications matching given filter. * @throws OrganizationManagementException If an error occurred when retrieving the count of - * discoverable applications. + * discoverable applications. */ default int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain) throws OrganizationManagementException { diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java index f055a3e8..07e74154 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java @@ -142,30 +142,32 @@ default List getSharedApplications(String mainAppId, String /** * Returns the basic information of the shared applications - * @param limit Maximum no of applications to be returned in the result set (optional). - * @param offset Zero based index of the first application to be returned in the result set (optional). - * @param filter Filter to search for applications (optional). - * @param sortOrder Sort order, ascending or descending (optional). - * @param sortBy Attribute to sort from (optional). + * + * @param limit Maximum no of applications to be returned in the result set (optional). + * @param offset Zero based index of the first application to be returned in the result set (optional). + * @param filter Filter to search for applications (optional). + * @param sortOrder Sort order, ascending or descending (optional). + * @param sortBy Attribute to sort from (optional). * @param tenantDomain Tenant domain. - * @param rootOrgId Root organization ID. + * @param rootOrgId Root organization ID. * @return List of DiscoverableApplicationBasicInfo of applications matching the given criteria. * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the - * discoverable applications. + * discoverable applications. */ List getDiscoverableSharedApplicationBasicInfo(int limit, int offset, String filter, String sortOrder, String sortBy, String tenantDomain, String rootOrgId) throws OrganizationManagementException; - /* + /** * Returns the count of discoverable applications matching given filter. - * @param filter Filter to search for applications (optional). - * @param tenantDomain Tenant domain. - * @param rootOrgId Root organization ID. + * + * @param filter Filter to search for applications (optional). + * @param tenantDomain Tenant domain. + * @param rootOrgId Root organization ID. * @return Count of discoverable applications matching given filter. * @throws OrganizationManagementException The server exception is thrown in a failure when retrieving the - * discoverable applications count. + * discoverable applications count. */ int getCountOfDiscoverableSharedApplications(String filter, String tenantDomain, String rootOrgId) throws OrganizationManagementException; From 1e4bdf5489c422e3a6bc1eae74ed2ee39103f804 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 16:44:55 +0530 Subject: [PATCH 09/10] update the quries --- .../application/constant/SQLConstants.java | 159 +++++++++--------- 1 file changed, 79 insertions(+), 80 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java index 6d85a8e9..3d8f8cf4 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/SQLConstants.java @@ -74,108 +74,107 @@ public class SQLConstants { SQLPlaceholders.SHARED_ORG_ID_LIST_PLACEHOLDER + ")"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MYSQL = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + - "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + - "rn = 1 ORDER BY ID DESC LIMIT ?, ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') " + + "ORDER BY ID DESC LIMIT ?, ?"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_POSTGRES = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + - "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + - "rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') " + + "ORDER BY ID DESC OFFSET ? LIMIT ?"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_ORACLE = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY " + - "sa.APP_NAME ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn " + - "FROM SP_APP sa JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + - "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + - "rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') " + + "BETWEEN ? AND ? ORDER BY ID DESC"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_MSSQL = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + - "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + - "rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') " + + "ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_INFORMIX = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT ID, APP_NAME, " + - "DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM DiscoverableApps WHERE " + - "rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') " + + "ORDER BY ID DESC SKIP ? LIMIT ?"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MYSQL = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + - "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC LIMIT ?, ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1') ORDER BY ID DESC LIMIT ?, ?"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_POSTGRESL = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + - "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? LIMIT ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1') ORDER BY ID DESC OFFSET ? LIMIT ?"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_ORACLE = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + - "DiscoverableApps WHERE rn = 1 BETWEEN ? AND ? ORDER BY ID DESC"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1') BETWEEN ? AND ? ORDER BY ID DESC"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_MSSQL = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + - "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1') ORDER BY ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; public static final String LOAD_DISCOVERABLE_SHARED_APPS_BY_TENANT_AND_APP_NAME_INFORMIX = - "WITH DiscoverableApps AS ( SELECT sa.ID, sa.APP_NAME, sa.DESCRIPTION, sa.UUID, sa.IMAGE_URL, " + - "sa.ACCESS_URL, sa.USERNAME, sa.USER_STORE, sa.TENANT_ID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT ID, APP_NAME, DESCRIPTION, UUID, IMAGE_URL, ACCESS_URL, USERNAME, USER_STORE, TENANT_ID FROM " + - "DiscoverableApps WHERE rn = 1 ORDER BY ID DESC SKIP ? LIMIT ?"; + "SELECT sa_shared.ID, sa_shared.APP_NAME, sa_shared.DESCRIPTION, sa_shared.UUID, sa_shared.IMAGE_URL, " + + "CASE WHEN sa_shared.ACCESS_URL IS NOT NULL THEN sa_shared.ACCESS_URL ELSE sa_main.ACCESS_URL END AS " + + "ACCESS_URL, sa_shared.USERNAME, sa_shared.USER_STORE, sa_shared.TENANT_ID FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1') ORDER BY ID DESC SKIP ? LIMIT ?"; public static final String LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_TENANT = - "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME " + - "ORDER BY CASE WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa " + - "JOIN SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND ssa.OWNER_ORG_ID = ? ) SELECT count(UUID) " + - "FROM DiscoverableApps WHERE rn = 1"; + "SELECT COUNT(sa_shared.UUID) FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR sa_shared.IS_DISCOVERABLE = '1') "; public static final String LOAD_DISCOVERABLE_SHARED_APP_COUNT_BY_APP_NAME_AND_TENANT = - "WITH DiscoverableApps AS ( SELECT sa.UUID, ROW_NUMBER() OVER ( PARTITION BY sa.APP_NAME ORDER BY CASE " + - "WHEN sa.UUID = ssa.SHARED_APP_ID THEN 1 ELSE 2 END, sa.ID DESC ) AS rn FROM SP_APP sa JOIN " + - "SP_SHARED_APP ssa ON sa.UUID = ssa.SHARED_APP_ID OR sa.UUID = ssa.MAIN_APP_ID WHERE " + - "ssa.SHARED_ORG_ID = ? AND sa.IS_DISCOVERABLE = '1' AND sa.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? ) " + - "SELECT count(UUID) FROM DiscoverableApps WHERE rn = 1"; + "SELECT COUNT(sa_shared.UUID) FROM SP_SHARED_APP ssa " + + "JOIN SP_APP sa_main ON ssa.MAIN_APP_ID = sa_main.UUID " + + "JOIN SP_APP sa_shared ON ssa.SHARED_APP_ID = sa_shared.UUID WHERE ssa.SHARED_ORG_ID = ? AND " + + "sa_shared.APP_NAME LIKE ? AND ssa.OWNER_ORG_ID = ? AND (sa_main.IS_DISCOVERABLE = '1' OR " + + "sa_shared.IS_DISCOVERABLE = '1')"; private SQLConstants() { From 4ad6969540834036c63b27c98e68fd8f97a805b1 Mon Sep 17 00:00:00 2001 From: asha15 <165079T@uom.lk> Date: Wed, 18 Sep 2024 18:41:40 +0530 Subject: [PATCH 10/10] update the comments --- .../management/application/OrgApplicationManager.java | 4 ++-- .../management/application/dao/OrgApplicationMgtDAO.java | 4 ++-- .../application/dao/impl/OrgApplicationMgtDAOImpl.java | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index a9406e68..80dadcdd 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -179,7 +179,7 @@ default Map getChildAppIds(String parentAppId, String parentOrgI } /** - * Get the discoverable application basic info. + * Get the discoverable shared application basic info. * * @param limit Maximum no of applications to be returned in the result set (optional). * @param offset Zero based index of the first application to be returned in the result set (optional). @@ -199,7 +199,7 @@ default List getDiscoverableSharedApplicationBasicInfo(int } /** - * Get the count of discoverable applications. + * Get the count of discoverable shared applications. * * @param filter Filter to search for applications (optional). * @param tenantDomain Tenant domain. diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java index 07e74154..0ddd9081 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/OrgApplicationMgtDAO.java @@ -141,7 +141,7 @@ default List getSharedApplications(String mainAppId, String } /** - * Returns the basic information of the shared applications + * Returns the basic information of the discoverable shared applications * * @param limit Maximum no of applications to be returned in the result set (optional). * @param offset Zero based index of the first application to be returned in the result set (optional). @@ -160,7 +160,7 @@ List getDiscoverableSharedApplicationBasicInfo(int limit, throws OrganizationManagementException; /** - * Returns the count of discoverable applications matching given filter. + * Returns the count of discoverable shared applications matching given filter. * * @param filter Filter to search for applications (optional). * @param tenantDomain Tenant domain. diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java index 159c779e..9bfd73f2 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/dao/impl/OrgApplicationMgtDAOImpl.java @@ -340,7 +340,6 @@ public List getDiscoverableSharedApplicationBasicInfo(int throw new OrganizationManagementException("Error while getting application basic information" + " for discoverable applications in tenantDomain: " + tenantDomain, e); } - return Collections.unmodifiableList(applicationBasicInfoList); } @@ -378,7 +377,6 @@ public int getCountOfDiscoverableSharedApplications(String filter, String tenant throw new OrganizationManagementServerException("Error while getting count of discoverable " + "applications matching filter:" + filter + " in tenantDomain: " + tenantDomain); } - return count; } @@ -403,7 +401,6 @@ private int getCountOfDiscoverableSharedApplications(String tenantDomain, String throw new OrganizationManagementServerException("Error while getting count of discoverable " + "shared applications in tenantDomain: " + tenantDomain); } - return count; } @@ -434,7 +431,6 @@ private List getDiscoverableSharedApplicationBasicInfo(int throw new OrganizationManagementException("Error while getting application basic information" + " for discoverable applications in tenantDomain: " + tenantDomain, e); } - return Collections.unmodifiableList(applicationBasicInfoList); }