From d9138d3df211fd590087a3e464039b3eb96e8545 Mon Sep 17 00:00:00 2001 From: BLasan Date: Thu, 4 Jan 2024 12:03:37 +0530 Subject: [PATCH] Add: Support to operation and API Policies dynamically --- .../apimgt/api/model/OperationPolicy.java | 2 +- .../apimgt/api/model/subscription/API.java | 14 ++ .../common/analytics/publishers/dto/API.java | 9 ++ .../publishers/dto/OperationPolicy.java | 4 +- .../analytics/publishers/dto/URITemplate.java | 18 +++ .../SynapseAnalyticsDataProvider.java | 30 +++- .../wso2/carbon/apimgt/impl/APIConstants.java | 3 + .../apimgt/impl/APIManagerConfiguration.java | 4 + .../impl/dao/SubscriptionValidationDAO.java | 132 +++++++++++++++--- .../SubscriptionValidationSQLConstants.java | 17 ++- .../apimgt/internal/service/dto/APIDTO.java | 23 ++- .../service/dto/OperationPolicyDTO.java | 27 +++- .../utils/SubscriptionValidationDataUtil.java | 30 +++- .../src/main/resources/api.yaml | 8 ++ .../swagger.json | 39 ++++++ .../apimgt/keymgt/model/entity/API.java | 11 ++ .../repository/conf/api-manager.xml.j2 | 2 + 17 files changed, 329 insertions(+), 44 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/OperationPolicy.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/OperationPolicy.java index f4d14f6f19ed..21b8e2415172 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/OperationPolicy.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/OperationPolicy.java @@ -105,7 +105,6 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(policyName, policyVersion, direction, parameters, policyId); } @@ -124,6 +123,7 @@ public String toString() { ", direction ='" + direction + '\'' + ", order ='" + order + '\'' + ", policyId ='" + policyId + '\'' + + ", parameters ='" + parameters + '\'' + '}'; } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/subscription/API.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/subscription/API.java index 169108248163..826ee0eaa36b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/subscription/API.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/subscription/API.java @@ -18,8 +18,13 @@ package org.wso2.carbon.apimgt.api.model.subscription; +import org.wso2.carbon.apimgt.api.model.OperationPolicy; +import org.wso2.carbon.apimgt.api.model.policy.APIPolicy; + import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * Entity for keeping API related information. @@ -39,6 +44,7 @@ public class API implements CacheableEntity { private String status; private String revision; private String organization; + private Set apiPolicies = new HashSet<>(); public String getRevision() { @@ -199,4 +205,12 @@ public String getOrganization() { public void setOrganization(String organization) { this.organization = organization; } + + public void setApiPolicy(OperationPolicy apiPolicy) { + this.apiPolicies.add(apiPolicy); + } + + public Set getApiPolicies() { + return apiPolicies; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/API.java b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/API.java index bc1e4b41b045..3c14d18ebded 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/API.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/API.java @@ -31,6 +31,7 @@ public class API { private String apiCreator; private String apiCreatorTenantDomain; private List uriTemplates = new ArrayList<>(); + private List apiPolicies = new ArrayList<>(); public String getApiId() { return apiId; @@ -87,4 +88,12 @@ public List getUriTemplates() { public void setUriTemplates(List uriTemplates) { this.uriTemplates = uriTemplates; } + + public void setApiPolicies(List apiPolicies) { + this.apiPolicies = apiPolicies; + } + + public List getApiPolicies() { + return apiPolicies; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/OperationPolicy.java b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/OperationPolicy.java index dfbae52b70b6..6c8dc3d7b9f9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/OperationPolicy.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/OperationPolicy.java @@ -1,12 +1,12 @@ /* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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 + * 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 diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/URITemplate.java b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/URITemplate.java index fa87cf236701..6f93ca300eb4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/URITemplate.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.analytics/src/main/java/org/wso2/carbon/apimgt/common/analytics/publishers/dto/URITemplate.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.common.analytics.publishers.dto; import java.util.ArrayList; diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/analytics/SynapseAnalyticsDataProvider.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/analytics/SynapseAnalyticsDataProvider.java index 7ac0debff486..efb2374af789 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/analytics/SynapseAnalyticsDataProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/analytics/SynapseAnalyticsDataProvider.java @@ -64,10 +64,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import static org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS; import static org.wso2.carbon.apimgt.gateway.handlers.analytics.Constants.UNKNOWN_VALUE; @@ -172,16 +170,20 @@ public API getApi() throws DataNotFoundException { api.setApiCreatorTenantDomain(MultitenantUtils.getTenantDomain(api.getApiCreator())); List uriTemplates = new ArrayList<>(); for (URLMapping uriTemplate : apiObj.getUrlMappings()) { - org.wso2.carbon.apimgt.common.analytics.publishers.dto.URITemplate uriTemplateObj = new org.wso2.carbon.apimgt.common.analytics.publishers.dto.URITemplate(); + org.wso2.carbon.apimgt.common.analytics.publishers.dto.URITemplate uriTemplateObj + = new org.wso2.carbon.apimgt.common.analytics.publishers.dto.URITemplate(); if (uriTemplate.getHttpMethod() != null && uriTemplate.getHttpMethod() - .equals(messageContext.getProperty("api.ut.HTTP_METHOD")) && uriTemplate.getUrlPattern() != null - && uriTemplate.getUrlPattern().equals(messageContext.getProperty("api.ut.resource"))) { + .equals(messageContext.getProperty(APIMgtGatewayConstants.HTTP_METHOD)) + && uriTemplate.getUrlPattern() != null && uriTemplate.getUrlPattern() + .equals(messageContext.getProperty("API_ELECTED_RESOURCE"))) { uriTemplateObj.setResourceURI(uriTemplate.getUrlPattern()); uriTemplateObj.setHttpVerb(uriTemplate.getHttpMethod()); uriTemplateObj.setAuthScheme(uriTemplate.getAuthScheme()); - List operationPolicies = new ArrayList<>(); + List operationPolicies + = new ArrayList<>(); for (OperationPolicy operationPolicy : uriTemplate.getOperationPolicies()) { - org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy operationPolicyObj = new org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy(); + org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy operationPolicyObj + = new org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy(); operationPolicyObj.setPolicyVersion(operationPolicy.getPolicyVersion()); operationPolicyObj.setPolicyName(operationPolicy.getPolicyName()); operationPolicyObj.setPolicyId(operationPolicy.getPolicyId()); @@ -191,9 +193,23 @@ public API getApi() throws DataNotFoundException { } uriTemplateObj.setOperationPolicies(operationPolicies); uriTemplates.add(uriTemplateObj); + break; } } + List apiPolicyList = + new ArrayList<>(); + for (OperationPolicy apiPolicy : apiObj.getApiPolicies()) { + org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy operationPolicyObj + = new org.wso2.carbon.apimgt.common.analytics.publishers.dto.OperationPolicy(); + operationPolicyObj.setPolicyVersion(apiPolicy.getPolicyVersion()); + operationPolicyObj.setPolicyName(apiPolicy.getPolicyName()); + operationPolicyObj.setPolicyId(apiPolicy.getPolicyId()); + operationPolicyObj.setDirection(apiPolicy.getDirection()); + operationPolicyObj.setOrder(apiPolicy.getOrder()); + apiPolicyList.add(operationPolicyObj); + } api.setUriTemplates(uriTemplates); + api.setApiPolicies(apiPolicyList); } return api; } 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 047139c8c59a..18fff7890b8e 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 @@ -44,6 +44,8 @@ public final class APIConstants { //governance registry apimgt root location public static final String APIMGT_REGISTRY_LOCATION = "/apimgt"; + public static final String POLICY_ENABLED_FOR_ANALYTICS = "policyEnabled"; + public static final String API_CONTEXT_ID = "api.context.id"; //This is the resource name of API public static final String API_RESOURCE_NAME = "/api"; @@ -973,6 +975,7 @@ private Permissions() { public static final String API_ANALYTICS = "Analytics."; public static final String API_USAGE_ENABLED = API_ANALYTICS + "Enabled"; + public static final String API_ANALYTICS_POLICY_ENABLED = API_ANALYTICS + "PolicyEnabled"; public static final String API_ANALYTICS_REPORTER_CLASS = API_ANALYTICS + "ReporterClass"; public static final String API_ANALYTICS_PROPERTIES = API_ANALYTICS + "Properties"; public static final String API_ANALYTICS_RESPONSE_SCHEMA_NAME = API_ANALYTICS + "ResponseSchemaName"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java index 78344794a64b..ae27c12eb4ac 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIManagerConfiguration.java @@ -363,6 +363,10 @@ private void readChildElements(OMElement serverConfig, OMElement analyticsType = element.getFirstChildWithName(new QName("Type")); analyticsProps.put("type", analyticsType.getText()); + + OMElement enablePolicy = element.getFirstChildWithName(new QName("PolicyEnabled")); + analyticsProps.put("policyEnabled", enablePolicy.getText()); + analyticsProperties = analyticsProps; } else if ("PersistenceConfigs".equals(localName)) { OMElement properties = element.getFirstChildWithName(new QName("Properties")); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/SubscriptionValidationDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/SubscriptionValidationDAO.java index 46dafc25ea46..d21c6be5cbe5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/SubscriptionValidationDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/SubscriptionValidationDAO.java @@ -43,6 +43,7 @@ import org.wso2.carbon.apimgt.api.model.subscription.SubscriptionPolicy; import org.wso2.carbon.apimgt.api.model.subscription.URLMapping; import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.ThrottlePolicyConstants; import org.wso2.carbon.apimgt.impl.dao.constants.SQLConstants; import org.wso2.carbon.apimgt.impl.dao.constants.SubscriptionValidationSQLConstants; @@ -63,12 +64,16 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import static org.wso2.carbon.apimgt.impl.APIConstants.POLICY_ENABLED_FOR_ANALYTICS; + /** * This Class used to handle DAO access for subscription Validation. */ public class SubscriptionValidationDAO { private static Log log = LogFactory.getLog(SubscriptionValidationDAO.class); + private static String OPERATION_POLICY_ENABLE_WITH_ANALYTICS_EVENT = "operationPolicyEnableWithAnalyticsEvent"; + private static Map configs = APIManagerConfiguration.getAnalyticsProperties(); /* * This method can be used to retrieve all the Subscriptions in the database @@ -428,7 +433,7 @@ public List getAllApis(String organization, boolean isExpand) { String revision = resultSet.getString("REVISION_UUID"); api.setPolicy(getAPILevelTier(connection, apiUuid, revision)); if (APIConstants.API_PRODUCT.equals(apiType)) { - attachURlMappingDetailsOfApiProduct(connection, api); + attachURlMappingDetailsOfApiProduct(connection, api, revision); } else { attachURLMappingDetails(connection, revision, api); api.setEnvironment(deploymentName); @@ -1108,7 +1113,7 @@ public List getAllApis(String organization, String deployment, boolean isEx String revision = resultSet.getString("REVISION_UUID"); api.setPolicy(getAPILevelTier(connection, apiUuid, revision)); if (APIConstants.API_PRODUCT.equals(apiType)) { - attachURlMappingDetailsOfApiProduct(connection, api); + attachURlMappingDetailsOfApiProduct(connection, api, revision); } else { attachURLMappingDetails(connection, revision, api); } @@ -1144,8 +1149,9 @@ private static void setDefaultVersionContext(String apiType, API api, String ver } } - private void attachURlMappingDetailsOfApiProduct(Connection connection, API api) throws SQLException { - + private void attachURlMappingDetailsOfApiProduct(Connection connection, API api, String revisionId) + throws SQLException { + // Need API Product revision ID to avoid unnecessary iterations String sql = SubscriptionValidationSQLConstants.GET_ALL_API_PRODUCT_URI_TEMPLATES_SQL; try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { preparedStatement.setInt(1, api.getApiId()); @@ -1171,6 +1177,13 @@ private void attachURlMappingDetailsOfApiProduct(Connection connection, API api) } } } + + if(configs.containsKey(POLICY_ENABLED_FOR_ANALYTICS)) { + boolean isPolicyEnabled = Boolean.parseBoolean(configs.get(POLICY_ENABLED_FOR_ANALYTICS)); + if (isPolicyEnabled) { + attachPolicies(connection, revisionId, api); + } + } } public API getAPIByContextAndVersion(String context, String version, String deployment, boolean isExpand) { @@ -1215,7 +1228,7 @@ public API getAPIByContextAndVersion(String context, String version, String depl if (isExpand) { api.setPolicy(getAPILevelTier(connection, apiUuid, revision)); if (APIConstants.API_PRODUCT.equals(apiType)) { - attachURlMappingDetailsOfApiProduct(connection, api); + attachURlMappingDetailsOfApiProduct(connection, api, revision); } else { attachURLMappingDetails(connection, revision, api); } @@ -1261,38 +1274,111 @@ private void attachURLMappingDetails(Connection connection, String revisionId, A } } - // Attach the relevant operation policies to the resources. - attachOperationPolicies(connection, revisionId, api); + if(configs.containsKey(POLICY_ENABLED_FOR_ANALYTICS)) { + boolean isPolicyEnabled = Boolean.parseBoolean(configs.get(POLICY_ENABLED_FOR_ANALYTICS)); + if (isPolicyEnabled) { + attachPolicies(connection, revisionId, api); + } + } } - private void attachOperationPolicies(Connection connection, String revisionId, API api) throws SQLException { - try(PreparedStatement preparedStatement = connection.prepareStatement(SubscriptionValidationSQLConstants.GET_OPERATION_POLICIES_PER_URI_BY_API_SQL)){ - preparedStatement.setInt(1, api.getApiId()); - preparedStatement.setString(2, revisionId); - try(ResultSet resultSet = preparedStatement.executeQuery()){ - while (resultSet.next()){ + // Attach API and Operation Policies based on the API type (API/API Product) + private void attachPolicies(Connection connection, String revisionId, API api) throws SQLException { + + // Find an optimistic solution to separate out + if (APIConstants.API_PRODUCT.equals(api.getApiType())) { + try (PreparedStatement preparedStatement = connection.prepareStatement( + SubscriptionValidationSQLConstants.GET_OPERATION_POLICIES_PER_URI_BY_API_SQL)) { + preparedStatement.setString(1, api.getApiUUID()); + preparedStatement.setString(2, revisionId); + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { String httpMethod = resultSet.getString("HTTP_METHOD"); String urlPattern = resultSet.getString("URL_PATTERN"); String policyName = resultSet.getString("POLICY_NAME"); String policyVersion = resultSet.getString("POLICY_VERSION"); - String direction = resultSet.getString("DIRECTION"); - String policyID = resultSet.getString("POLICY_UUID"); - URLMapping urlMapping = api.getResource(urlPattern, httpMethod); - if(urlMapping!=null){ - if (StringUtils.isNotEmpty(policyID) && StringUtils.isNotEmpty(policyName) - && StringUtils.isNotEmpty(policyVersion) && StringUtils.isNotEmpty(direction)) { + String operationPolicyDirection = resultSet.getString("OPERATION_POLICY_DIRECTION"); + String operationPolicyID = resultSet.getString("OPERATION_POLICY_UUID"); + String parameters = resultSet.getString("OPERATION_PARAMS"); + URLMapping urlMapping = null; + if (StringUtils.isNotEmpty(httpMethod) && StringUtils.isNotEmpty(urlPattern)) { + urlMapping = api.getResource(urlPattern, httpMethod); + } + if (urlMapping != null) { + if (StringUtils.isNotEmpty(operationPolicyID) && StringUtils.isNotEmpty(policyName) + && StringUtils.isNotEmpty(policyVersion) && StringUtils.isNotEmpty( + operationPolicyDirection)) { OperationPolicy operationPolicy = new OperationPolicy(); - operationPolicy.setPolicyId(policyID); + operationPolicy.setPolicyId(operationPolicyID); operationPolicy.setPolicyName(policyName); operationPolicy.setPolicyVersion(policyVersion); - operationPolicy.setDirection(direction); + operationPolicy.setDirection(operationPolicyDirection); + operationPolicy.setParameters(APIMgtDBUtil.convertJSONStringToMap(parameters)); urlMapping.setOperationPolicies(operationPolicy); + api.addResource(urlMapping); } + } + } + } + } catch (APIManagementException e) { + log.error("Error while converting parameters to map for API : " + api.getApiUUID() + " Revision: " + + revisionId, e); + } + return; + } + + try (PreparedStatement preparedStatement = connection.prepareStatement( + SubscriptionValidationSQLConstants.GET_OPERATION_POLICIES_PER_URI_BY_API_SQL)) { + preparedStatement.setString(1, api.getApiUUID()); + preparedStatement.setString(2, revisionId); + try (ResultSet resultSet = preparedStatement.executeQuery()) { + while (resultSet.next()) { + String httpMethod = resultSet.getString("HTTP_METHOD"); + String urlPattern = resultSet.getString("URL_PATTERN"); + String policyName = resultSet.getString("POLICY_NAME"); + String policyVersion = resultSet.getString("POLICY_VERSION"); + String operationPolicyDirection = resultSet.getString("OPERATION_POLICY_DIRECTION"); + String apiPolicyDirection = resultSet.getString("API_POLICY_DIRECTION"); + String operationPolicyID = resultSet.getString("OPERATION_POLICY_UUID"); + String apiPolicyUUID = resultSet.getString("API_POLICY_UUID"); + + // We get parameters of the policies separately. However, this can be retrieved from the AM_API_OPERATION_POLICY_MAPPING as it contains both API and Operation Policies + String operationParameters = resultSet.getString("OPERATION_PARAMS"); + String apiParams = resultSet.getString("API_PARAMS"); + URLMapping urlMapping = null; + if (StringUtils.isNotEmpty(httpMethod) && StringUtils.isNotEmpty(urlPattern)) { + urlMapping = api.getResource(urlPattern, httpMethod); + } + if (urlMapping != null) { + if (StringUtils.isNotEmpty(operationPolicyID) && StringUtils.isNotEmpty(policyName) + && StringUtils.isNotEmpty(policyVersion) && StringUtils.isNotEmpty( + operationPolicyDirection)) { + OperationPolicy operationPolicy = new OperationPolicy(); + operationPolicy.setPolicyId(operationPolicyID); + operationPolicy.setPolicyName(policyName); + operationPolicy.setPolicyVersion(policyVersion); + operationPolicy.setDirection(operationPolicyDirection); + operationPolicy.setParameters(APIMgtDBUtil.convertJSONStringToMap(operationParameters)); + urlMapping.setOperationPolicies(operationPolicy); api.addResource(urlMapping); } } + if (StringUtils.isNotEmpty(apiPolicyUUID) && StringUtils.isNotEmpty(policyName) + && StringUtils.isNotEmpty(policyVersion) && StringUtils.isNotEmpty(apiPolicyDirection)) { + OperationPolicy apiPolicy = new OperationPolicy(); + apiPolicy.setPolicyId(apiPolicyUUID); + apiPolicy.setPolicyName(policyName); + apiPolicy.setPolicyVersion(policyVersion); + apiPolicy.setDirection(apiPolicyDirection); + apiPolicy.setParameters(APIMgtDBUtil.convertJSONStringToMap(apiParams)); + api.setApiPolicy(apiPolicy); + } } } + } catch (APIManagementException e) { + log.error("Error while converting parameters to map for API : " + api.getApiUUID() + " Revision: " + + revisionId, e); + } } private boolean isAPIDefaultVersion(Connection connection, String provider, String name, String version) @@ -1354,7 +1440,7 @@ public API getApiByUUID(String apiId, String deployment, String organization, bo if (isExpand) { api.setPolicy(getAPILevelTier(connection, apiUuid, revision)); if (APIConstants.API_PRODUCT.equals(apiType)) { - attachURlMappingDetailsOfApiProduct(connection, api); + attachURlMappingDetailsOfApiProduct(connection, api, revision); } else { attachURLMappingDetails(connection, revision, api); } @@ -1443,7 +1529,7 @@ public List getAllApisByLabel(String gatewayLabel, Boolean expand) { if (expand) { api.setPolicy(getAPILevelTier(connection, apiUuid, revision)); if (APIConstants.API_PRODUCT.equals(apiType)) { - attachURlMappingDetailsOfApiProduct(connection, api); + attachURlMappingDetailsOfApiProduct(connection, api, revision); } else { attachURLMappingDetails(connection, revision, api); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SubscriptionValidationSQLConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SubscriptionValidationSQLConstants.java index 6a14a417fe78..b05d52e805e3 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SubscriptionValidationSQLConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SubscriptionValidationSQLConstants.java @@ -573,13 +573,18 @@ public class SubscriptionValidationSQLConstants { "AM_API_RESOURCE_SCOPE_MAPPING.SCOPE_NAME FROM AM_API_URL_MAPPING LEFT JOIN AM_API_RESOURCE_SCOPE_MAPPING" + " ON AM_API_URL_MAPPING.URL_MAPPING_ID=AM_API_RESOURCE_SCOPE_MAPPING.URL_MAPPING_ID WHERE " + "AM_API_URL_MAPPING.API_ID = ? AND AM_API_URL_MAPPING.REVISION_UUID = ?"; - public static final String GET_OPERATION_POLICIES_PER_URI_BY_API_SQL = "SELECT AUM.HTTP_METHOD, AUM.URL_PATTERN, " - + "OP.POLICY_NAME, OP.POLICY_VERSION, OPM.DIRECTION, OPM.POLICY_UUID " - + "FROM AM_API_URL_MAPPING AS AUM INNER JOIN AM_API_OPERATION_POLICY_MAPPING OPM ON AUM.URL_MAPPING_ID = OPM.URL_MAPPING_ID " - + "INNER JOIN AM_OPERATION_POLICY OP ON OPM.POLICY_UUID = OP.POLICY_UUID " - + "INNER JOIN AM_API_OPERATION_POLICY AOP ON OPM.POLICY_UUID = AOP.POLICY_UUID " - + "WHERE AUM.API_ID = ? AND AUM.REVISION_UUID = ?"; + public static final String GET_OPERATION_POLICIES_PER_URI_BY_API_SQL = + "SELECT OP.POLICY_NAME, OP.POLICY_VERSION,APM.DIRECTION AS API_POLICY_DIRECTION, APM.POLICY_UUID AS API_POLICY_UUID, " + + "OPM.POLICY_UUID AS OPERATION_POLICY_UUID, OPM.DIRECTION AS OPERATION_POLICY_DIRECTION, " + + "AUM.HTTP_METHOD, AUM.URL_PATTERN, OPM.PARAMETERS AS OPERATION_PARAMS, " + + "APM.PARAMETERS AS API_PARAMS " + + "FROM AM_API_OPERATION_POLICY AS AOP " + + "LEFT JOIN AM_API_OPERATION_POLICY_MAPPING OPM ON AOP.POLICY_UUID = OPM.POLICY_UUID " + + "LEFT JOIN AM_API_URL_MAPPING AUM ON AUM.URL_MAPPING_ID = OPM.URL_MAPPING_ID " + + "INNER JOIN AM_OPERATION_POLICY OP ON OP.POLICY_UUID = AOP.POLICY_UUID " + + "LEFT JOIN AM_API_POLICY_MAPPING as APM ON APM.POLICY_UUID = AOP.POLICY_UUID " + + "WHERE AOP.API_UUID = ? AND AOP.REVISION_UUID = ?"; public static final String GET_ALL_APIS_BY_ORGANIZATION_AND_DEPLOYMENT_SQL = "SELECT AM_API.API_PROVIDER,AM_API" + ".API_NAME,AM_API.CONTEXT, AM_API.CONTEXT_TEMPLATE, AM_API.API_UUID,AM_API.API_ID,AM_API.API_TIER,AM_API.API_VERSION,AM_API" + ".API_TYPE,AM_API.STATUS,AM_REVISION.REVISION_UUID AS REVISION_UUID,AM_DEPLOYMENT_REVISION_MAPPING.NAME " + diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/APIDTO.java b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/APIDTO.java index 28f5672acaee..02f196a41056 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/APIDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/APIDTO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import java.util.ArrayList; import java.util.List; +import org.wso2.carbon.apimgt.internal.service.dto.OperationPolicyDTO; import org.wso2.carbon.apimgt.internal.service.dto.URLMappingDTO; import javax.validation.constraints.*; @@ -30,6 +31,7 @@ public class APIDTO { private String status = null; private String organization = null; private Boolean isDefaultVersion = null; + private List apiPolicies = new ArrayList<>(); private List urlMappings = new ArrayList<>(); /** @@ -229,6 +231,23 @@ public void setIsDefaultVersion(Boolean isDefaultVersion) { this.isDefaultVersion = isDefaultVersion; } + /** + **/ + public APIDTO apiPolicies(List apiPolicies) { + this.apiPolicies = apiPolicies; + return this; + } + + + @ApiModelProperty(value = "") + @JsonProperty("apiPolicies") + public List getApiPolicies() { + return apiPolicies; + } + public void setApiPolicies(List apiPolicies) { + this.apiPolicies = apiPolicies; + } + /** **/ public APIDTO urlMappings(List urlMappings) { @@ -267,12 +286,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(status, API.status) && Objects.equals(organization, API.organization) && Objects.equals(isDefaultVersion, API.isDefaultVersion) && + Objects.equals(apiPolicies, API.apiPolicies) && Objects.equals(urlMappings, API.urlMappings); } @Override public int hashCode() { - return Objects.hash(uuid, apiId, provider, name, version, context, policy, apiType, status, organization, isDefaultVersion, urlMappings); + return Objects.hash(uuid, apiId, provider, name, version, context, policy, apiType, status, organization, isDefaultVersion, apiPolicies, urlMappings); } @Override @@ -291,6 +311,7 @@ public String toString() { sb.append(" status: ").append(toIndentedString(status)).append("\n"); sb.append(" organization: ").append(toIndentedString(organization)).append("\n"); sb.append(" isDefaultVersion: ").append(toIndentedString(isDefaultVersion)).append("\n"); + sb.append(" apiPolicies: ").append(toIndentedString(apiPolicies)).append("\n"); sb.append(" urlMappings: ").append(toIndentedString(urlMappings)).append("\n"); sb.append("}"); return sb.toString(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/OperationPolicyDTO.java b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/OperationPolicyDTO.java index 8fdf85451488..23c77094f0dd 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/OperationPolicyDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/gen/java/org/wso2/carbon/apimgt/internal/service/dto/OperationPolicyDTO.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import javax.validation.constraints.*; @@ -21,6 +24,7 @@ public class OperationPolicyDTO { private String direction = null; private String policyId = null; private Integer order = null; + private Map parameters = new HashMap<>(); /** **/ @@ -107,6 +111,23 @@ public void setOrder(Integer order) { this.order = order; } + /** + **/ + public OperationPolicyDTO parameters(Map parameters) { + this.parameters = parameters; + return this; + } + + + @ApiModelProperty(value = "") + @JsonProperty("parameters") + public Map getParameters() { + return parameters; + } + public void setParameters(Map parameters) { + this.parameters = parameters; + } + @Override public boolean equals(java.lang.Object o) { @@ -121,12 +142,13 @@ public boolean equals(java.lang.Object o) { Objects.equals(policyVersion, operationPolicy.policyVersion) && Objects.equals(direction, operationPolicy.direction) && Objects.equals(policyId, operationPolicy.policyId) && - Objects.equals(order, operationPolicy.order); + Objects.equals(order, operationPolicy.order) && + Objects.equals(parameters, operationPolicy.parameters); } @Override public int hashCode() { - return Objects.hash(policyName, policyVersion, direction, policyId, order); + return Objects.hash(policyName, policyVersion, direction, policyId, order, parameters); } @Override @@ -139,6 +161,7 @@ public String toString() { sb.append(" direction: ").append(toIndentedString(direction)).append("\n"); sb.append(" policyId: ").append(toIndentedString(policyId)).append("\n"); sb.append(" order: ").append(toIndentedString(order)).append("\n"); + sb.append(" parameters: ").append(toIndentedString(parameters)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/java/org/wso2/carbon/apimgt/internal/service/utils/SubscriptionValidationDataUtil.java b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/java/org/wso2/carbon/apimgt/internal/service/utils/SubscriptionValidationDataUtil.java index 333bb1fb47ae..66e8bc66e2b9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/java/org/wso2/carbon/apimgt/internal/service/utils/SubscriptionValidationDataUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/java/org/wso2/carbon/apimgt/internal/service/utils/SubscriptionValidationDataUtil.java @@ -103,18 +103,31 @@ private static APIDTO fromAPItoDTO(API model) { urlMappingDTO.setUrlPattern(urlMapping.getUrlPattern()); urlMappingDTO.setScopes(urlMapping.getScopes()); List operationPolicyDTOList = new ArrayList<>(); - for(OperationPolicy operationPolicy: urlMapping.getOperationPolicies()) { + for (OperationPolicy operationPolicy : urlMapping.getOperationPolicies()) { OperationPolicyDTO operationPolicyDTO = new OperationPolicyDTO(); operationPolicyDTO.setPolicyId(operationPolicy.getPolicyId()); operationPolicyDTO.setPolicyName(operationPolicy.getPolicyName()); operationPolicyDTO.setPolicyVersion(operationPolicy.getPolicyVersion()); operationPolicyDTO.setDirection(operationPolicy.getDirection()); + operationPolicyDTO.setParameters(operationPolicy.getParameters()); operationPolicyDTO.setOrder(operationPolicy.getOrder()); operationPolicyDTOList.add(operationPolicyDTO); } urlMappingDTO.setOperationPolicies(operationPolicyDTOList); urlMappingsDTO.add(urlMappingDTO); } + List apiPolicies = new ArrayList<>(); + for (OperationPolicy apiPolicy : model.getApiPolicies()) { + OperationPolicyDTO operationPolicyDTO = new OperationPolicyDTO(); + operationPolicyDTO.setPolicyId(apiPolicy.getPolicyId()); + operationPolicyDTO.setPolicyName(apiPolicy.getPolicyName()); + operationPolicyDTO.setPolicyVersion(apiPolicy.getPolicyVersion()); + operationPolicyDTO.setDirection(apiPolicy.getDirection()); + operationPolicyDTO.setOrder(apiPolicy.getOrder()); + operationPolicyDTO.setParameters(apiPolicy.getParameters()); + apiPolicies.add(operationPolicyDTO); + } + apidto.setApiPolicies(apiPolicies); apidto.setUrlMappings(urlMappingsDTO); } return apidto; @@ -146,18 +159,31 @@ public static APIListDTO fromAPIToAPIListDTO(API model) { urlMappingDTO.setUrlPattern(urlMapping.getUrlPattern()); urlMappingDTO.setScopes(urlMapping.getScopes()); List operationPolicyDTOList = new ArrayList<>(); - for(OperationPolicy operationPolicy: urlMapping.getOperationPolicies()) { + for (OperationPolicy operationPolicy : urlMapping.getOperationPolicies()) { OperationPolicyDTO operationPolicyDTO = new OperationPolicyDTO(); operationPolicyDTO.setPolicyId(operationPolicy.getPolicyId()); operationPolicyDTO.setPolicyName(operationPolicy.getPolicyName()); operationPolicyDTO.setPolicyVersion(operationPolicy.getPolicyVersion()); operationPolicyDTO.setDirection(operationPolicy.getDirection()); operationPolicyDTO.setOrder(operationPolicy.getOrder()); + operationPolicyDTO.setParameters(operationPolicy.getParameters()); operationPolicyDTOList.add(operationPolicyDTO); } urlMappingDTO.setOperationPolicies(operationPolicyDTOList); urlMappingsDTO.add(urlMappingDTO); } + List apiPolicies = new ArrayList<>(); + for (OperationPolicy apiPolicy : model.getApiPolicies()) { + OperationPolicyDTO operationPolicyDTO = new OperationPolicyDTO(); + operationPolicyDTO.setPolicyId(apiPolicy.getPolicyId()); + operationPolicyDTO.setPolicyName(apiPolicy.getPolicyName()); + operationPolicyDTO.setPolicyVersion(apiPolicy.getPolicyVersion()); + operationPolicyDTO.setDirection(apiPolicy.getDirection()); + operationPolicyDTO.setParameters(apiPolicy.getParameters()); + operationPolicyDTO.setOrder(apiPolicy.getOrder()); + apiPolicies.add(operationPolicyDTO); + } + apidto.setApiPolicies(apiPolicies); apidto.setUrlMappings(urlMappingsDTO); apiListdto.setCount(1); apiListdto.getList().add(apidto); diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/resources/api.yaml b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/resources/api.yaml index c993565bacd3..374700a78e49 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/resources/api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/src/main/resources/api.yaml @@ -863,6 +863,10 @@ definitions: type: boolean description: Whether this is the default version of the API. example: false + apiPolicies: + type: array + items: + $ref: '#/definitions/OperationPolicy' urlMappings: type: array items: @@ -1389,6 +1393,10 @@ definitions: type: string order: type: integer + parameters: + type: object + additionalProperties: + type: object #----------------------------------------------------- # The pagination resource #----------------------------------------------------- diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json index 9a89d4cfe705..7b508d0f1996 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json @@ -1108,6 +1108,12 @@ "example" : false, "description" : "Whether this is the default version of the API." }, + "apiPolicies" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/OperationPolicy" + } + }, "urlMappings" : { "type" : "array", "items" : { @@ -1703,9 +1709,42 @@ "items" : { "type" : "string" } + }, + "operationPolicies" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/OperationPolicy" + } } } }, + "OperationPolicy" : { + "properties" : { + "policyName" : { + "type" : "string" + }, + "policyVersion" : { + "type" : "string" + }, + "direction" : { + "type" : "string" + }, + "policyId" : { + "type" : "string" + }, + "order" : { + "type" : "integer" + }, + "parameters" : { + "type" : "object", + "additionalProperties" : { + "type" : "object", + "properties" : { } + } + } + }, + "title" : "Operation Policy" + }, "Pagination" : { "properties" : { "offset" : { diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java index 11f0678a7339..0d091fece3bf 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/model/entity/API.java @@ -18,6 +18,7 @@ package org.wso2.carbon.apimgt.keymgt.model.entity; +import org.wso2.carbon.apimgt.api.model.OperationPolicy; import org.wso2.carbon.apimgt.api.model.subscription.CacheableEntity; import org.wso2.carbon.apimgt.api.model.subscription.URLMapping; @@ -41,6 +42,7 @@ public class API implements CacheableEntity { private String organization; private boolean deployed = false; private boolean isDefaultVersion = false; + private List apiPolicies = new ArrayList<>(); public API() { } @@ -205,6 +207,7 @@ public String toString() { ", status='" + status + '\'' + ", isDefaultVersion=" + isDefaultVersion + ", urlMappings=" + urlMappings + + ", apiPolicies=" + apiPolicies + '}'; } @@ -295,4 +298,12 @@ public boolean isDeployed() { public void setDeployed(boolean deployed) { this.deployed = deployed; } + + public void setApiPolicies(List apiPolicies) { + this.apiPolicies = apiPolicies; + } + + public List getApiPolicies() { + return apiPolicies; + } } diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index 850daa43de5f..213ede226f12 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -325,6 +325,8 @@ {{apim.analytics.enable}} + {{apim.analytics.enablePolicy}} + {{apim.analytics.type}} {{apim.analytics.auth_token}}