From 3c17da28191076e3e8eafc601e451e993d29759e Mon Sep 17 00:00:00 2001 From: shnrndk Date: Sun, 19 Nov 2023 11:38:54 +0530 Subject: [PATCH 01/25] ChangeApiProvider rest api added --- .../apimgt/persistence/APIPersistence.java | 13 ++++ .../persistence/RegistryPersistenceImpl.java | 72 +++++++++++++++++++ .../src/main/resources/admin-api.yaml | 56 ++++++++++++++- .../src/main/webapp/WEB-INF/beans.xml | 1 + 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java index 583bd1d2ab38..391fda941841 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java @@ -16,6 +16,8 @@ package org.wso2.carbon.apimgt.persistence; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.model.Tag; import org.wso2.carbon.apimgt.persistence.dto.DevPortalAPI; import org.wso2.carbon.apimgt.persistence.dto.DevPortalAPISearchResult; @@ -508,4 +510,15 @@ PublisherAPIProductSearchResult searchAPIProductsForPublisher(Organization org, */ Set getAllTags(Organization org, UserContext ctx) throws APIPersistenceException; + /** + * + * @param providerName + * @param apiId + * @param org + * @param ctx + * @return + * @throws APIPersistenceException + */ + String changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) + throws APIPersistenceException, APIManagementException; } \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index f567d2896037..b75599c2d87d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.http.entity.ContentType; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; @@ -3737,4 +3738,75 @@ public int compare(Tag o1, Tag o2) { } } } + + @Override + public String changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) + throws APIPersistenceException, APIManagementException { + + boolean isTenantFlowStarted = false; + boolean transactionCommitted = false; + RegistryHolder holder = getRegistry(org); + Registry userRegistry = holder.getRegistry(); + isTenantFlowStarted = holder.isTenantFlowStarted(); + try { + String oldArtifactPath = GovernanceUtils.getArtifactPath(userRegistry, apiId); + Resource apiResource = userRegistry.get(oldArtifactPath); + if (apiResource != null) { + //userRegistry.beginTransaction(); + GenericArtifactManager artifactManager = RegistryPersistenceUtil.getArtifactManager(userRegistry, + APIConstants.API_KEY); + if (artifactManager == null) { + String errorMessage = "Artifact manager is null when changing the provider name of " + apiId; + log.error(errorMessage); + throw new APIPersistenceException(errorMessage); + } + //Moving the registry file + GenericArtifact artifact = getAPIArtifact(apiId, userRegistry); + String oldProvider = artifact.getAttribute(APIConstants.API_OVERVIEW_PROVIDER); + String newProvider = providerName; + String[] artifactPathChunks = oldArtifactPath.split(oldProvider); + String newArtifactApiPath = artifactPathChunks[0] + newProvider + artifactPathChunks[1]; + userRegistry.move(oldArtifactPath, newArtifactApiPath); + String oldArtifactSwaggerPath = oldArtifactPath.replaceFirst("/api$", + "/swagger.json"); + String newArtifactSwaggerPath = newArtifactApiPath.replaceFirst("/api$", + "/swagger.json"); + userRegistry.move(oldArtifactSwaggerPath, newArtifactSwaggerPath); + int time=0; + while (!userRegistry.resourceExists(newArtifactSwaggerPath) && + !userRegistry.resourceExists(newArtifactApiPath) || time > 5000) { + Thread.sleep(1000); + log.info("-------------Resource Not Existed-------------"); + time += 1000; + } + Resource newAPIArtifact = userRegistry.get(newArtifactApiPath); + Resource newSwaggerArtifact = userRegistry.get(newArtifactSwaggerPath); + userRegistry.put(newArtifactApiPath,newAPIArtifact); + userRegistry.put(newArtifactSwaggerPath,newSwaggerArtifact); + //Thread.sleep(10000); + artifact = getAPIArtifact(apiId, userRegistry); + artifact.setAttribute(APIConstants.API_OVERVIEW_PROVIDER, newProvider); + artifactManager.updateGenericArtifact(artifact); + + //userRegistry.commitTransaction(); + transactionCommitted=true; + } + } catch (RegistryException e) { + throw new APIManagementException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + try { + if (userRegistry != null && !transactionCommitted) { + userRegistry.rollbackTransaction(); + } + } catch (RegistryException ex) { + log.error("Error while rolling back the transaction for Api Provider Change"); + } + if (isTenantFlowStarted) { + PrivilegedCarbonContext.endTenantFlow(); + } + } + return null; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml index 1d7e2e27960b..f69b3d2618ee 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml @@ -3202,6 +3202,43 @@ paths: source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -F "type=WSO2-IS" "https://127.0.0.1:9443/api/am/admin/v4/key-managers/discover"' + ###################################################### + # API Provider Resource + ###################################################### + /provider/{providerName}/apis/{apiId}: + put: + tags: + - Api Provider Change + summary: Update the api provider + description: | + Update the api provider + parameters: + - $ref: '#/components/parameters/providerName' + - $ref: '#/components/parameters/apiId' + operationId: providerProviderNameApisApiIdPut + responses: + 200: + description: | + OK. + Api Provider updated. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + security: + - OAuth2Security: + - apim:admin + x-code-samples: + - lang: Curl + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: application/json" "https://127.0.0.1:9443/api/am/admin/v4/provider/admin/apis/33662a62-8db1-4d75-af08-afd63c6bd0b4"' + components: schemas: Error: @@ -5196,6 +5233,22 @@ components: required: true schema: type: string + providerName: + name: providerName + in: path + description: | + Provider Name + required: true + schema: + type: string + apiId: + name: apiId + in: path + description: | + API Id + required: true + schema: + type: string securitySchemes: OAuth2Security: type: oauth2 @@ -5234,4 +5287,5 @@ components: apim:scope_manage: Manage system scopes apim:role_manage: Manage system roles apim:admin_application_view: View Applications - apim:keymanagers_manage: Manage Key Managers \ No newline at end of file + apim:keymanagers_manage: Manage Key Managers + apim:api_provider_change: Retrieve and manage applications \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml index 6f7967ffacc4..f33f5e510824 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml @@ -49,6 +49,7 @@ + From 3c5bbc4b66b2500e193a0a688c7a27c5bbc0d696 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 22 Nov 2023 17:08:33 +0530 Subject: [PATCH 02/25] Added support to change provider by get artifacts from apiid. --- .../carbon/apimgt/persistence/RegistryPersistenceImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index b75599c2d87d..04161abe4f81 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -285,7 +285,7 @@ public String addAPIRevision(Organization org, String apiUUID, int revisionId) t if (apiArtifact != null) { API api = RegistryPersistenceUtil.getApiForPublishing(registry, apiArtifact); APIIdentifier apiId = api.getId(); - String apiPath = RegistryPersistenceUtil.getAPIPath(apiId); + String apiPath = getAPIArtifact(api.getUuid(),registry).getPath(); int prependIndex = apiPath.lastIndexOf("/api"); String apiSourcePath = apiPath.substring(0, prependIndex); String revisionTargetPath = RegistryPersistenceUtil.getRevisionPath(apiId.getUUID(), revisionId); @@ -475,7 +475,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw tenantFlowStarted = holder.isTenantFlowStarted(); registry.beginTransaction(); - String apiArtifactId = registry.get(RegistryPersistenceUtil.getAPIPath(api.getId())).getUUID(); + String apiArtifactId = api.getUuid(); GenericArtifactManager artifactManager = RegistryPersistenceUtil.getArtifactManager(registry, APIConstants.API_KEY); if (artifactManager == null) { String errorMessage = "Artifact manager is null when updating API artifact ID " + api.getId(); @@ -800,8 +800,7 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep String path = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getApiName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion(); - Resource apiResource = registry.get(path); - String artifactId = apiResource.getUUID(); + String artifactId = getAPIArtifact(apiId,registry).getId(); artifactManager.removeGenericArtifact(artifactId); String thumbPath = RegistryPersistenceUtil.getIconPath(identifier); From 583cdab1acdc7d71fa869ab416ab4f44ceb97224 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 22 Nov 2023 17:20:24 +0530 Subject: [PATCH 03/25] Remove the api path move logic --- .../persistence/RegistryPersistenceImpl.java | 33 ++----------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 04161abe4f81..8a5f9d8ed3c5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -3751,7 +3751,7 @@ public String changeApiProvider(String providerName, String apiId, String org, M String oldArtifactPath = GovernanceUtils.getArtifactPath(userRegistry, apiId); Resource apiResource = userRegistry.get(oldArtifactPath); if (apiResource != null) { - //userRegistry.beginTransaction(); + userRegistry.beginTransaction(); GenericArtifactManager artifactManager = RegistryPersistenceUtil.getArtifactManager(userRegistry, APIConstants.API_KEY); if (artifactManager == null) { @@ -3759,41 +3759,14 @@ public String changeApiProvider(String providerName, String apiId, String org, M log.error(errorMessage); throw new APIPersistenceException(errorMessage); } - //Moving the registry file GenericArtifact artifact = getAPIArtifact(apiId, userRegistry); - String oldProvider = artifact.getAttribute(APIConstants.API_OVERVIEW_PROVIDER); - String newProvider = providerName; - String[] artifactPathChunks = oldArtifactPath.split(oldProvider); - String newArtifactApiPath = artifactPathChunks[0] + newProvider + artifactPathChunks[1]; - userRegistry.move(oldArtifactPath, newArtifactApiPath); - String oldArtifactSwaggerPath = oldArtifactPath.replaceFirst("/api$", - "/swagger.json"); - String newArtifactSwaggerPath = newArtifactApiPath.replaceFirst("/api$", - "/swagger.json"); - userRegistry.move(oldArtifactSwaggerPath, newArtifactSwaggerPath); - int time=0; - while (!userRegistry.resourceExists(newArtifactSwaggerPath) && - !userRegistry.resourceExists(newArtifactApiPath) || time > 5000) { - Thread.sleep(1000); - log.info("-------------Resource Not Existed-------------"); - time += 1000; - } - Resource newAPIArtifact = userRegistry.get(newArtifactApiPath); - Resource newSwaggerArtifact = userRegistry.get(newArtifactSwaggerPath); - userRegistry.put(newArtifactApiPath,newAPIArtifact); - userRegistry.put(newArtifactSwaggerPath,newSwaggerArtifact); - //Thread.sleep(10000); - artifact = getAPIArtifact(apiId, userRegistry); - artifact.setAttribute(APIConstants.API_OVERVIEW_PROVIDER, newProvider); + artifact.setAttribute(APIConstants.API_OVERVIEW_PROVIDER, providerName); artifactManager.updateGenericArtifact(artifact); - - //userRegistry.commitTransaction(); + userRegistry.commitTransaction(); transactionCommitted=true; } } catch (RegistryException e) { throw new APIManagementException(e); - } catch (InterruptedException e) { - throw new RuntimeException(e); } finally { try { if (userRegistry != null && !transactionCommitted) { From 982daf1fe9e9b918727d65179c02b58af6d8495c Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 27 Nov 2023 10:24:51 +0530 Subject: [PATCH 04/25] Added the view apis rest api in admin portal and fixed bugs in the changeprovider method. --- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 12 + .../impl/dao/constants/SQLConstants.java | 2 + .../apimgt/persistence/APIPersistence.java | 12 +- .../persistence/RegistryPersistenceImpl.java | 7 +- .../v1/utils/mappings/APIInfoMappingUtil.java | 62 ++++- .../src/main/resources/admin-api.yaml | 224 +++++++++++++++++- .../src/main/webapp/WEB-INF/beans.xml | 2 +- 7 files changed, 299 insertions(+), 22 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index d1f902ceee8a..ac431494a3d5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -18066,6 +18066,18 @@ private void updateAPIServiceMapping(int apiId, String serviceKey, String md5, i } } + public void updateApiProvider(String apiUuid, String providerName) + throws APIManagementException, SQLException { + try (Connection connection = APIMgtDBUtil.getConnection()) { + PreparedStatement statement = connection.prepareStatement(SQLConstants.UPDATE_API_PROVIDER_SQL); + statement.setString(1, providerName); + statement.setString(2, apiUuid); + statement.executeUpdate(); + } catch (SQLException e) { + handleException("Error while updating the change API provider of " + apiUuid, e); + } + } + private void updateLatestRevisionNumber(Connection connection, String apiUUID, int revisionId) throws SQLException { try (PreparedStatement preparedStatement = diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java index 38ce9feaab97..996dbbacefe8 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java @@ -175,6 +175,8 @@ public class SQLConstants { " MD5 = ? " + " WHERE API_ID = ?"; + public static final String UPDATE_API_PROVIDER_SQL = "UPDATE AM_API SET API_PROVIDER = ? WHERE API_UUID = ?"; + public static final String GET_MD5_VALUE_OF_SERVICE_BY_API_ID_SQL = "SELECT " + " AM_SERVICE_CATALOG.MD5 AS SERVICE_MD5, " + " AM_SERVICE_CATALOG.SERVICE_NAME, " + diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java index 391fda941841..a7cbcd70aa9f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java @@ -510,15 +510,5 @@ PublisherAPIProductSearchResult searchAPIProductsForPublisher(Organization org, */ Set getAllTags(Organization org, UserContext ctx) throws APIPersistenceException; - /** - * - * @param providerName - * @param apiId - * @param org - * @param ctx - * @return - * @throws APIPersistenceException - */ - String changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) - throws APIPersistenceException, APIManagementException; + void changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) throws APIManagementException, APIPersistenceException; } \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 8a5f9d8ed3c5..d4546a91e959 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -3739,8 +3739,8 @@ public int compare(Tag o1, Tag o2) { } @Override - public String changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) - throws APIPersistenceException, APIManagementException { + public void changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) + throws APIPersistenceException { boolean isTenantFlowStarted = false; boolean transactionCommitted = false; @@ -3766,7 +3766,7 @@ public String changeApiProvider(String providerName, String apiId, String org, M transactionCommitted=true; } } catch (RegistryException e) { - throw new APIManagementException(e); + throw new APIPersistenceException("Error while Changing the api Provider", e); } finally { try { if (userRegistry != null && !transactionCommitted) { @@ -3779,6 +3779,5 @@ public String changeApiProvider(String providerName, String apiId, String org, M PrivilegedCarbonContext.endTenantFlow(); } } - return null; } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java index d548d925deb7..3c5faaa9473a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java @@ -17,19 +17,21 @@ package org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.APIIdentifier; import org.wso2.carbon.apimgt.impl.utils.APIUtil; -import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoDTO; -import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoListDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.*; +import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class APIInfoMappingUtil { + private static final String EMPTY_STRING = ""; /** * Converts a APIIdentifier object into APIInfoDTO * @@ -70,4 +72,56 @@ public static APIInfoListDTO fromAPIInfoListToDTO(List apiIds) th apiInfoListDTO.setCount(apiInfoDTOs.size()); return apiInfoListDTO; } + + public static APIListDTO fromAPIListToInfoDTO(List apiList) throws APIManagementException { + APIListDTO apiListDTO = new APIListDTO(); + List apiInfoDTOs = apiListDTO.getList(); + for (API api : apiList) { + apiInfoDTOs.add(fromAPIToInfoDTO(api)); + } + apiListDTO.setCount(apiInfoDTOs.size()); + return apiListDTO; + } + + private static APIInfomationDTO fromAPIToInfoDTO(API api) { + APIInfomationDTO apiInfoDTO = new APIInfomationDTO(); + APIIdentifier apiId = api.getId(); + apiInfoDTO.setName(apiId.getName()); + apiInfoDTO.setVersion(apiId.getVersion()); + apiInfoDTO.setProvider(apiId.getProviderName()); + return apiInfoDTO; + } + + public static void setPaginationParams(Object apiListDTO, String query, int offset, int limit, int size) { + + //acquiring pagination parameters and setting pagination urls + Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, size); + String paginatedPrevious = EMPTY_STRING; + String paginatedNext = EMPTY_STRING; + + if (paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET) != null) { + paginatedPrevious = RestApiCommonUtil + .getAPIPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), + paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_LIMIT), query); + } + + if (paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET) != null) { + paginatedNext = RestApiCommonUtil + .getAPIPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET), + paginatedParams.get(RestApiConstants.PAGINATION_NEXT_LIMIT), query); + } + + PaginationApisDTO paginationDTO = getPaginationDTO(limit, offset, size, paginatedNext, paginatedPrevious); + ((APIListDTO) apiListDTO).setPagination(paginationDTO); + } + + private static PaginationApisDTO getPaginationDTO(int limit, int offset, int total, String next, String previous) { + PaginationApisDTO paginationDTO = new PaginationApisDTO(); + paginationDTO.setLimit(limit); + paginationDTO.setOffset(offset); + paginationDTO.setTotal(total); + paginationDTO.setNext(next); + paginationDTO.setPrevious(previous); + return paginationDTO; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml index f69b3d2618ee..6e555ade3134 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml @@ -3205,7 +3205,7 @@ paths: ###################################################### # API Provider Resource ###################################################### - /provider/{providerName}/apis/{apiId}: + /apis/{apiId}/provider/{providerName}: put: tags: - Api Provider Change @@ -3234,11 +3234,92 @@ paths: security: - OAuth2Security: - apim:admin + #- apim:api_provider_change x-code-samples: - lang: Curl source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -H "Content-Type: application/json" "https://127.0.0.1:9443/api/am/admin/v4/provider/admin/apis/33662a62-8db1-4d75-af08-afd63c6bd0b4"' + ###################################################### + # The "API Collection" resource APIs + ###################################################### + /apis: + get: + tags: + - APIs + summary: | + Retrieve/Search APIs + description: | + This operation provides you a list of available APIs qualifying under a given search condition. + Each retrieved API is represented with a minimal amount of attributes. If you want to get complete details of an API, you need to use **Get details of an API** operation. + parameters: + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' + - $ref: '#/components/parameters/sortBy' + - $ref: '#/components/parameters/sortOrder' + - $ref: '#/components/parameters/requestedTenant' + - name: query + in: query + description: | + **Search condition**. + + You can search in attributes by using an **":"** modifier. + Eg. + "provider:wso2" will match an API if the provider of the API contains "wso2". + "provider:"wso2"" will match an API if the provider of the API is exactly "wso2". + "status:PUBLISHED" will match an API if the API is in PUBLISHED state. + + Also you can use combined modifiers + Eg. + name:pizzashack version:v1 will match an API if the name of the API is pizzashack and version is v1. + + Supported attribute modifiers are [**version, context, name, status, + description, provider, api-category, tags, doc, contexttemplate, + lcstate, content, type, label, enablestore, thirdparty**] + + If no advanced attribute modifier has been specified, the API names containing + the search term will be returned as a result. + + Please note that you need to use encoded URL (URL encoding) if you are using a client which does not support URL encoding (such as curl) + schema: + type: string + - $ref: '#/components/parameters/If-None-Match' + - $ref: '#/components/parameters/Accept' + responses: + 200: + description: | + OK. + List of qualifying APIs is returned. + headers: + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + schema: + type: string + Content-Type: + description: The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/APIList' + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). + content: {} + 406: + $ref: '#/components/responses/NotAcceptable' + security: + - OAuth2Security: + - apim:admin + #- apim:api_provider_change + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis"' + operationId: getAllAPIs components: schemas: Error: @@ -4934,6 +5015,145 @@ components: Link to the previous subset of resources qualified. Empty if current subset is the first subset returned. example: "" + APIList: + title: API List + type: object + properties: + count: + type: integer + description: | + Number of APIs returned. + example: 1 + list: + type: array + items: + $ref: '#/components/schemas/APIInfomation' + pagination: + $ref: '#/components/schemas/PaginationApis' + APIInfomation: + title: API Info object with basic API details. + type: object + properties: + id: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorAPI + description: + type: string + example: A calculator API that supports basic operations + context: + type: string + example: CalculatorAPI + additionalProperties: + type: array + items: + type: object + properties: + name: + type: string + value: + type: string + display: + type: boolean + description: Map of custom properties of API + additionalPropertiesMap: + type: object + additionalProperties: + type: object + properties: + name: + type: string + value: + type: string + display: + type: boolean + default: false + version: + type: string + example: 1.0.0 + provider: + type: string + description: | + If the provider value is not given, the user invoking the API will be used as the provider. + example: admin + type: + type: string + example: HTTP + audience: + type: string + description: The audience of the API. Accepted values are PUBLIC, SINGLE + example: PUBLIC + enum: + - PUBLIC + - SINGLE + lifeCycleStatus: + type: string + example: CREATED + workflowStatus: + type: string + example: APPROVED + hasThumbnail: + type: boolean + example: true + securityScheme: + type: array + items: + type: string + createdTime: + type: string + example: 2021-02-11 09:57:25 + updatedTime: + type: string + example: 2021-02-11 09:57:25 + updatedBy: + type: string + example: wso2.system.user + gatewayVendor: + type: string + example: wso2 + advertiseOnly: + type: boolean + example: true + monetizedInfo: + type: boolean + example: true + businessOwner: + type: string + example: Business Owner + businessOwnerEmail: + type: string + example: businessowner@abc.com + TechnicalOwner: + type: string + example: Technical Owner + TechnicalOwnerEmail: + type: string + example: technicalowner@abc.com + PaginationApis: + title: Pagination + type: object + properties: + offset: + type: integer + example: 0 + limit: + type: integer + example: 1 + total: + type: integer + example: 10 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -5245,7 +5465,7 @@ components: name: apiId in: path description: | - API Id + **API ID** consisting of the **UUID** of the API. required: true schema: type: string diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml index f33f5e510824..dfcbcb151259 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/webapp/WEB-INF/beans.xml @@ -49,7 +49,7 @@ - + From d6f3a11cb37acc86c8f56872e0187175f6f6ff57 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 29 Nov 2023 10:02:22 +0530 Subject: [PATCH 05/25] Added the uuid key to the get apis object in the admin rest api. --- .../rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java index 3c5faaa9473a..01da769d2c8e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java @@ -89,6 +89,7 @@ private static APIInfomationDTO fromAPIToInfoDTO(API api) { apiInfoDTO.setName(apiId.getName()); apiInfoDTO.setVersion(apiId.getVersion()); apiInfoDTO.setProvider(apiId.getProviderName()); + apiInfoDTO.setId(api.getUuid()); return apiInfoDTO; } From bd246eb48b28ec5cdd0c2847fe1fb67674327b97 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 29 Nov 2023 15:21:04 +0530 Subject: [PATCH 06/25] Delete api bug fixed --- .../apimgt/persistence/RegistryPersistenceImpl.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index d4546a91e959..829109f9e879 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -794,14 +794,9 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep registry.delete(artifact.getPath()); } } - - artifactManager.removeGenericArtifact(apiArtifact); - - String path = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + - identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + - identifier.getApiName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion(); - String artifactId = getAPIArtifact(apiId,registry).getId(); + String artifactId = getAPIArtifact(apiId, registry).getId(); artifactManager.removeGenericArtifact(artifactId); + artifactManager.removeGenericArtifact(apiArtifact); String thumbPath = RegistryPersistenceUtil.getIconPath(identifier); if (registry.resourceExists(thumbPath)) { From 2e46e19c9aa6e045633a9143fc02626f094e8d38 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Thu, 30 Nov 2023 16:13:55 +0530 Subject: [PATCH 07/25] Remove msg context param --- .../org/wso2/carbon/apimgt/impl/APIProviderImplTest.java | 7 +++---- .../org/wso2/carbon/apimgt/persistence/APIPersistence.java | 4 ++-- .../carbon/apimgt/persistence/RegistryPersistenceImpl.java | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/APIProviderImplTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/APIProviderImplTest.java index 4df38a328b6a..efb01914720d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/APIProviderImplTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/APIProviderImplTest.java @@ -125,16 +125,15 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.List; -import java.util.UUID; import java.util.SortedMap; import java.util.TreeMap; -import java.util.ArrayList; - +import java.util.UUID; import javax.cache.Caching; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java index a7cbcd70aa9f..1088b74c1081 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java @@ -16,7 +16,6 @@ package org.wso2.carbon.apimgt.persistence; -import org.apache.cxf.jaxrs.ext.MessageContext; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.model.Tag; import org.wso2.carbon.apimgt.persistence.dto.DevPortalAPI; @@ -510,5 +509,6 @@ PublisherAPIProductSearchResult searchAPIProductsForPublisher(Organization org, */ Set getAllTags(Organization org, UserContext ctx) throws APIPersistenceException; - void changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) throws APIManagementException, APIPersistenceException; + void changeApiProvider(String providerName, String apiId, String org) throws APIManagementException, + APIPersistenceException; } \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 829109f9e879..0c8d5c0c07df 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.http.entity.ContentType; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; @@ -3734,7 +3733,7 @@ public int compare(Tag o1, Tag o2) { } @Override - public void changeApiProvider(String providerName, String apiId, String org, MessageContext ctx) + public void changeApiProvider(String providerName, String apiId, String org) throws APIPersistenceException { boolean isTenantFlowStarted = false; From 7de9b63b33cec5da7bfdb1a1764d71a6cfdd68cd Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 4 Dec 2023 07:46:00 +0530 Subject: [PATCH 08/25] ApiApiServiceImpl added to admin --- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 2 +- .../api/admin/v1/impl/ApisApiServiceImpl.java | 116 ++++++++++++++++++ .../src/main/resources/admin-api.yaml | 4 +- 3 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index ac431494a3d5..65b2beefbbf2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -18067,7 +18067,7 @@ private void updateAPIServiceMapping(int apiId, String serviceKey, String md5, i } public void updateApiProvider(String apiUuid, String providerName) - throws APIManagementException, SQLException { + throws APIManagementException { try (Connection connection = APIMgtDBUtil.getConnection()) { PreparedStatement statement = connection.prepareStatement(SQLConstants.UPDATE_API_PROVIDER_SQL); statement.setString(1, providerName); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java new file mode 100644 index 000000000000..c2ff3ae831f7 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -0,0 +1,116 @@ +package org.wso2.carbon.apimgt.rest.api.admin.v1.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.api.APIProvider; +import org.wso2.carbon.apimgt.api.ExceptionCodes; +import org.wso2.carbon.apimgt.api.model.API; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.GZIPUtils; +import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; +import org.wso2.carbon.apimgt.impl.factory.PersistenceFactory; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; +import org.wso2.carbon.apimgt.persistence.APIPersistence; +import org.wso2.carbon.apimgt.persistence.exceptions.APIPersistenceException; +import org.wso2.carbon.apimgt.rest.api.admin.v1.ApisApiService; +import org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings.APIInfoMappingUtil; +import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; +import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants; +import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.ws.rs.core.Response; + +public class ApisApiServiceImpl implements ApisApiService { + + private static final Log log = LogFactory.getLog(ApisApiServiceImpl.class); + + public Response getAllAPIs(Integer limit, Integer offset, String sortBy, String sortOrder, String xWSO2Tenant, + String query, String ifNoneMatch, String accept, MessageContext messageContext) { + List allMatchedApis = new ArrayList<>(); + Object apiListDTO; + + //pre-processing + //setting default limit and offset values if they are not set + limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; + offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; + query = query == null ? "" : query; + sortBy = sortBy != null ? sortBy : RestApiConstants.DEFAULT_SORT_CRITERION; + sortOrder = sortOrder != null ? sortOrder : RestApiConstants.DESCENDING_SORT_ORDER; + try { + + //revert content search back to normal search by name to avoid doc result complexity and + // to comply with REST api practices + if (query.startsWith(APIConstants.CONTENT_SEARCH_TYPE_PREFIX + ":")) { + query = query + .replace(APIConstants.CONTENT_SEARCH_TYPE_PREFIX + ":", + APIConstants.NAME_TYPE_PREFIX + ":"); + } + + APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); + + String organization = RestApiUtil.getValidatedOrganization(messageContext); + + Map result; + + result = apiProvider.searchPaginatedAPIs(query, organization, offset, limit, sortBy, sortOrder); + + Set apis = (Set) result.get("apis"); + allMatchedApis.addAll(apis); + + apiListDTO = APIInfoMappingUtil.fromAPIListToInfoDTO(allMatchedApis); + + //Add pagination section in the response + Object totalLength = result.get("length"); + Integer length = 0; + if (totalLength != null) { + length = (Integer) totalLength; + } + APIInfoMappingUtil.setPaginationParams(apiListDTO, query, offset, limit, length); + if (APIConstants.APPLICATION_GZIP.equals(accept)) { + try { + File zippedResponse = GZIPUtils.constructZippedResponse(apiListDTO); + return Response.ok().entity(zippedResponse) + .header("Content-Disposition", "attachment"). + header("Content-Encoding", "gzip").build(); + } catch (APIManagementException e) { + RestApiUtil.handleInternalServerError(e.getMessage(), e, log); + } + } else { + return Response.ok().entity(apiListDTO).build(); + } + } catch (APIManagementException e) { + String errorMessage = "Error while retrieving APIs"; + RestApiUtil.handleInternalServerError(errorMessage, e, log); + } + return null; + } + + public Response providerProviderNameApisApiIdPut(String providerName, String apiId, MessageContext messageContext) + throws APIManagementException { + String tenantDomain = RestApiCommonUtil.getLoggedInUserTenantDomain(); + String organization = null; + if (tenantDomain != null) { + organization = tenantDomain; + } + try { + if (!APIUtil.isUserExist(providerName)) { + throw new APIManagementException("User Not Found. Username :" + providerName + ",", + ExceptionCodes.USER_NOT_FOUND); + } + APIPersistence apiPersistenceInstance; + apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); + ApiMgtDAO.getInstance().updateApiProvider(apiId, providerName); + apiPersistenceInstance.changeApiProvider(providerName, apiId, organization); + }catch (APIManagementException | APIPersistenceException e) { + throw new APIManagementException("Error While Changing the Api Provider", e); + } + return Response.ok().build(); + } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml index 6e555ade3134..514b71890cb5 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml @@ -3234,7 +3234,7 @@ paths: security: - OAuth2Security: - apim:admin - #- apim:api_provider_change + - apim:api_provider_change x-code-samples: - lang: Curl source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" @@ -3314,7 +3314,7 @@ paths: security: - OAuth2Security: - apim:admin - #- apim:api_provider_change + - apim:api_provider_change x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" From 1c9b2788cb5a4dec87d0e10c8c4f164cb3b7f0e9 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Sun, 19 Nov 2023 11:55:53 +0530 Subject: [PATCH 09/25] Api Name Space Restriction Removed. --- .../publisher/v1/common/mappings/PublisherCommonUtils.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java index a33cd065bb03..8b66a1163e1e 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java @@ -839,11 +839,6 @@ public static void validateScopes(API api) throws APIManagementException { public static API addAPIWithGeneratedSwaggerDefinition(APIDTO apiDto, String oasVersion, String username, String organization) throws APIManagementException, CryptoException { - if (APIUtil.isOnPremResolver()) { - String name = apiDto.getName(); - //replace all white spaces in the API Name - apiDto.setName(name.replaceAll("\\s+", "")); - } if (APIDTO.TypeEnum.ASYNC.equals(apiDto.getType())) { throw new APIManagementException("ASYNC API type does not support API creation from scratch", ExceptionCodes.API_CREATION_NOT_SUPPORTED_FOR_ASYNC_TYPE_APIS); From 1f48063fa7bcb8694630a9ea6f0d09e883b57705 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Sun, 19 Nov 2023 11:57:04 +0530 Subject: [PATCH 10/25] Content Based search improved to support api name search with spaces --- .../rest/api/publisher/v1/impl/SearchApiServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java index 14619e862710..ecb9eaa75cef 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java @@ -50,7 +50,9 @@ public class SearchApiServiceImpl implements SearchApiService { public Response search(Integer limit, Integer offset, String query, String ifNoneMatch, MessageContext messageContext) throws APIManagementException { SearchResultListDTO resultListDTO = new SearchResultListDTO(); - + if (query.startsWith("name:") || query.startsWith("description:")) { + query = query.replaceAll(" ", "%20"); + } limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; From bb2e72e48e96e7837f5ef5df68e911f669d42714 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Fri, 1 Dec 2023 11:42:02 +0530 Subject: [PATCH 11/25] Api restore lifeCycleState bug fix --- .../carbon/apimgt/persistence/RegistryPersistenceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 0c8d5c0c07df..d2cf6ec31b47 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -348,7 +348,6 @@ public void restoreAPIRevision(Organization org, String apiUUID, String revision GenericArtifactManager artifactManager = RegistryPersistenceUtil.getArtifactManager(registry, APIConstants.API_KEY); GenericArtifact apiArtifact = artifactManager.getGenericArtifact(apiUUID); - String lcState = ((GenericArtifactImpl) apiArtifact).getLcState(); if (apiArtifact != null) { String existingVersionComparable = apiArtifact.getAttribute(APIConstants .API_OVERVIEW_VERSION_COMPARABLE); @@ -359,6 +358,8 @@ public void restoreAPIRevision(Organization org, String apiUUID, String revision visibleRoles = visibleRolesList.split(","); } String apiPath = GovernanceUtils.getArtifactPath(registry, apiUUID); + String lifecycleStatus = artifactManager.getGenericArtifact(apiUUID) + .getAttribute(APIConstants.API_OVERVIEW_STATUS); int prependIndex = apiPath.lastIndexOf("/api"); String apiSourcePath = apiPath.substring(0, prependIndex); String revisionTargetPath = RegistryPersistenceUtil.getRevisionPath(apiUUID, revisionId); @@ -366,8 +367,10 @@ public void restoreAPIRevision(Organization org, String apiUUID, String revision registry.copy(revisionTargetPath, apiSourcePath); Resource newAPIArtifact = registry.get(apiPath); newAPIArtifact.setUUID(apiUUID); - newAPIArtifact.setProperty("registry.lifecycle.APILifeCycle.state", java.util.Arrays.asList((lcState))); registry.put(apiPath, newAPIArtifact); + GenericArtifact artifact = getAPIArtifact(apiUUID, registry); + artifact.setAttribute(APIConstants.API_OVERVIEW_STATUS, lifecycleStatus); + artifactManager.updateGenericArtifact(apiArtifact); RegistryPersistenceUtil.clearResourcePermissions(apiPath, api.getId(), ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), From e65dc33a7a5b32508eb839ac5819d0efbc2526dd Mon Sep 17 00:00:00 2001 From: shnrndk Date: Tue, 5 Dec 2023 19:25:20 +0530 Subject: [PATCH 12/25] Delete bug fixed --- .../apimgt/persistence/RegistryPersistenceImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index d2cf6ec31b47..5ef48a3c9e6e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -796,9 +796,17 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep registry.delete(artifact.getPath()); } } + String artifactId = getAPIArtifact(apiId, registry).getId(); + String apiPath = getAPIArtifact(apiId, registry).getPath(); artifactManager.removeGenericArtifact(artifactId); artifactManager.removeGenericArtifact(apiArtifact); + if (apiPath.endsWith("api")) { + apiPath = apiPath.replaceAll("/api$", ""); + Resource apiResource = registry.get(apiPath); + artifactId = apiResource.getUUID(); + artifactManager.removeGenericArtifact(artifactId); + } String thumbPath = RegistryPersistenceUtil.getIconPath(identifier); if (registry.resourceExists(thumbPath)) { From 07d101ef9b5e06a3f2235440951d890ab9c2f988 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 11 Dec 2023 07:39:08 +0530 Subject: [PATCH 13/25] Admin portal get apis implement, and fix bugs in change api provider. --- .../org/wso2/carbon/apimgt/api/APIAdmin.java | 23 ++ .../api/model/ApplicationInfoKeyManager.java | 37 +++ .../wso2/carbon/apimgt/impl/APIAdminImpl.java | 83 ++++++ .../wso2/carbon/apimgt/impl/APIConstants.java | 4 + .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 20 +- .../apimgt/persistence/APIPersistence.java | 4 + .../persistence/RegistryPersistenceImpl.java | 98 ++++++- .../apimgt/persistence/dto/AdminApiInfo.java | 57 ++++ .../dto/AdminApiSearchContent.java | 133 +++++++++ .../dto/AdminContentSearchResult.java | 60 ++++ .../api/admin/v1/impl/ApisApiServiceImpl.java | 116 -------- .../v1/utils/mappings/APIInfoMappingUtil.java | 67 +---- .../src/main/resources/admin-api.yaml | 256 +++++------------- 13 files changed, 594 insertions(+), 364 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/ApplicationInfoKeyManager.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiInfo.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiSearchContent.java create mode 100644 components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java delete mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java index f64f7aedc561..e736437b5b08 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java @@ -465,4 +465,27 @@ boolean isScopeExists(String username, String scopeName) Policy[] getPolicies(int tenantId, String level) throws APIManagementException; Policy getPolicyByNameAndType(int tenantId, String level, String name) throws APIManagementException; + + /** + * Update the Api Provider of a given Api Id + * + * @param apiId Api ID + * @param provider ProviderName/Owner of the Api + * @param organisation Organisation + * @throws APIManagementException + */ + void updateApiProvider(String apiId, String provider, String organisation) throws APIManagementException; + + /** + * Get/Search All Apis in admin portal + * + * @param searchQuery Api name search query + * @param organization organisation + * @param start + * @param end + * @return + * @throws APIManagementException + */ + Map searchPaginatedApis(String searchQuery, String organization, int start, int end) + throws APIManagementException; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/ApplicationInfoKeyManager.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/ApplicationInfoKeyManager.java new file mode 100644 index 000000000000..e17e00792941 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/ApplicationInfoKeyManager.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.api.model; + +/** + * This class represent the minimized view of the Application in api model for Key manager operations in admin REST API. + */ +public class ApplicationInfoKeyManager extends ApplicationInfo { + + private String organization; + + public String getOrganization() { + + return organization; + } + + public void setOrganization(String organization) { + + this.organization = organization; + } + +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java index a36e9b7e21a1..df2266420357 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java @@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.solr.client.solrj.util.ClientUtils; import org.everit.json.schema.Schema; import org.everit.json.schema.ValidationException; import org.json.JSONException; @@ -39,10 +40,16 @@ import org.wso2.carbon.apimgt.api.APIMgtResourceNotFoundException; import org.wso2.carbon.apimgt.api.ExceptionCodes; import org.wso2.carbon.apimgt.api.dto.KeyManagerConfigurationDTO; +import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.APICategory; +import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.apimgt.api.model.APIProduct; +import org.wso2.carbon.apimgt.api.model.APIProductIdentifier; import org.wso2.carbon.apimgt.api.model.Application; import org.wso2.carbon.apimgt.api.model.ApplicationInfo; import org.wso2.carbon.apimgt.api.model.ConfigurationDto; +import org.wso2.carbon.apimgt.api.model.Documentation; +import org.wso2.carbon.apimgt.api.model.DocumentationType; import org.wso2.carbon.apimgt.api.model.Environment; import org.wso2.carbon.apimgt.api.model.KeyManagerConfiguration; import org.wso2.carbon.apimgt.api.model.KeyManagerConnectorConfiguration; @@ -59,11 +66,30 @@ import org.wso2.carbon.apimgt.impl.dao.constants.SQLConstants; import org.wso2.carbon.apimgt.impl.dto.ThrottleProperties; import org.wso2.carbon.apimgt.impl.dto.WorkflowProperties; +import org.wso2.carbon.apimgt.impl.factory.PersistenceFactory; import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; import org.wso2.carbon.apimgt.impl.keymgt.KeyMgtNotificationSender; import org.wso2.carbon.apimgt.impl.monetization.DefaultMonetizationImpl; import org.wso2.carbon.apimgt.impl.service.KeyMgtRegistrationService; +import org.wso2.carbon.apimgt.impl.utils.APINameComparator; +import org.wso2.carbon.apimgt.impl.utils.APIProductNameComparator; import org.wso2.carbon.apimgt.impl.utils.APIUtil; +import org.wso2.carbon.apimgt.impl.utils.ContentSearchResultNameComparator; +import org.wso2.carbon.apimgt.persistence.APIPersistence; +import org.wso2.carbon.apimgt.persistence.dto.AdminApiInfo; +import org.wso2.carbon.apimgt.persistence.dto.AdminApiSearchContent; +import org.wso2.carbon.apimgt.persistence.dto.AdminContentSearchResult; +import org.wso2.carbon.apimgt.persistence.dto.DocumentSearchContent; +import org.wso2.carbon.apimgt.persistence.dto.Organization; +import org.wso2.carbon.apimgt.persistence.dto.PublisherAPIInfo; +import org.wso2.carbon.apimgt.persistence.dto.PublisherAPISearchResult; +import org.wso2.carbon.apimgt.persistence.dto.PublisherContentSearchResult; +import org.wso2.carbon.apimgt.persistence.dto.PublisherSearchContent; +import org.wso2.carbon.apimgt.persistence.dto.SearchContent; +import org.wso2.carbon.apimgt.persistence.dto.UserContext; +import org.wso2.carbon.apimgt.persistence.exceptions.APIPersistenceException; +import org.wso2.carbon.apimgt.persistence.mapper.APIMapper; +import org.wso2.carbon.apimgt.persistence.utils.RegistrySearchUtil; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.util.CryptoException; @@ -90,9 +116,13 @@ import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.SortedSet; import java.util.TimeZone; +import java.util.TreeSet; import java.util.UUID; import java.util.stream.Collectors; @@ -1287,6 +1317,59 @@ public void updateTenantConfig(String organization, String config) throws APIMan } } + public void updateApiProvider(String apiId, String provider, String organisation) throws APIManagementException { + APIPersistence apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); + try { + ApiMgtDAO.getInstance().updateApiProvider(apiId, provider); + apiPersistenceInstance.changeApiProvider(provider, apiId, organisation); + } catch (APIPersistenceException e) { + throw new APIManagementException("Error while changing the API provider", e); + } + } + + public Map searchPaginatedApis(String searchQuery, String organization, int start, int end) + throws APIManagementException { + ArrayList compoundResult = new ArrayList(); + Map docMap = new HashMap(); + Map result = new HashMap(); + SortedSet apiSet = new TreeSet(new APINameComparator()); + String modifiedSearchQuery = buildSearchQuery(searchQuery); + try { + APIPersistence apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); + AdminContentSearchResult results = apiPersistenceInstance.searchContentForAdmin(organization, + modifiedSearchQuery, start, end, Integer.MAX_VALUE); + if (results != null) { + List resultList = results.getApis(); + for (SearchContent item : resultList) { + if ("API".equals(item.getType())) { + AdminApiSearchContent adminSearchApi = (AdminApiSearchContent) item; + API api = new API(new APIIdentifier(adminSearchApi.getProvider(), adminSearchApi.getName(), + adminSearchApi.getVersion())); + api.setUuid(adminSearchApi.getId()); + apiSet.add(api); + } + } + compoundResult.addAll(apiSet); + compoundResult.addAll(docMap.entrySet()); + compoundResult.sort(new ContentSearchResultNameComparator()); + } else { + result.put("length", compoundResult.size()); + } + } catch (APIPersistenceException e) { + throw new APIManagementException("Error while searching apis ", e); + } + result.put("apis", compoundResult); + return result; + } + + private String buildSearchQuery(String searchQuery) { + if (searchQuery.equals(APIConstants.CHAR_ASTERIX)) { + return String.format(APIConstants.ADMIN_PORTAL_GET_APIS_QUERY, APIConstants.CHAR_ASTERIX); + } else { + return String.format(APIConstants.ADMIN_PORTAL_GET_APIS_QUERY, searchQuery); + } + } + @Override public String getTenantConfigSchema(String organization) { return APIUtil.retrieveTenantConfigJsonSchema().toString(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 1cc201027efb..a85d01779088 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -145,6 +145,10 @@ public final class APIConstants { public static final String SSL_VERIFY_CLIENT_STATUS_REQUIRE = "require"; + public static final String ADMIN_PORTAL_GET_APIS_QUERY = "name=\\*\"%s\"\\* AND" + + " mediaType:application\\/vnd.wso2\\-api\\+xml AND" + + " type=(HTTP OR WS OR SOAPTOREST OR GRAPHQL OR SOAP OR SSE OR WEBSUB OR WEBHOOK OR ASYNC)"; + //location for custom url domain mapings. "" will be replaced by actual tenant name. public static final String API_DOMAIN_MAPPINGS = "/customurl/api-cloud//urlMapping/"; public static final String API_DOMAIN_MAPPING_TENANT_ID_IDENTIFIER = ""; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index 65b2beefbbf2..fae5d53a6dc0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -18066,15 +18066,23 @@ private void updateAPIServiceMapping(int apiId, String serviceKey, String md5, i } } - public void updateApiProvider(String apiUuid, String providerName) + public void updateApiProvider(String apiUUID, String providerName) throws APIManagementException { try (Connection connection = APIMgtDBUtil.getConnection()) { - PreparedStatement statement = connection.prepareStatement(SQLConstants.UPDATE_API_PROVIDER_SQL); - statement.setString(1, providerName); - statement.setString(2, apiUuid); - statement.executeUpdate(); + connection.setAutoCommit(false); + try (PreparedStatement statement = connection.prepareStatement(SQLConstants.UPDATE_API_PROVIDER_SQL)) { + statement.setString(1, providerName); + statement.setString(2, apiUUID); + statement.executeUpdate(); + connection.commit(); + } catch (SQLException e) { + connection.rollback(); + handleException("Error while updating the API provider of " + apiUUID, e); + } finally { + connection.setAutoCommit(true); + } } catch (SQLException e) { - handleException("Error while updating the change API provider of " + apiUuid, e); + handleException("Error while updating the API provider of " + apiUUID, e); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java index 1088b74c1081..c62ed7f45910 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIPersistence.java @@ -18,6 +18,7 @@ import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.model.Tag; +import org.wso2.carbon.apimgt.persistence.dto.AdminContentSearchResult; import org.wso2.carbon.apimgt.persistence.dto.DevPortalAPI; import org.wso2.carbon.apimgt.persistence.dto.DevPortalAPISearchResult; import org.wso2.carbon.apimgt.persistence.dto.DevPortalContentSearchResult; @@ -511,4 +512,7 @@ PublisherAPIProductSearchResult searchAPIProductsForPublisher(Organization org, void changeApiProvider(String providerName, String apiId, String org) throws APIManagementException, APIPersistenceException; + + AdminContentSearchResult searchContentForAdmin(String org, String searchQuery, int start, int count, + int limit) throws APIPersistenceException; } \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 5ef48a3c9e6e..11ddfc4db52b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -3746,7 +3746,6 @@ public int compare(Tag o1, Tag o2) { @Override public void changeApiProvider(String providerName, String apiId, String org) throws APIPersistenceException { - boolean isTenantFlowStarted = false; boolean transactionCommitted = false; RegistryHolder holder = getRegistry(org); @@ -3785,4 +3784,101 @@ public void changeApiProvider(String providerName, String apiId, String org) } } } + + @Override + public AdminContentSearchResult searchContentForAdmin(String org, String searchQuery, int start, int count, + int limit) throws APIPersistenceException { + log.debug("Requested query for admin key Manager usages API search: " + searchQuery); + + boolean isTenantFlowStarted = false; + AdminContentSearchResult result = null; + try { + RegistryHolder holder = getRegistry(org); + Registry registry = holder.getRegistry(); + isTenantFlowStarted = holder.isTenantFlowStarted(); + String tenantAwareUsername = getTenantAwareUsername(RegistryPersistenceUtil.getTenantAdminUserName(org)); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(tenantAwareUsername); + PaginationContext.init(start, Integer.MAX_VALUE, "ASC", APIConstants.API_OVERVIEW_NAME, limit); + GenericArtifactManager apiArtifactManager = RegistryPersistenceUtil.getArtifactManager(registry, + APIConstants.API_KEY); + + int tenantId = holder.getTenantId(); + if (tenantId == -1) { + tenantId = MultitenantConstants.SUPER_TENANT_ID; + } + + UserRegistry systemUserRegistry = ServiceReferenceHolder.getInstance().getRegistryService() + .getRegistry(CarbonConstants.REGISTRY_SYSTEM_USERNAME, tenantId); + ContentBasedSearchService contentBasedSearchService = new ContentBasedSearchService(); + + SearchResultsBean resultsBean = contentBasedSearchService + .searchContent(searchQuery, systemUserRegistry); + String errorMsg = resultsBean.getErrorMessage(); + if (errorMsg != null) { + throw new APIPersistenceException("Error while searching " + errorMsg); + } + ResourceData[] resourceDataList = resultsBean.getResourceDataList(); + int totalLength = PaginationContext.getInstance().getLength(); + + if (resourceDataList != null) { + result = new AdminContentSearchResult(); + List contentData = new ArrayList<>(); + if (log.isDebugEnabled()) { + log.debug("Number of records Found: " + resourceDataList.length); + } + + for (ResourceData data : resourceDataList) { + String resourcePath = data.getResourcePath(); + if (resourcePath.contains(APIConstants.APIMGT_REGISTRY_LOCATION)) { + int index = resourcePath.indexOf(APIConstants.APIMGT_REGISTRY_LOCATION); + resourcePath = resourcePath.substring(index); + Resource resource = registry.get(resourcePath); + String apiArtifactId = resource.getUUID(); + + String type; + if (apiArtifactId != null) { + GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiArtifactId); + if (apiArtifact.getAttribute(APIConstants.API_OVERVIEW_TYPE). + equals(APIConstants.API_PRODUCT)) { + type = APIConstants.API_PRODUCT; + } else { + type = APIConstants.API; + } + PublisherAPI pubAPI = RegistryPersistenceUtil.getAPIForSearch(apiArtifact); + AdminApiSearchContent content = new AdminApiSearchContent(); + content.setContext(pubAPI.getContext()); + content.setDescription(pubAPI.getDescription()); + content.setId(pubAPI.getId()); + content.setName(pubAPI.getApiName()); + content.setProvider(RegistryPersistenceUtil.replaceEmailDomainBack(pubAPI + .getProviderName())); + content.setType(type); + content.setVersion(pubAPI.getVersion()); + content.setStatus(pubAPI.getStatus()); + content.setAdvertiseOnly(pubAPI.isAdvertiseOnly()); + content.setThumbnailUri(pubAPI.getThumbnail()); + if (apiArtifact.getAttribute("overview_keyManagers") != null) { + content.setKeyManagerEntry(apiArtifact.getAttribute("overview_keyManagers") + .replace("[\"","").replace("\"]","") + .replace("\",\""," , ")); + } + contentData.add(content); + } else { + throw new GovernanceException("artifact id is null for " + resourcePath); + } + } + } + result.setApiCount(contentData.size()); + result.setApis(contentData); + } + } catch (RegistryException | IndexerException | APIManagementException e) { + throw new APIPersistenceException("Error while searching for content ", e); + } finally { + if (isTenantFlowStarted) { + PrivilegedCarbonContext.endTenantFlow(); + } + } + return result; + } + } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiInfo.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiInfo.java new file mode 100644 index 000000000000..5590d4c13454 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.persistence.dto; + +public class AdminApiInfo { + private String id; + private String apiName; + private String version; + private String providerName; + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getApiName() { + return apiName; + } + + public void setApiName(String apiName) { + this.apiName = apiName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiSearchContent.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiSearchContent.java new file mode 100644 index 000000000000..7bd9ca8f2eeb --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminApiSearchContent.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.persistence.dto; + +public class AdminApiSearchContent implements SearchContent { + + String id; + String type = "API"; + String name; + String transportType = "HTTP"; + String description; + String context; + String version; + String provider; + String status; + String thumbnailUri; + Boolean advertiseOnly; + + String keyManagerEntry; + + @Override + public String getId() { + return id; + } + + @Override + public String getType() { + return type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTransportType() { + return transportType; + } + + public void setTransportType(String transportType) { + this.transportType = transportType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getContext() { + return context; + } + + public void setContext(String context) { + this.context = context; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getThumbnailUri() { + return thumbnailUri; + } + + public void setThumbnailUri(String thumbnailUri) { + this.thumbnailUri = thumbnailUri; + } + + public void setId(String id) { + this.id = id; + } + + public void setType(String type) { + this.type = type; + } + + public Boolean getAdvertiseOnly() { + return advertiseOnly; + } + + public void setAdvertiseOnly(Boolean advertiseOnly) { + this.advertiseOnly = advertiseOnly; + } + + public String getKeyManagerEntry() { + return keyManagerEntry; + } + + public void setKeyManagerEntry(String keyManagerEntry) { + this.keyManagerEntry = keyManagerEntry; + } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java new file mode 100644 index 000000000000..7cb52a3c70cb --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.persistence.dto; + +import org.wso2.carbon.apimgt.api.model.ApplicationInfoKeyManager; + +import java.util.ArrayList; +import java.util.List; + +public class AdminContentSearchResult { + int apiCount; + int applicationCount; + List apis = new ArrayList(); + + List applications = new ArrayList<>(); + + public List getApis() { + return apis; + } + + public void setApis(List apis) { + this.apis = apis; + } + + public int getApiCount() { + return apiCount; + } + + public void setApiCount(int apiCount) { + this.apiCount = apiCount; + } + + public int getApplicationCount() { + return applicationCount; + } + + public void setApplicationCount(int applicationCount) { + this.applicationCount = applicationCount; + } + + public List getApplications() { return applications; } + + public void setApplications(List applications) {this.applications = applications; } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java deleted file mode 100644 index c2ff3ae831f7..000000000000 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.wso2.carbon.apimgt.rest.api.admin.v1.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.cxf.jaxrs.ext.MessageContext; -import org.wso2.carbon.apimgt.api.APIManagementException; -import org.wso2.carbon.apimgt.api.APIProvider; -import org.wso2.carbon.apimgt.api.ExceptionCodes; -import org.wso2.carbon.apimgt.api.model.API; -import org.wso2.carbon.apimgt.impl.APIConstants; -import org.wso2.carbon.apimgt.impl.GZIPUtils; -import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; -import org.wso2.carbon.apimgt.impl.factory.PersistenceFactory; -import org.wso2.carbon.apimgt.impl.utils.APIUtil; -import org.wso2.carbon.apimgt.persistence.APIPersistence; -import org.wso2.carbon.apimgt.persistence.exceptions.APIPersistenceException; -import org.wso2.carbon.apimgt.rest.api.admin.v1.ApisApiService; -import org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings.APIInfoMappingUtil; -import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; -import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants; -import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.ws.rs.core.Response; - -public class ApisApiServiceImpl implements ApisApiService { - - private static final Log log = LogFactory.getLog(ApisApiServiceImpl.class); - - public Response getAllAPIs(Integer limit, Integer offset, String sortBy, String sortOrder, String xWSO2Tenant, - String query, String ifNoneMatch, String accept, MessageContext messageContext) { - List allMatchedApis = new ArrayList<>(); - Object apiListDTO; - - //pre-processing - //setting default limit and offset values if they are not set - limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; - offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; - query = query == null ? "" : query; - sortBy = sortBy != null ? sortBy : RestApiConstants.DEFAULT_SORT_CRITERION; - sortOrder = sortOrder != null ? sortOrder : RestApiConstants.DESCENDING_SORT_ORDER; - try { - - //revert content search back to normal search by name to avoid doc result complexity and - // to comply with REST api practices - if (query.startsWith(APIConstants.CONTENT_SEARCH_TYPE_PREFIX + ":")) { - query = query - .replace(APIConstants.CONTENT_SEARCH_TYPE_PREFIX + ":", - APIConstants.NAME_TYPE_PREFIX + ":"); - } - - APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); - - String organization = RestApiUtil.getValidatedOrganization(messageContext); - - Map result; - - result = apiProvider.searchPaginatedAPIs(query, organization, offset, limit, sortBy, sortOrder); - - Set apis = (Set) result.get("apis"); - allMatchedApis.addAll(apis); - - apiListDTO = APIInfoMappingUtil.fromAPIListToInfoDTO(allMatchedApis); - - //Add pagination section in the response - Object totalLength = result.get("length"); - Integer length = 0; - if (totalLength != null) { - length = (Integer) totalLength; - } - APIInfoMappingUtil.setPaginationParams(apiListDTO, query, offset, limit, length); - if (APIConstants.APPLICATION_GZIP.equals(accept)) { - try { - File zippedResponse = GZIPUtils.constructZippedResponse(apiListDTO); - return Response.ok().entity(zippedResponse) - .header("Content-Disposition", "attachment"). - header("Content-Encoding", "gzip").build(); - } catch (APIManagementException e) { - RestApiUtil.handleInternalServerError(e.getMessage(), e, log); - } - } else { - return Response.ok().entity(apiListDTO).build(); - } - } catch (APIManagementException e) { - String errorMessage = "Error while retrieving APIs"; - RestApiUtil.handleInternalServerError(errorMessage, e, log); - } - return null; - } - - public Response providerProviderNameApisApiIdPut(String providerName, String apiId, MessageContext messageContext) - throws APIManagementException { - String tenantDomain = RestApiCommonUtil.getLoggedInUserTenantDomain(); - String organization = null; - if (tenantDomain != null) { - organization = tenantDomain; - } - try { - if (!APIUtil.isUserExist(providerName)) { - throw new APIManagementException("User Not Found. Username :" + providerName + ",", - ExceptionCodes.USER_NOT_FOUND); - } - APIPersistence apiPersistenceInstance; - apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); - ApiMgtDAO.getInstance().updateApiProvider(apiId, providerName); - apiPersistenceInstance.changeApiProvider(providerName, apiId, organization); - }catch (APIManagementException | APIPersistenceException e) { - throw new APIManagementException("Error While Changing the Api Provider", e); - } - return Response.ok().build(); - } -} diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java index 01da769d2c8e..428efe885b50 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java @@ -17,21 +17,21 @@ package org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings; -import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.APIIdentifier; import org.wso2.carbon.apimgt.impl.utils.APIUtil; -import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.*; -import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoListDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.ApiResultDTO; import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.*; +import java.util.ArrayList; +import java.util.List; public class APIInfoMappingUtil { - private static final String EMPTY_STRING = ""; /** * Converts a APIIdentifier object into APIInfoDTO * @@ -73,56 +73,13 @@ public static APIInfoListDTO fromAPIInfoListToDTO(List apiIds) th return apiInfoListDTO; } - public static APIListDTO fromAPIListToInfoDTO(List apiList) throws APIManagementException { - APIListDTO apiListDTO = new APIListDTO(); - List apiInfoDTOs = apiListDTO.getList(); - for (API api : apiList) { - apiInfoDTOs.add(fromAPIToInfoDTO(api)); - } - apiListDTO.setCount(apiInfoDTOs.size()); - return apiListDTO; - } - - private static APIInfomationDTO fromAPIToInfoDTO(API api) { - APIInfomationDTO apiInfoDTO = new APIInfomationDTO(); + public static ApiResultDTO fromAPIToAPIResultDTO(API api) { + ApiResultDTO apiResultDTO = new ApiResultDTO(); + apiResultDTO.setId(api.getUuid()); APIIdentifier apiId = api.getId(); - apiInfoDTO.setName(apiId.getName()); - apiInfoDTO.setVersion(apiId.getVersion()); - apiInfoDTO.setProvider(apiId.getProviderName()); - apiInfoDTO.setId(api.getUuid()); - return apiInfoDTO; - } - - public static void setPaginationParams(Object apiListDTO, String query, int offset, int limit, int size) { - - //acquiring pagination parameters and setting pagination urls - Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, size); - String paginatedPrevious = EMPTY_STRING; - String paginatedNext = EMPTY_STRING; - - if (paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET) != null) { - paginatedPrevious = RestApiCommonUtil - .getAPIPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), - paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_LIMIT), query); - } - - if (paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET) != null) { - paginatedNext = RestApiCommonUtil - .getAPIPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET), - paginatedParams.get(RestApiConstants.PAGINATION_NEXT_LIMIT), query); - } - - PaginationApisDTO paginationDTO = getPaginationDTO(limit, offset, size, paginatedNext, paginatedPrevious); - ((APIListDTO) apiListDTO).setPagination(paginationDTO); - } - - private static PaginationApisDTO getPaginationDTO(int limit, int offset, int total, String next, String previous) { - PaginationApisDTO paginationDTO = new PaginationApisDTO(); - paginationDTO.setLimit(limit); - paginationDTO.setOffset(offset); - paginationDTO.setTotal(total); - paginationDTO.setNext(next); - paginationDTO.setPrevious(previous); - return paginationDTO; + apiResultDTO.setName(apiId.getApiName()); + apiResultDTO.setVersion(apiId.getVersion()); + apiResultDTO.setProvider(apiId.getProviderName()); + return apiResultDTO; } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml index 514b71890cb5..cf1bd587f6a1 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/resources/admin-api.yaml @@ -3203,43 +3203,6 @@ paths: -F "type=WSO2-IS" "https://127.0.0.1:9443/api/am/admin/v4/key-managers/discover"' ###################################################### - # API Provider Resource - ###################################################### - /apis/{apiId}/provider/{providerName}: - put: - tags: - - Api Provider Change - summary: Update the api provider - description: | - Update the api provider - parameters: - - $ref: '#/components/parameters/providerName' - - $ref: '#/components/parameters/apiId' - operationId: providerProviderNameApisApiIdPut - responses: - 200: - description: | - OK. - Api Provider updated. - headers: - Content-Type: - description: | - The content type of the body. - schema: - type: string - 400: - $ref: '#/components/responses/BadRequest' - 404: - $ref: '#/components/responses/NotFound' - security: - - OAuth2Security: - - apim:admin - - apim:api_provider_change - x-code-samples: - - lang: Curl - source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - -H "Content-Type: application/json" "https://127.0.0.1:9443/api/am/admin/v4/provider/admin/apis/33662a62-8db1-4d75-af08-afd63c6bd0b4"' - ###################################################### # The "API Collection" resource APIs ###################################################### /apis: @@ -3254,37 +3217,15 @@ paths: parameters: - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' - - $ref: '#/components/parameters/sortBy' - - $ref: '#/components/parameters/sortOrder' - - $ref: '#/components/parameters/requestedTenant' - name: query in: query description: | - **Search condition**. + **Search and get all apis in admin portal**. - You can search in attributes by using an **":"** modifier. - - Eg. - "provider:wso2" will match an API if the provider of the API contains "wso2". - "provider:"wso2"" will match an API if the provider of the API is exactly "wso2". - "status:PUBLISHED" will match an API if the API is in PUBLISHED state. - - Also you can use combined modifiers - Eg. - name:pizzashack version:v1 will match an API if the name of the API is pizzashack and version is v1. - - Supported attribute modifiers are [**version, context, name, status, - description, provider, api-category, tags, doc, contexttemplate, - lcstate, content, type, label, enablestore, thirdparty**] - - If no advanced attribute modifier has been specified, the API names containing - the search term will be returned as a result. - - Please note that you need to use encoded URL (URL encoding) if you are using a client which does not support URL encoding (such as curl) + You can search by proving a keyword. schema: type: string - $ref: '#/components/parameters/If-None-Match' - - $ref: '#/components/parameters/Accept' responses: 200: description: | @@ -3303,7 +3244,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/APIList' + $ref: '#/components/schemas/SearchResultList' 304: description: | Not Modified. @@ -3320,6 +3261,47 @@ paths: source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis"' operationId: getAllAPIs + ###################################################### + # Change Api Provider + ###################################################### + /apis/{apiId}/change-provider: + post: + tags: + - Api Provider Change + summary: Update the api provider + description: | + Update the api provider + operationId: providerNamePost + parameters: + - name: provider + in: query + required: true + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. + Api Provider updated. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + security: + - OAuth2Security: + - apim:admin + - apim:api_provider_change + x-code-samples: + - lang: Curl + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: application/json" "https://127.0.0.1:9443/api/am/admin/v4/provider/admin/apis/33662a62-8db1-4d75-af08-afd63c6bd0b4"' components: schemas: Error: @@ -5015,122 +4997,6 @@ components: Link to the previous subset of resources qualified. Empty if current subset is the first subset returned. example: "" - APIList: - title: API List - type: object - properties: - count: - type: integer - description: | - Number of APIs returned. - example: 1 - list: - type: array - items: - $ref: '#/components/schemas/APIInfomation' - pagination: - $ref: '#/components/schemas/PaginationApis' - APIInfomation: - title: API Info object with basic API details. - type: object - properties: - id: - type: string - example: 01234567-0123-0123-0123-012345678901 - name: - type: string - example: CalculatorAPI - description: - type: string - example: A calculator API that supports basic operations - context: - type: string - example: CalculatorAPI - additionalProperties: - type: array - items: - type: object - properties: - name: - type: string - value: - type: string - display: - type: boolean - description: Map of custom properties of API - additionalPropertiesMap: - type: object - additionalProperties: - type: object - properties: - name: - type: string - value: - type: string - display: - type: boolean - default: false - version: - type: string - example: 1.0.0 - provider: - type: string - description: | - If the provider value is not given, the user invoking the API will be used as the provider. - example: admin - type: - type: string - example: HTTP - audience: - type: string - description: The audience of the API. Accepted values are PUBLIC, SINGLE - example: PUBLIC - enum: - - PUBLIC - - SINGLE - lifeCycleStatus: - type: string - example: CREATED - workflowStatus: - type: string - example: APPROVED - hasThumbnail: - type: boolean - example: true - securityScheme: - type: array - items: - type: string - createdTime: - type: string - example: 2021-02-11 09:57:25 - updatedTime: - type: string - example: 2021-02-11 09:57:25 - updatedBy: - type: string - example: wso2.system.user - gatewayVendor: - type: string - example: wso2 - advertiseOnly: - type: boolean - example: true - monetizedInfo: - type: boolean - example: true - businessOwner: - type: string - example: Business Owner - businessOwnerEmail: - type: string - example: businessowner@abc.com - TechnicalOwner: - type: string - example: Technical Owner - TechnicalOwnerEmail: - type: string - example: technicalowner@abc.com PaginationApis: title: Pagination type: object @@ -5154,6 +5020,32 @@ components: description: | Link to the previous subset of resources qualified. Empty if current subset is the first subset returned. + SearchResultList: + title: Unified Search Result List + type: object + properties: + apis: + type: array + items: + $ref: '#/components/schemas/ApiResult' + count: + type: integer + description: | + Number of results returned. + example: 1 + pagination: + $ref: '#/components/schemas/Pagination' + ApiResult: + type: object + properties: + provider: + type: string + name: + type: string + version: + type: string + id: + type: string responses: BadRequest: description: Bad Request. Invalid request or validation error. @@ -5453,14 +5345,6 @@ components: required: true schema: type: string - providerName: - name: providerName - in: path - description: | - Provider Name - required: true - schema: - type: string apiId: name: apiId in: path From 7a4e130b8a792fe1ee8254607fd670e5e8e58057 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 11 Dec 2023 11:43:12 +0530 Subject: [PATCH 14/25] Delete improved --- .../persistence/RegistryPersistenceImpl.java | 11 +++++------ .../utils/RegistryPersistenceUtil.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 11ddfc4db52b..993258e48ee6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -796,7 +796,6 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep registry.delete(artifact.getPath()); } } - String artifactId = getAPIArtifact(apiId, registry).getId(); String apiPath = getAPIArtifact(apiId, registry).getPath(); artifactManager.removeGenericArtifact(artifactId); @@ -817,17 +816,17 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep if (registry.resourceExists(wsdlArchivePath)) { registry.delete(wsdlArchivePath); } - + String providerName = RegistryPersistenceUtil.extractProvider(apiPath); /*Remove API Definition Resource - swagger*/ String apiDefinitionFilePath = APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR + - identifier.getApiName() + '-' + identifier.getVersion() + '-' + identifier.getProviderName(); + identifier.getApiName() + '-' + identifier.getVersion() + '-' + providerName; if (registry.resourceExists(apiDefinitionFilePath)) { registry.delete(apiDefinitionFilePath); } /*remove empty directories*/ String apiCollectionPath = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + - identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getApiName(); + providerName + RegistryConstants.PATH_SEPARATOR + identifier.getApiName(); if (registry.resourceExists(apiCollectionPath)) { Resource apiCollection = registry.get(apiCollectionPath); CollectionImpl collection = (CollectionImpl) apiCollection; @@ -841,7 +840,7 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep } String apiProviderPath = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + - identifier.getProviderName(); + providerName; if (registry.resourceExists(apiProviderPath)) { Resource providerCollection = registry.get(apiProviderPath); @@ -849,7 +848,7 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep //if there is no api for given provider delete the provider directory if (collection.getChildCount() == 0) { if (log.isDebugEnabled()) { - log.debug("No more APIs from the provider " + identifier.getProviderName() + " found. " + + log.debug("No more APIs from the provider " + providerName + " found. " + "Removing provider collection from registry"); } registry.delete(apiProviderPath); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 67bd67eb6aa7..562515896382 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -1826,6 +1826,21 @@ public static void addLifecycleIfNotExists(int tenantId) throws APIPersistenceEx } } + public static String extractProvider(String apiPath) { + String[] parts = apiPath.split("/"); + Integer index = null; + for (int i = 0; i < parts.length; i++) { + if (parts[i].equals("provider")) { + index = i; + } + } + if (index != -1 && index < parts.length - 1) { + return parts[index + 1]; + } else { + return null; + } + } + private static RegistryService getRegistryService() { return ServiceReferenceHolder.getInstance().getRegistryService(); } From bf8d504b9869976ab13b1698e21c4acaba87c3b6 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 11 Dec 2023 11:59:37 +0530 Subject: [PATCH 15/25] Added validation to remove trailing leading spaces and multiple occurence of spaces. --- .../api/publisher/v1/common/mappings/PublisherCommonUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java index 8b66a1163e1e..27dfa2e959b3 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/PublisherCommonUtils.java @@ -839,6 +839,8 @@ public static void validateScopes(API api) throws APIManagementException { public static API addAPIWithGeneratedSwaggerDefinition(APIDTO apiDto, String oasVersion, String username, String organization) throws APIManagementException, CryptoException { + String name = apiDto.getName(); + apiDto.setName(name.trim().replaceAll("\\s{2,}", " ")); if (APIDTO.TypeEnum.ASYNC.equals(apiDto.getType())) { throw new APIManagementException("ASYNC API type does not support API creation from scratch", ExceptionCodes.API_CREATION_NOT_SUPPORTED_FOR_ASYNC_TYPE_APIS); From 88a9538ad32852642ec67c2a05b74d1193abd592 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Mon, 11 Dec 2023 20:38:17 +0530 Subject: [PATCH 16/25] add apim:api_provider_change to tenant-conf.json --- .../src/main/resources/tenant/tenant-conf.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/resources/tenant/tenant-conf.json b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/resources/tenant/tenant-conf.json index b8bab6c3a32f..12aabf40cca5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/resources/tenant/tenant-conf.json +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/resources/tenant/tenant-conf.json @@ -348,6 +348,18 @@ { "Name": "apim:policies_import_export", "Roles": "admin,Internal/devops" + }, + { + "Name": "apim:admin_tier_manage", + "Roles": "admin" + }, + { + "Name": "apim:admin_tier_view", + "Roles": "admin" + }, + { + "Name": "apim:api_provider_change", + "Roles": "admin" } ] }, From 810c6dc72c5e880ea795962686d7235f9d8ae5d2 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Tue, 12 Dec 2023 10:49:01 +0530 Subject: [PATCH 17/25] API Constants added --- .../wso2/carbon/apimgt/impl/APIAdminImpl.java | 9 +-- .../api/admin/v1/impl/ApisApiServiceImpl.java | 79 +++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java index df2266420357..5de01f1bff92 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java @@ -1330,7 +1330,6 @@ public void updateApiProvider(String apiId, String provider, String organisation public Map searchPaginatedApis(String searchQuery, String organization, int start, int end) throws APIManagementException { ArrayList compoundResult = new ArrayList(); - Map docMap = new HashMap(); Map result = new HashMap(); SortedSet apiSet = new TreeSet(new APINameComparator()); String modifiedSearchQuery = buildSearchQuery(searchQuery); @@ -1341,7 +1340,7 @@ public Map searchPaginatedApis(String searchQuery, String organi if (results != null) { List resultList = results.getApis(); for (SearchContent item : resultList) { - if ("API".equals(item.getType())) { + if (APIConstants.API_IDENTIFIER_TYPE.equals(item.getType())) { AdminApiSearchContent adminSearchApi = (AdminApiSearchContent) item; API api = new API(new APIIdentifier(adminSearchApi.getProvider(), adminSearchApi.getName(), adminSearchApi.getVersion())); @@ -1350,15 +1349,15 @@ public Map searchPaginatedApis(String searchQuery, String organi } } compoundResult.addAll(apiSet); - compoundResult.addAll(docMap.entrySet()); compoundResult.sort(new ContentSearchResultNameComparator()); + result.put(APIConstants.API_DATA_LENGTH, compoundResult.size()); } else { - result.put("length", compoundResult.size()); + result.put(APIConstants.API_DATA_LENGTH, compoundResult.size()); } } catch (APIPersistenceException e) { throw new APIManagementException("Error while searching apis ", e); } - result.put("apis", compoundResult); + result.put(APIConstants.API_DATA_APIS, compoundResult); return result; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java new file mode 100644 index 000000000000..c0312503c1d8 --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -0,0 +1,79 @@ +package org.wso2.carbon.apimgt.rest.api.admin.v1.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.wso2.carbon.apimgt.api.APIAdmin; +import org.wso2.carbon.apimgt.api.APIManagementException; +import org.wso2.carbon.apimgt.api.ExceptionCodes; +import org.wso2.carbon.apimgt.api.model.API; +import org.wso2.carbon.apimgt.impl.APIAdminImpl; +import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.restapi.publisher.SearchApiServiceImplUtil; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; +import org.wso2.carbon.apimgt.rest.api.admin.v1.ApisApiService; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.ApiResultDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.SearchResultListDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings.APIInfoMappingUtil; +import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; +import org.wso2.carbon.apimgt.rest.api.util.RestApiConstants; +import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.ws.rs.core.Response; + +public class ApisApiServiceImpl implements ApisApiService { + + private static final Log log = LogFactory.getLog(ApisApiServiceImpl.class); + + public Response getAllAPIs(Integer limit, Integer offset, String query, String ifNoneMatch, + MessageContext messageContext) { + SearchResultListDTO resultListDTO = new SearchResultListDTO(); + limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; + offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; + query = query == null ? APIConstants.CHAR_ASTERIX : query; + try { + APIAdmin apiAdmin = new APIAdminImpl(); + String organization = RestApiUtil.getOrganization(messageContext); + Map result = apiAdmin + .searchPaginatedApis(query, organization, offset, limit); + List apis = SearchApiServiceImplUtil.getAPIListFromAPISearchResult(result); + List allMatchedResults = getAllMatchedResults(apis); + resultListDTO.setApis(allMatchedResults); + resultListDTO.setCount(allMatchedResults.size()); + } catch (APIManagementException e) { + RestApiUtil.handleInternalServerError(e.getMessage(), e, log); + } + return Response.ok().entity(resultListDTO).build(); + } + + public Response providerNamePost(String provider, String apiId, MessageContext messageContext) + throws APIManagementException { + String tenantDomain = RestApiCommonUtil.getLoggedInUserTenantDomain(); + try { + if (!APIUtil.isUserExist(provider)) { + throw new APIManagementException("User " + provider + " not found.", + ExceptionCodes.USER_NOT_FOUND); + } + APIAdmin apiAdmin = new APIAdminImpl(); + apiAdmin.updateApiProvider(apiId, provider, tenantDomain); + } catch (APIManagementException e) { + throw new APIManagementException("Error while changing the API provider", e); + } + return Response.ok().build(); + } + + private List getAllMatchedResults(List apis) throws APIManagementException { + List allMatchedResults = new ArrayList<>(); + for (Object searchResult : apis) { + if (searchResult instanceof API) { + API api = (API) searchResult; + ApiResultDTO apiResult = APIInfoMappingUtil.fromAPIToAPIResultDTO(api); + allMatchedResults.add(apiResult); + } + } + return allMatchedResults; + } +} From b131264977de2c4c1fff7ea41953f5edfd1642ed Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 13 Dec 2023 09:50:57 +0530 Subject: [PATCH 18/25] add apis doc bug fixed if provider changed, and search issue fixed. --- .../carbon/apimgt/persistence/RegistryPersistenceImpl.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 993258e48ee6..3c5eabd0f8d9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -2165,8 +2165,7 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat APIConstants.API_KEY); GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiId); - String apiProviderName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_PROVIDER); - apiProviderName = RegistryPersistenceUtil.replaceEmailDomain(apiProviderName); + String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath()); String apiName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_NAME); String apiVersion = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_VERSION); @@ -2419,8 +2418,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S APIConstants.API_KEY); GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiId); - String apiProviderName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_PROVIDER); - apiProviderName = RegistryPersistenceUtil.replaceEmailDomain(apiProviderName); + String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath()); String apiName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_NAME); String apiVersion = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_VERSION); From 433717f760fdbf19e565337ae0b875e0a8383f80 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Wed, 13 Dec 2023 21:31:31 +0530 Subject: [PATCH 19/25] Pagination issues solved. --- .../wso2/carbon/apimgt/impl/APIAdminImpl.java | 3 +- .../wso2/carbon/apimgt/impl/APIConstants.java | 1 + .../persistence/RegistryPersistenceImpl.java | 3 +- .../dto/AdminContentSearchResult.java | 6 +++ .../api/admin/v1/impl/ApisApiServiceImpl.java | 3 ++ .../v1/utils/mappings/APIInfoMappingUtil.java | 37 +++++++++++++++++++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java index 5de01f1bff92..26efd07ad93c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java @@ -1336,7 +1336,7 @@ public Map searchPaginatedApis(String searchQuery, String organi try { APIPersistence apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); AdminContentSearchResult results = apiPersistenceInstance.searchContentForAdmin(organization, - modifiedSearchQuery, start, end, Integer.MAX_VALUE); + modifiedSearchQuery, start, end, end); if (results != null) { List resultList = results.getApis(); for (SearchContent item : resultList) { @@ -1351,6 +1351,7 @@ public Map searchPaginatedApis(String searchQuery, String organi compoundResult.addAll(apiSet); compoundResult.sort(new ContentSearchResultNameComparator()); result.put(APIConstants.API_DATA_LENGTH, compoundResult.size()); + result.put(APIConstants.ADMIN_API_LIST_RESPONSE_PARAMS_TOTAL, results.getApiTotal()); } else { result.put(APIConstants.API_DATA_LENGTH, compoundResult.size()); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index a85d01779088..a08feb441db6 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -1649,6 +1649,7 @@ private ConfigParameters() { public static final String API_DATA_DEFAULT_THUMB = "images/api-default.png"; public static final String API_DATA_APIS = "apis"; public static final String API_DATA_TOT_LENGTH = "totalLength"; + public static final String ADMIN_API_LIST_RESPONSE_PARAMS_TOTAL = "totalLength"; public static final String API_DATA_LENGTH = "length"; public static final String API_DATA_ISMORE = "isMore"; public static final String API_DATA_PRODUCTION_ENDPOINTS = "production_endpoints"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 3c5eabd0f8d9..7fec84ee1e1d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -3795,7 +3795,7 @@ public AdminContentSearchResult searchContentForAdmin(String org, String searchQ isTenantFlowStarted = holder.isTenantFlowStarted(); String tenantAwareUsername = getTenantAwareUsername(RegistryPersistenceUtil.getTenantAdminUserName(org)); PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(tenantAwareUsername); - PaginationContext.init(start, Integer.MAX_VALUE, "ASC", APIConstants.API_OVERVIEW_NAME, limit); + PaginationContext.init(start, count, "ASC", APIConstants.API_OVERVIEW_NAME, limit); GenericArtifactManager apiArtifactManager = RegistryPersistenceUtil.getArtifactManager(registry, APIConstants.API_KEY); @@ -3867,6 +3867,7 @@ public AdminContentSearchResult searchContentForAdmin(String org, String searchQ } result.setApiCount(contentData.size()); result.setApis(contentData); + result.setApiTotal(totalLength); } } catch (RegistryException | IndexerException | APIManagementException e) { throw new APIPersistenceException("Error while searching for content ", e); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java index 7cb52a3c70cb..6a87b83d659e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/AdminContentSearchResult.java @@ -25,6 +25,12 @@ public class AdminContentSearchResult { int apiCount; + + public int getApiTotal() { return apiTotal; } + + public void setApiTotal(int apiTotal) { this.apiTotal = apiTotal; } + + int apiTotal; int applicationCount; List apis = new ArrayList(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java index c0312503c1d8..2ffa9073abc9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -15,6 +15,7 @@ import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.ApiResultDTO; import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.SearchResultListDTO; import org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings.APIInfoMappingUtil; +import org.wso2.carbon.apimgt.rest.api.admin.v1.utils.mappings.ApplicationMappingUtil; import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.util.RestApiConstants; import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; @@ -43,6 +44,8 @@ public Response getAllAPIs(Integer limit, Integer offset, String query, String i List allMatchedResults = getAllMatchedResults(apis); resultListDTO.setApis(allMatchedResults); resultListDTO.setCount(allMatchedResults.size()); + APIInfoMappingUtil.setPaginationParams(resultListDTO, limit, offset, (Integer) result + .get(APIConstants.ADMIN_API_LIST_RESPONSE_PARAMS_TOTAL)); } catch (APIManagementException e) { RestApiUtil.handleInternalServerError(e.getMessage(), e, log); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java index 428efe885b50..c7ad8e99a620 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/utils/mappings/APIInfoMappingUtil.java @@ -23,12 +23,16 @@ import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoDTO; import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.APIInfoListDTO; import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.ApiResultDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.PaginationDTO; +import org.wso2.carbon.apimgt.rest.api.admin.v1.dto.SearchResultListDTO; +import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.common.RestApiConstants; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class APIInfoMappingUtil { @@ -73,6 +77,39 @@ public static APIInfoListDTO fromAPIInfoListToDTO(List apiIds) th return apiInfoListDTO; } + public static void setPaginationParams(SearchResultListDTO apiListDTO, int limit, int offset, + int size) { + + Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, size); + + String paginatedPrevious = ""; + String paginatedNext = ""; + + if (paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET) != null) { + paginatedPrevious = RestApiCommonUtil + .getApplicationPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), + paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_LIMIT), null); + } + + if (paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET) != null) { + paginatedNext = RestApiCommonUtil + .getApplicationPaginatedURL(paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET), + paginatedParams.get(RestApiConstants.PAGINATION_NEXT_LIMIT), null); + } + PaginationDTO paginationDTO = getPaginationDTO(limit, offset, size, paginatedNext, paginatedPrevious); + apiListDTO.setPagination(paginationDTO); + } + + private static PaginationDTO getPaginationDTO(int limit, int offset, int total, String next, String previous) { + PaginationDTO paginationDTO = new PaginationDTO(); + paginationDTO.setLimit(limit); + paginationDTO.setOffset(offset); + paginationDTO.setTotal(total); + paginationDTO.setNext(next); + paginationDTO.setPrevious(previous); + return paginationDTO; + } + public static ApiResultDTO fromAPIToAPIResultDTO(API api) { ApiResultDTO apiResultDTO = new ApiResultDTO(); apiResultDTO.setId(api.getUuid()); From b2cc551edaa727b045fc4e7f52110e26d6d33dc8 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Thu, 14 Dec 2023 15:31:30 +0530 Subject: [PATCH 20/25] Extract api provider feature added --- .../persistence/RegistryPersistenceImpl.java | 9 ++++++--- .../utils/RegistryPersistenceUtil.java | 17 ++++------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 7fec84ee1e1d..645602ad9392 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -816,7 +816,8 @@ public void deleteAPI(Organization org, String apiId) throws APIPersistenceExcep if (registry.resourceExists(wsdlArchivePath)) { registry.delete(wsdlArchivePath); } - String providerName = RegistryPersistenceUtil.extractProvider(apiPath); + String providerName = RegistryPersistenceUtil.extractProvider(apiPath, + apiArtifact.getQName().getLocalPart()); /*Remove API Definition Resource - swagger*/ String apiDefinitionFilePath = APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR + identifier.getApiName() + '-' + identifier.getVersion() + '-' + providerName; @@ -2165,7 +2166,8 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat APIConstants.API_KEY); GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiId); - String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath()); + String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath(), + apiArtifact.getQName().getLocalPart()); String apiName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_NAME); String apiVersion = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_VERSION); @@ -2418,7 +2420,8 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S APIConstants.API_KEY); GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiId); - String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath()); + String apiProviderName = RegistryPersistenceUtil.extractProvider(apiArtifact.getPath(), + apiArtifact.getQName().getLocalPart()); String apiName = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_NAME); String apiVersion = apiArtifact.getAttribute(APIConstants.API_OVERVIEW_VERSION); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 562515896382..405285bca48e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -1826,19 +1826,10 @@ public static void addLifecycleIfNotExists(int tenantId) throws APIPersistenceEx } } - public static String extractProvider(String apiPath) { - String[] parts = apiPath.split("/"); - Integer index = null; - for (int i = 0; i < parts.length; i++) { - if (parts[i].equals("provider")) { - index = i; - } - } - if (index != -1 && index < parts.length - 1) { - return parts[index + 1]; - } else { - return null; - } + public static String extractProvider(String apiPath, String apiName) { + int startIndex = apiPath.indexOf("provider/") + "provider/" .length(); + int endIndex = apiPath.indexOf("/" + apiName + "/"); + return apiPath.substring(startIndex, endIndex); } private static RegistryService getRegistryService() { From a561c1711fe57b47fe977f5cb39b72d1e574b00d Mon Sep 17 00:00:00 2001 From: shnrndk Date: Sun, 17 Dec 2023 18:07:51 +0530 Subject: [PATCH 21/25] add comments --- .../org/wso2/carbon/apimgt/api/APIAdmin.java | 4 +- .../wso2/carbon/apimgt/impl/APIAdminImpl.java | 22 ++++++- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 11 +++- .../persistence/RegistryPersistenceImpl.java | 1 - .../api/admin/v1/impl/ApisApiServiceImpl.java | 58 +++++++++++++------ 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java index e736437b5b08..d5df5ddeb443 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIAdmin.java @@ -470,7 +470,7 @@ boolean isScopeExists(String username, String scopeName) * Update the Api Provider of a given Api Id * * @param apiId Api ID - * @param provider ProviderName/Owner of the Api + * @param provider New ProviderName/Owner of the Api * @param organisation Organisation * @throws APIManagementException */ @@ -480,7 +480,7 @@ boolean isScopeExists(String username, String scopeName) * Get/Search All Apis in admin portal * * @param searchQuery Api name search query - * @param organization organisation + * @param organization organization * @param start * @param end * @return diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java index 26efd07ad93c..f1afd0815a5c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java @@ -1327,11 +1327,21 @@ public void updateApiProvider(String apiId, String provider, String organisation } } + /** + * get/search paginated APIs in admin portal + * + * @param searchQuery API name search query + * @param organization organization + * @param start start index of the pagination + * @param end end index of the pagination + * @return APIs result object + * @throws APIManagementException if an error occurs when searching/getting the APIs + */ public Map searchPaginatedApis(String searchQuery, String organization, int start, int end) throws APIManagementException { - ArrayList compoundResult = new ArrayList(); - Map result = new HashMap(); - SortedSet apiSet = new TreeSet(new APINameComparator()); + ArrayList compoundResult = new ArrayList<>(); + Map result = new HashMap<>(); + SortedSet apiSet = new TreeSet<>(new APINameComparator()); String modifiedSearchQuery = buildSearchQuery(searchQuery); try { APIPersistence apiPersistenceInstance = PersistenceFactory.getAPIPersistenceInstance(); @@ -1362,6 +1372,12 @@ public Map searchPaginatedApis(String searchQuery, String organi return result; } + /** + * If the user provided a search query then it will use that, otherwise it will use the asterix(*) symbol. + * + * @param searchQuery searchQuery that the user provided + * @return modified searchQuery + */ private String buildSearchQuery(String searchQuery) { if (searchQuery.equals(APIConstants.CHAR_ASTERIX)) { return String.format(APIConstants.ADMIN_PORTAL_GET_APIS_QUERY, APIConstants.CHAR_ASTERIX); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index 7fe692cece3e..4b83fadeeab7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -18178,6 +18178,13 @@ private void updateAPIServiceMapping(int apiId, String serviceKey, String md5, i } } + /** + * Update the API provider of a given API + * + * @param apiUUID API id of the API that needs to update the provider + * @param providerName New API provider + * @throws APIManagementException if an error occurs when changing the API provider + */ public void updateApiProvider(String apiUUID, String providerName) throws APIManagementException { try (Connection connection = APIMgtDBUtil.getConnection()) { @@ -18189,9 +18196,7 @@ public void updateApiProvider(String apiUUID, String providerName) connection.commit(); } catch (SQLException e) { connection.rollback(); - handleException("Error while updating the API provider of " + apiUUID, e); - } finally { - connection.setAutoCommit(true); + throw e; } } catch (SQLException e) { handleException("Error while updating the API provider of " + apiUUID, e); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index 645602ad9392..fba1410b5c90 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -3788,7 +3788,6 @@ public void changeApiProvider(String providerName, String apiId, String org) @Override public AdminContentSearchResult searchContentForAdmin(String org, String searchQuery, int start, int count, int limit) throws APIPersistenceException { - log.debug("Requested query for admin key Manager usages API search: " + searchQuery); boolean isTenantFlowStarted = false; AdminContentSearchResult result = null; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java index 2ffa9073abc9..0d48174a9732 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -29,46 +29,68 @@ public class ApisApiServiceImpl implements ApisApiService { private static final Log log = LogFactory.getLog(ApisApiServiceImpl.class); + /** + * This method gets all the APIs in the admin portal. + * + * @param limit pagination limit/ end value + * @param offset pagination start value + * @param query search query if the user has given any. + * @param ifNoneMatch + * @param messageContext + * @return api results + * @throws APIManagementException If there is any when getting the all apis + */ public Response getAllAPIs(Integer limit, Integer offset, String query, String ifNoneMatch, - MessageContext messageContext) { + MessageContext messageContext) throws APIManagementException { SearchResultListDTO resultListDTO = new SearchResultListDTO(); limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; query = query == null ? APIConstants.CHAR_ASTERIX : query; - try { - APIAdmin apiAdmin = new APIAdminImpl(); - String organization = RestApiUtil.getOrganization(messageContext); - Map result = apiAdmin - .searchPaginatedApis(query, organization, offset, limit); - List apis = SearchApiServiceImplUtil.getAPIListFromAPISearchResult(result); - List allMatchedResults = getAllMatchedResults(apis); - resultListDTO.setApis(allMatchedResults); - resultListDTO.setCount(allMatchedResults.size()); - APIInfoMappingUtil.setPaginationParams(resultListDTO, limit, offset, (Integer) result - .get(APIConstants.ADMIN_API_LIST_RESPONSE_PARAMS_TOTAL)); - } catch (APIManagementException e) { - RestApiUtil.handleInternalServerError(e.getMessage(), e, log); - } + APIAdmin apiAdmin = new APIAdminImpl(); + String organization = RestApiUtil.getOrganization(messageContext); + Map result = apiAdmin + .searchPaginatedApis(query, organization, offset, limit); + List apis = SearchApiServiceImplUtil.getAPIListFromAPISearchResult(result); + List allMatchedResults = getAllMatchedResults(apis); + resultListDTO.setApis(allMatchedResults); + resultListDTO.setCount(allMatchedResults.size()); + APIInfoMappingUtil.setPaginationParams(resultListDTO, limit, offset, (Integer) result + .get(APIConstants.ADMIN_API_LIST_RESPONSE_PARAMS_TOTAL)); return Response.ok().entity(resultListDTO).build(); } + /** + * change API provider + * + * @param provider new provider name + * @param apiId API Id of the given API + * @param messageContext + * @return whether the api provider change successful or not + * @throws APIManagementException if there is any error when changing the API provider. + */ public Response providerNamePost(String provider, String apiId, MessageContext messageContext) throws APIManagementException { - String tenantDomain = RestApiCommonUtil.getLoggedInUserTenantDomain(); + String organisation = RestApiCommonUtil.getLoggedInUserTenantDomain(); try { if (!APIUtil.isUserExist(provider)) { throw new APIManagementException("User " + provider + " not found.", ExceptionCodes.USER_NOT_FOUND); } APIAdmin apiAdmin = new APIAdminImpl(); - apiAdmin.updateApiProvider(apiId, provider, tenantDomain); + apiAdmin.updateApiProvider(apiId, provider, organisation); } catch (APIManagementException e) { throw new APIManagementException("Error while changing the API provider", e); } return Response.ok().build(); } - private List getAllMatchedResults(List apis) throws APIManagementException { + /** + * Return the apis object as ApiResultDTO object. + * + * @param apis apis object + * @return ApiResultDTO object + */ + private List getAllMatchedResults(List apis) { List allMatchedResults = new ArrayList<>(); for (Object searchResult : apis) { if (searchResult instanceof API) { From 40c4078a0c7cd39b2395df87e678132a40f48da3 Mon Sep 17 00:00:00 2001 From: shnrndk Date: Tue, 19 Dec 2023 14:33:19 +0530 Subject: [PATCH 22/25] add exception codes --- .../java/org/wso2/carbon/apimgt/api/ExceptionCodes.java | 6 ++++-- .../main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java | 3 ++- .../apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java index a387f492fc3e..8b77bfd668f4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java @@ -541,8 +541,10 @@ public enum ExceptionCodes implements ErrorHandler { "Revision deployment request conflicted with the current deployment state of the revision %s. Please try again later", false), INVALID_API_ID(902006, "Invalid API ID", 404, "The provided API ID is not found %s", false), INVALID_ENDPOINT_CONFIG(902012, "Endpoint config value(s) is(are) not valid", 400, "Endpoint config value(s) is(are) not valid"), - ARTIFACT_SYNC_HTTP_REQUEST_FAILED(903009, "Error while retrieving from remote endpoint", 500, "Error while executing HTTP request to retrieve from remote endpoint"); - + ARTIFACT_SYNC_HTTP_REQUEST_FAILED(903009, "Error while retrieving from remote endpoint", 500, "Error while executing HTTP request to retrieve from remote endpoint"), + // Admin portal get apis and api provider change related errors + CHANGE_API_PROVIDER_FAILED(903011, "Error while changing the API provider", 500, "Error while changing the API provider in the registry or DB"), + GET_SEARCH_APIS_IN_ADMIN_FAILED(903012, "Error while getting the apis", 500, "Error while getting/searching the apis from registry"); private final long errorCode; private final String errorMessage; private final int httpStatusCode; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java index f1afd0815a5c..24b1f2d4944f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIAdminImpl.java @@ -1366,7 +1366,8 @@ public Map searchPaginatedApis(String searchQuery, String organi result.put(APIConstants.API_DATA_LENGTH, compoundResult.size()); } } catch (APIPersistenceException e) { - throw new APIManagementException("Error while searching apis ", e); + throw new APIManagementException("Error while searching apis ", + ExceptionCodes.GET_SEARCH_APIS_IN_ADMIN_FAILED); } result.put(APIConstants.API_DATA_APIS, compoundResult); return result; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java index 0d48174a9732..f08a837cbe47 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -79,7 +79,8 @@ public Response providerNamePost(String provider, String apiId, MessageContext m APIAdmin apiAdmin = new APIAdminImpl(); apiAdmin.updateApiProvider(apiId, provider, organisation); } catch (APIManagementException e) { - throw new APIManagementException("Error while changing the API provider", e); + throw new APIManagementException("Error while changing the API provider", + ExceptionCodes.CHANGE_API_PROVIDER_FAILED); } return Response.ok().build(); } From a8775522eeae6a224148469405bb5cdb7c76c4c5 Mon Sep 17 00:00:00 2001 From: Sahan Randika Date: Fri, 19 Jan 2024 15:34:40 +0530 Subject: [PATCH 23/25] Add constants and license header --- .../wso2/carbon/apimgt/api/ExceptionCodes.java | 5 +---- .../carbon/apimgt/persistence/APIConstants.java | 1 + .../utils/RegistryPersistenceUtil.java | 3 ++- .../api/admin/v1/impl/ApisApiServiceImpl.java | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java index 5f21ca8fe689..a338d4ceda2b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java @@ -543,13 +543,10 @@ public enum ExceptionCodes implements ErrorHandler { INVALID_API_ID(902006, "Invalid API ID", 404, "The provided API ID is not found %s", false), INVALID_ENDPOINT_CONFIG(902012, "Endpoint config value(s) is(are) not valid", 400, "Endpoint config value(s) is(are) not valid"), ARTIFACT_SYNC_HTTP_REQUEST_FAILED(903009, "Error while retrieving from remote endpoint", 500, "Error while executing HTTP request to retrieve from remote endpoint"), + KEY_MANAGER_RESTRICTED_FOR_USER(902013, "Unauthorized Access to Key Manager", 403, "Key Manager is Restricted for this user"), // Admin portal get apis and api provider change related errors CHANGE_API_PROVIDER_FAILED(903011, "Error while changing the API provider", 500, "Error while changing the API provider in the registry or DB"), GET_SEARCH_APIS_IN_ADMIN_FAILED(903012, "Error while getting the apis", 500, "Error while getting/searching the apis from registry"); - - KEY_MANAGER_RESTRICTED_FOR_USER(902013, "Unauthorized Access to Key Manager", 403, "Key Manager is Restricted for this user"), - ARTIFACT_SYNC_HTTP_REQUEST_FAILED(903009, "Error while retrieving from remote endpoint", 500, "Error while executing HTTP request to retrieve from remote endpoint"); - private final long errorCode; private final String errorMessage; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java index 3acfce4d1ed3..a76dea914eb1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java @@ -244,6 +244,7 @@ public static class Monetization { public static final String TAG_COLON_SEARCH_TYPE_PREFIX = "tag:"; public static final String NAME_TYPE_PREFIX = "name"; private static final String PROVIDER_SEARCH_TYPE_PREFIX = "provider"; + public static final String API_PROVIDER_SUFFIX_SLASH = "provider/"; private static final String VERSION_SEARCH_TYPE_PREFIX = "version"; private static final String CONTEXT_SEARCH_TYPE_PREFIX = "context"; public static final String CONTENT_SEARCH_TYPE_PREFIX = "content"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 405285bca48e..8c35fc554c3c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -1827,7 +1827,8 @@ public static void addLifecycleIfNotExists(int tenantId) throws APIPersistenceEx } public static String extractProvider(String apiPath, String apiName) { - int startIndex = apiPath.indexOf("provider/") + "provider/" .length(); + int startIndex = apiPath.indexOf(APIConstants.API_PROVIDER_SUFFIX_SLASH) + + APIConstants.API_PROVIDER_SUFFIX_SLASH.length(); int endIndex = apiPath.indexOf("/" + apiName + "/"); return apiPath.substring(startIndex, endIndex); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java index f08a837cbe47..432496b9b111 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.admin.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/admin/v1/impl/ApisApiServiceImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.wso2.carbon.apimgt.rest.api.admin.v1.impl; import org.apache.commons.logging.Log; From c4e957a25dc551aac6d2e8d6886d4a753b3a2e82 Mon Sep 17 00:00:00 2001 From: Sahan Randika Date: Wed, 7 Feb 2024 19:42:11 +0530 Subject: [PATCH 24/25] update api provider suffix slash constant --- .../java/org/wso2/carbon/apimgt/persistence/APIConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java index a76dea914eb1..7a19bff16c72 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/APIConstants.java @@ -244,7 +244,7 @@ public static class Monetization { public static final String TAG_COLON_SEARCH_TYPE_PREFIX = "tag:"; public static final String NAME_TYPE_PREFIX = "name"; private static final String PROVIDER_SEARCH_TYPE_PREFIX = "provider"; - public static final String API_PROVIDER_SUFFIX_SLASH = "provider/"; + public static final String API_PROVIDER_SUFFIX_SLASH = PROVIDER_SEARCH_TYPE_PREFIX + "/"; private static final String VERSION_SEARCH_TYPE_PREFIX = "version"; private static final String CONTEXT_SEARCH_TYPE_PREFIX = "context"; public static final String CONTENT_SEARCH_TYPE_PREFIX = "content"; From 9d96651d7a877c678972674c4ef2fe07a539f0a7 Mon Sep 17 00:00:00 2001 From: Sahan Randika Date: Wed, 7 Feb 2024 19:37:57 +0530 Subject: [PATCH 25/25] fix deploy pizzashackapi display issue after publish --- .../wso2/carbon/apimgt/rest/api/common/RestApiConstants.java | 1 + .../rest/api/publisher/v1/impl/SearchApiServiceImpl.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java index 09bc187b95ca..c98caecabccd 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java @@ -203,6 +203,7 @@ public final class RestApiConstants { public static final String ORG_ID = "ORG_ID"; public static final int PAGINATION_LIMIT_DEFAULT = 25; + public static final String PIZZASHACK_SEARCH_QUERY = "name:PizzaShackAPI version:1.0 context:pizzashack"; public static final int PAGINATION_OFFSET_DEFAULT = 0; public static final String PAGINATION_NEXT_OFFSET = "next_offset"; public static final String PAGINATION_NEXT_LIMIT = "next_limit"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java index ecb9eaa75cef..73d09820cc69 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/SearchApiServiceImpl.java @@ -50,7 +50,8 @@ public class SearchApiServiceImpl implements SearchApiService { public Response search(Integer limit, Integer offset, String query, String ifNoneMatch, MessageContext messageContext) throws APIManagementException { SearchResultListDTO resultListDTO = new SearchResultListDTO(); - if (query.startsWith("name:") || query.startsWith("description:")) { + if (!query.equals(RestApiConstants.PIZZASHACK_SEARCH_QUERY) && (query.startsWith("name:") | + query.startsWith("description:"))) { query = query.replaceAll(" ", "%20"); }