From dcf2e6d74205075daefac204c4cb496fc64dae6b Mon Sep 17 00:00:00 2001 From: BLasan Date: Fri, 6 Sep 2024 10:53:00 +0530 Subject: [PATCH] Fix: Revision create, delete, revision deploy, revision undeploy, revision restore scenarios --- .../wso2/carbon/apimgt/api/APIProvider.java | 1 + .../apimgt/api/model/CustomBackendData.java | 60 ++++++++ .../apimgt/gateway/InMemoryAPIDeployer.java | 2 +- .../wso2/carbon/apimgt/impl/APIConstants.java | 2 +- .../carbon/apimgt/impl/APIProviderImpl.java | 8 +- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 130 +++++++++++++++--- .../impl/dao/constants/SQLConstants.java | 14 +- .../apimgt/impl/utils/GatewayUtils.java | 8 ++ .../src/test/resources/dbscripts/h2.sql | 11 ++ .../persistence/RegistryPersistenceImpl.java | 2 +- .../src/main/resources/publisher-api.yaml | 28 ---- .../v1/common/TemplateBuilderUtil.java | 20 ++- .../v1/common/mappings/ExportUtils.java | 17 +-- .../src/main/resources/publisher-api.yaml | 3 - .../src/main/resources/sql/h2.sql | 11 ++ 15 files changed, 244 insertions(+), 73 deletions(-) create mode 100644 components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/CustomBackendData.java diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java index 5923fbe4a3f4..ef38f84169a7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java @@ -66,6 +66,7 @@ public interface APIProvider extends APIManager { Comment getComment(ApiTypeWrapper apiTypeWrapper, String commentId, Integer replyLimit, Integer replyOffset) throws APIManagementException; void deleteCustomBackendByID(String backendUUID, String apiUUID, String type) throws APIManagementException; + InputStream getCustomBackendSequenceByAPIAndRevisionUUUID(String apiUUID, String revisionUUID, String type) throws APIManagementException; /** * @param apiTypeWrapper Api type wrapper diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/CustomBackendData.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/CustomBackendData.java new file mode 100644 index 000000000000..c9372a2045bf --- /dev/null +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/model/CustomBackendData.java @@ -0,0 +1,60 @@ +package org.wso2.carbon.apimgt.api.model; + +import java.io.InputStream; + +public class CustomBackendData { + private String Id; + private InputStream sequence; + private String type; + private String name; + private String apiUUID; + private String revisionUUID; + + public InputStream getSequence() { + return sequence; + } + + public void setSequence(InputStream sequence) { + this.sequence = sequence; + } + + public String getId() { + return Id; + } + + public void setId(String id) { + Id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getApiUUID() { + return apiUUID; + } + + public void setApiUUID(String apiUUID) { + this.apiUUID = apiUUID; + } + + public String getRevisionUUID() { + return revisionUUID; + } + + public void setRevisionUUID(String revisionUUID) { + this.revisionUUID = revisionUUID; + } +} diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index c37d7ef97d57..7cb4200c1feb 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -349,7 +349,7 @@ private void unDeployAPI(APIGatewayAdmin apiGatewayAdmin, DeployAPIInGatewayEven } GatewayUtils.setCustomSequencesToBeRemoved(api, gatewayAPIDTO); - // GatewayUtils.setCustomBackendToBeRemoved(api, gatewayAPIDTO); + GatewayUtils.setCustomBackendToBeRemoved(gatewayAPIDTO); } gatewayAPIDTO.setLocalEntriesToBeRemove( 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 c23f10fb2dff..6b1dc1497aaf 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 @@ -1765,7 +1765,7 @@ private ConfigParameters() { public static final String ENDPOINT_TYPE_SERVICE = "service"; public static final String ENDPOINT_TYPE_ADDRESS = "address"; public static final String ENDPOINT_TYPE_AWSLAMBDA = "awslambda"; - public static final String ENDPOINT_TYPE_SEQUENCE = "custom_sequence"; + public static final String ENDPOINT_TYPE_SEQUENCE = "custom_backend"; public static final String SEQUENCE_DATA = "sequence"; public static final String ENDPOINT_PRODUCTION_FAILOVERS = "production_failovers"; public static final String ENDPOINT_SANDBOX_FAILOVERS = "sandbox_failovers"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java index dd94b5c68931..17f9389bf507 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java @@ -34,7 +34,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.solr.client.solrj.util.ClientUtils; -import org.apache.solr.common.util.Hash; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; @@ -1066,6 +1065,11 @@ public Map getCustomBackendOfAPIByUUID(String customBackendUUID, return apiMgtDAO.getCustomBackendSequenceOfAPIByUUID(backendUUID, apiUUID, type); } + @Override + public InputStream getCustomBackendSequenceByAPIAndRevisionUUUID(String apiUUID, String revisionUUID, String type) throws APIManagementException { + return apiMgtDAO.getCustomBackendSequenceByAPIandRevisionUUID(apiUUID, revisionUUID, type); + } + @Override public void addNewCustomBackendForRevision(String revisionUUID, String updatedBackendUUID, String apiUUID, Map config) throws APIManagementException { if (config.get("production") != null) { @@ -5940,6 +5944,7 @@ public String addAPIRevision(APIRevision apiRevision, String organization) throw ExceptionCodes.from(ExceptionCodes.API_REVISION_UUID_NOT_FOUND)); } apiRevision.setRevisionUUID(revisionUUID); + try { apiMgtDAO.addAPIRevision(apiRevision); } catch (APIManagementException e) { @@ -6521,7 +6526,6 @@ public void deleteAPIRevision(String apiId, String apiRevisionId, String organiz ERROR_DELETING_API_REVISION,apiRevision.getApiUUID())); } apiMgtDAO.deleteAPIRevision(apiRevision); - apiMgtDAO.deleteCustomBackendByRevision(apiId, apiRevisionId); gatewayArtifactsMgtDAO.deleteGatewayArtifact(apiRevision.getApiUUID(), apiRevision.getRevisionUUID()); if (artifactSaver != null) { try { 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 b2a812db7562..92a3b9d2edd7 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 @@ -59,6 +59,7 @@ import org.wso2.carbon.apimgt.api.model.BlockConditionsDTO; import org.wso2.carbon.apimgt.api.model.Comment; import org.wso2.carbon.apimgt.api.model.CommentList; +import org.wso2.carbon.apimgt.api.model.CustomBackendData; import org.wso2.carbon.apimgt.api.model.DeployedAPIRevision; import org.wso2.carbon.apimgt.api.model.Environment; import org.wso2.carbon.apimgt.api.model.GatewayPolicyData; @@ -11193,14 +11194,37 @@ public Map retrieveCustomBackendOfAPIRevision(String apiUUID, St return map; } + public InputStream getCustomBackendSequenceByAPIandRevisionUUID(String apiUUID, String revisionUUID, String type) throws APIManagementException { + String sqlQuery = SQLConstants.CustomBackendConstants.GET_CUSTOM_BACKEND_FROM_API_AND_REVISION_UUID; + boolean isRev = checkAPIUUIDIsARevisionUUID(apiUUID) != null; + InputStream sequence = null; + try (Connection con = APIMgtDBUtil.getConnection(); + PreparedStatement pstmt = con.prepareStatement(sqlQuery)) { + pstmt.setString(1, apiUUID); + pstmt.setString(2, revisionUUID); + pstmt.setString(3, type); + try (ResultSet rs = pstmt.executeQuery()) { + while(rs.next()) { + sequence = rs.getBinaryStream("SEQUENCE"); + } + } + } catch (SQLException ex) { + handleException("Error when retrieving Custom Backend of API: "+apiUUID, ex); + } + return sequence; + } + public InputStream getCustomBackendSequenceOfAPIByUUID(String backendUUID, String apiUUID, String type) throws APIManagementException { String sqlQuery = SQLConstants.CustomBackendConstants.GET_API_SPECIFIC_CUSTOM_BACKEND_FROM_SEQUENCE_ID; + boolean isRev = checkAPIUUIDIsARevisionUUID(apiUUID) != null; ResultSet rs = null; InputStream sequence = null; try (Connection con = APIMgtDBUtil.getConnection(); PreparedStatement ps = con.prepareStatement(sqlQuery)) { ps.setString(1, backendUUID); ps.setString(2, apiUUID); + ps.setString(3, type); + rs = ps.executeQuery(); while(rs.next()) { try (InputStream in = rs.getBinaryStream("SEQUENCE")) { @@ -17189,8 +17213,6 @@ public void addAPIRevision(APIRevision apiRevision) throws APIManagementExceptio insertScopeResourceMappingStatement.executeBatch(); insertProductResourceMappingStatement.executeBatch(); revisionAPIPolicies(apiRevision, tenantDomain, uriTemplateMap, connection); - // Add Custom Backend - revisionCustomBackend(apiRevision, connection); // Adding to AM_API_CLIENT_CERTIFICATE String getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE; @@ -17262,6 +17284,8 @@ public void addAPIRevision(APIRevision apiRevision) throws APIManagementExceptio insertGraphQLComplexityStatement.executeBatch(); updateLatestRevisionNumber(connection, apiRevision.getApiUUID(), apiRevision.getId()); addAPIRevisionMetaData(connection, apiRevision.getApiUUID(), apiRevision.getRevisionUUID()); + // Add Custom Backend + revisionCustomBackend(apiRevision, connection); connection.commit(); } catch (SQLException e) { connection.rollback(); @@ -18113,6 +18137,7 @@ public void restoreAPIRevision(APIRevision apiRevision) throws APIManagementExce } restoreAPIPolicies(apiRevision, tenantDomain, uriTemplateMap, connection); + restoreCustomBackend(apiRevision, connection); insertScopeResourceMappingStatement.executeBatch(); insertProductResourceMappingStatement.executeBatch(); @@ -18250,6 +18275,9 @@ public void deleteAPIRevision(APIRevision apiRevision) throws APIManagementExcep // Removing related revision entries from operation policies deleteAllAPISpecificOperationPoliciesByAPIUUID(connection, apiRevision.getApiUUID(), apiRevision.getRevisionUUID()); + // Removing related Custom Backend entries + deleteAllCustomBackendsOfAPIRevision(apiRevision.getApiUUID(), apiRevision.getRevisionUUID(), connection); + connection.commit(); } catch (SQLException e) { connection.rollback(); @@ -18262,6 +18290,18 @@ public void deleteAPIRevision(APIRevision apiRevision) throws APIManagementExcep } } + private void deleteAllCustomBackendsOfAPIRevision(String apiUUID, String revisionUUID, Connection connection) throws APIManagementException { + String deleteSqlQuery = SQLConstants.CustomBackendConstants.DELETE_CUSTOM_BACKEND_BY_REVISION; + try (PreparedStatement pstmt = connection.prepareStatement(deleteSqlQuery)) { + connection.setAutoCommit(false); + pstmt.setString(1, apiUUID); + pstmt.setString(2, revisionUUID); + pstmt.executeUpdate(); + } catch (SQLException ex) { + handleException("Error when deleting Custom Backend of API: " + apiUUID, ex); + } + } + /** * Adds an API Product revision record to the database * @@ -21153,23 +21193,48 @@ private void revisionCustomBackend(APIRevision apiRevision, Connection connectio throws SQLException, APIManagementException { String addCBSqlQuery = SQLConstants.CustomBackendConstants.ADD_CUSTOM_BACKEND; String getCBSQLQuery = SQLConstants.CustomBackendConstants.GET_ALL_API_SPECIFIC_CUSTOM_BACKENDS; - ResultSet rs = null; - try (Connection con = APIMgtDBUtil.getConnection(); - PreparedStatement getPstmt = con.prepareStatement(getCBSQLQuery); - PreparedStatement addPstmt = con.prepareStatement(addCBSqlQuery)) { - con.setAutoCommit(false); + try (PreparedStatement getPstmt = connection.prepareStatement(getCBSQLQuery); + PreparedStatement addPstmt = connection.prepareStatement(addCBSqlQuery)) { + connection.setAutoCommit(false); getPstmt.setString(1, apiRevision.getApiUUID()); - rs = getPstmt.executeQuery(); - while (rs.next()) { - addPstmt.setString(1, rs.getString("ID")); - addPstmt.setString(2, apiRevision.getApiUUID()); - addPstmt.setBinaryStream(3, rs.getBinaryStream("SEQUENCE")); - addPstmt.setString(4, rs.getString("TYPE")); - addPstmt.setString(5, apiRevision.getRevisionUUID()); - addPstmt.setString(6, rs.getString("NAME")); - addPstmt.addBatch(); - } - addPstmt.executeBatch(); + List customBackendDataList = new ArrayList<>(); + int count = 0; + + try (ResultSet rs = getPstmt.executeQuery()) { + while (rs.next()) { + addPstmt.setString(1, rs.getString("ID")); + addPstmt.setString(2, apiRevision.getApiUUID()); + addPstmt.setBinaryStream(3, rs.getBinaryStream("SEQUENCE")); + addPstmt.setString(4, rs.getString("TYPE")); + addPstmt.setString(5, apiRevision.getRevisionUUID()); + addPstmt.setString(6, rs.getString("NAME")); + addPstmt.addBatch(); + count++; + + // CustomBackendData customBackendData = new CustomBackendData(); + // customBackendData.setId(rs.getString("ID")); + // customBackendData.setName(rs.getString("NAME")); + // customBackendData.setApiUUID(apiRevision.getApiUUID()); + // customBackendData.setRevisionUUID(apiRevision.getRevisionUUID()); + // customBackendData.setSequence(rs.getBinaryStream("SEQUENCE")); + // customBackendData.setType(rs.getString("TYPE")); + // customBackendDataList.add(customBackendData); + } + } + + // for(CustomBackendData customBackendData: customBackendDataList) { + // addPstmt.setString(1, customBackendData.getId()); + // addPstmt.setString(2, customBackendData.getApiUUID()); + // addPstmt.setBinaryStream(3, customBackendData.getSequence()); + // addPstmt.setString(4, customBackendData.getType()); + // addPstmt.setString(5, customBackendData.getRevisionUUID()); + // addPstmt.setString(6, customBackendData.getName()); + // addPstmt.addBatch(); + // } + + if (count > 0) { + addPstmt.executeBatch(); + } } catch (SQLException ex) { handleException("Error while adding Custom Backends to the database of API: " + apiRevision.getApiUUID(), ex); @@ -21283,6 +21348,35 @@ private void handlePolicyCloningWhenRevisioning(OperationPolicy policy, String a } } + private void restoreCustomBackend(APIRevision apiRevision, Connection connection) throws SQLException { + String deleteSql = SQLConstants.CustomBackendConstants.DELETE_WORKING_COPY_OF_CUSTOM_BACKEND; + String getSql = SQLConstants.CustomBackendConstants.GET_CUSTOM_BACKEND_OF_API_REVISION; + String addSql = SQLConstants.CustomBackendConstants.ADD_CUSTOM_BACKEND; + try (PreparedStatement pstmt = connection.prepareStatement(deleteSql); + PreparedStatement pstmtGet = connection.prepareStatement(getSql); + PreparedStatement pstmtAdd = connection.prepareStatement(addSql)) { + connection.setAutoCommit(false); + pstmt.setString(1, apiRevision.getApiUUID()); + pstmt.executeUpdate(); + + pstmtGet.setString(1, apiRevision.getApiUUID()); + pstmtGet.setString(2, apiRevision.getRevisionUUID()); + + try(ResultSet rs = pstmtGet.executeQuery()) { + while(rs.next()) { + pstmtAdd.setString(1, rs.getString("ID")); + pstmtAdd.setString(2, apiRevision.getApiUUID()); + pstmtAdd.setBinaryStream(3, rs.getBinaryStream("SEQUENCE")); + pstmtAdd.setString(4, rs.getString("TYPE")); + pstmtAdd.setString(5, "0"); + pstmtAdd.setString(6, rs.getString("NAME")); + pstmtAdd.addBatch(); + } + } + pstmtAdd.executeBatch(); + } + } + /** * Restore a revision of API policies. This will copy the policy and policy mapping to working copy. * 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 3d567b8f2074..339dbdb72f13 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 @@ -4404,14 +4404,16 @@ public static class SystemConfigsConstants { public static class CustomBackendConstants { public static final String ADD_CUSTOM_BACKEND = "INSERT INTO AM_API_CUSTOM_BACKEND (ID,API_UUID,SEQUENCE,TYPE,REVISION_UUID,NAME) " + "VALUES (?,?,?,?,?,?)"; - public static final String DELETE_CUSTOM_BACKEND = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND ID = ? AND TYPE = ? AND REVISION_UUID = 0"; - public static final String DELETE_CUSTOM_BACKEND_BY_REVISION = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE REVISION_UUID = ?"; + public static final String DELETE_WORKING_COPY_OF_CUSTOM_BACKEND = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID = '0'"; + public static final String DELETE_CUSTOM_BACKEND = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND ID = ? AND TYPE = ? AND REVISION_UUID = '0'"; + public static final String DELETE_CUSTOM_BACKEND_BY_REVISION = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID = ?"; public static final String DELETE_CUSTOM_BACKEND_BY_API = "DELETE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ?"; - public static final String GET_CUSTOM_BACKEND_OF_API_REVISION = "SELECT NAME, SEQUENCE, TYPE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID = ?"; - public static final String GET_CUSTOM_BACKEND_OF_API_DEFAULT_REVISION = "SELECT ACB.NAME, ACB.TYPE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID IS NULL"; + public static final String GET_CUSTOM_BACKEND_OF_API_REVISION = "SELECT ID, NAME, SEQUENCE, TYPE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID = ?"; + public static final String GET_CUSTOM_BACKEND_OF_API_DEFAULT_REVISION = "SELECT ACB.NAME, ACB.TYPE FROM AM_API_CUSTOM_BACKEND WHERE API_UUID = ? AND REVISION_UUID = '0'"; public static final String GET_REVISION_SPECIFIC_CUSTOM_BACKEND_FROM_SEQUENCE_ID = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND ACB.REVISION_UUID = ? AND ACB.TYPE = ?"; - public static final String GET_API_SPECIFIC_CUSTOM_BACKEND_FROM_SEQUENCE_ID = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND ACB.API_UUID = ? AND ACB.REVISION_UUID = 0 AND ACB.TYPE = ?"; - public static final String GET_ALL_API_SPECIFIC_CUSTOM_BACKENDS = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.API_UUID = ? AND ACB.REVISION_UUID = 0"; + public static final String GET_API_SPECIFIC_CUSTOM_BACKEND_FROM_SEQUENCE_ID = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND ACB.API_UUID = ? AND ACB.REVISION_UUID = '0' AND ACB.TYPE = ?"; + public static final String GET_CUSTOM_BACKEND_FROM_API_AND_REVISION_UUID = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.API_UUID = ? AND ACB.REVISION_UUID = ? AND ACB.TYPE = ?"; + public static final String GET_ALL_API_SPECIFIC_CUSTOM_BACKENDS = "SELECT ACB.ID, ACB.NAME, ACB.SEQUENCE, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.API_UUID = ? AND ACB.REVISION_UUID = '0'"; public static final String GET_REVISION_SPECIFIC_CUSTOM_BACKEND_META_DATA_FROM_SEQUENCE_ID = "SELECT ACB.ID, ACB.NAME, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND ACB.REVISION_UUID = ?"; public static final String GET_API_SPECIFIC_CUSTOM_BACKEND_META_DATA_FROM_SEQUENCE_ID = "SELECT ACB.ID, ACB.NAME, ACB.TYPE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND API_UUID = ?"; public static final String GET_API_SPECIFIC_CUSTOM_BACKEND_SEQUENCE_FROM_SEQUENCE_ID = "SELECT ACB.SEQUENCE FROM AM_API_CUSTOM_BACKEND ACB WHERE ACB.ID = ? AND API_UUID = ?"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/GatewayUtils.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/GatewayUtils.java index 633844789fc2..599b2f14e94f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/GatewayUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/GatewayUtils.java @@ -46,6 +46,14 @@ public static void setCustomSequencesToBeRemoved(API api, GatewayAPIDTO gatewayA gatewayAPIDTO.setSequencesToBeRemove(addStringToList(faultSequence, gatewayAPIDTO.getSequencesToBeRemove())); } + public static void setCustomBackendToBeRemoved(GatewayAPIDTO gatewayAPIDTO) { + String sandBoxBackend = APIUtil.getCustomBackendName(gatewayAPIDTO.getApiId(), "SANDBOX"); + gatewayAPIDTO.setSequencesToBeRemove(addStringToList(sandBoxBackend, gatewayAPIDTO.getSequencesToBeRemove())); + String productionBackend = APIUtil.getCustomBackendName(gatewayAPIDTO.getApiId(), "PRODUCTION"); + gatewayAPIDTO.setSequencesToBeRemove( + addStringToList(productionBackend, gatewayAPIDTO.getSequencesToBeRemove())); + } + public static String[] addStringToList(String key, String[] keys) { if (keys == null) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql index 834115bd1cb4..654ad3d51f17 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql @@ -1310,6 +1310,17 @@ CREATE TABLE IF NOT EXISTS AM_API ( UNIQUE (API_PROVIDER,API_NAME,API_VERSION) ); +CREATE TABLE IF NOT EXISTS AM_API_CUSTOM_BACKEND ( + ID VARCHAR(60) NOT NULL, + API_UUID VARCHAR(256) NOT NULL, + REVISION_UUID VARCHAR(256) DEFAULT '0', + SEQUENCE LONGBLOB, + NAME VARCHAR(256) NOT NULL, + TYPE VARCHAR(120) NOT NULL, + PRIMARY KEY(ID, API_UUID, REVISION_UUID, TYPE), + FOREIGN KEY(API_UUID) REFERENCES AM_API(API_UUID) ON DELETE CASCADE +); + CREATE TABLE IF NOT EXISTS AM_API_URL_MAPPING ( URL_MAPPING_ID INTEGER AUTO_INCREMENT, API_ID INTEGER NOT NULL, 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 f3a83f589b87..dd4b1d9409a5 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 @@ -392,7 +392,7 @@ public void restoreAPIRevision(Organization org, String apiUUID, String revision registry.put(apiPath, newAPIArtifact); GenericArtifact artifact = getAPIArtifact(apiUUID, registry); artifact.setAttribute(APIConstants.API_OVERVIEW_STATUS, lifecycleStatus); - artifactManager.updateGenericArtifact(apiArtifact); + artifactManager.updateGenericArtifact(artifact); RegistryPersistenceUtil.clearResourcePermissions(apiPath, api.getId(), ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index 045a2df045f4..d22fd1138b3a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -577,34 +577,6 @@ paths: source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/7a2298c4-c905-403f-8fac-38c73301631f/custom-backend/7a2298c4-c915-483f-8fac-38c73301631f"' - /apis/{apiId}/custom-backend/{customBackendId}/content: - get: - tags: - - API Custom Backend Sequence - summary: Download an API Specific Custom Backend - description: | - This operation can be used to download a particular API specific Custom Backend. - operationId: getAPISpecificOperationPolicyContentByPolicyId - parameters: - - $ref: '#/components/parameters/apiId' - - $ref: '#/components/parameters/customBackendId' - responses: - 200: - description: | - OK. - Custom Backend returned. - headers: - Content-Type: - description: | - The content type of the body. - schema: - type: string - content: - application/zip: - schema: - type: string - format: binary - /apis/{apiId}/custom-backend: put: tags: 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/TemplateBuilderUtil.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/TemplateBuilderUtil.java index 8dc6f7578938..bc2babe56983 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.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/TemplateBuilderUtil.java @@ -924,11 +924,21 @@ private static void setCustomSequencesToBeAdded(API api, GatewayAPIDTO gatewayAP if (APIConstants.ENDPOINT_TYPE_SEQUENCE.equals( endpointConfigMap.get(APIConstants.API_ENDPOINT_CONFIG_PROTOCOL_TYPE))) { - GatewayContentDTO gatewayCustomBackendSequenceDTO = retrieveCustomBackendSequence(api, - endpointConfigMap.get("type").toString(), extractedPath); - if (gatewayCustomBackendSequenceDTO != null) { - gatewayAPIDTO.setSequenceToBeAdd( - addGatewayContentToList(gatewayCustomBackendSequenceDTO, gatewayAPIDTO.getSequenceToBeAdd())); + if (endpointConfigMap.get("sandbox") != null) { + GatewayContentDTO gatewayCustomBackendSequenceDTO = retrieveCustomBackendSequence(api, "SANDBOX", + extractedPath); + if (gatewayCustomBackendSequenceDTO != null) { + gatewayAPIDTO.setSequenceToBeAdd(addGatewayContentToList(gatewayCustomBackendSequenceDTO, + gatewayAPIDTO.getSequenceToBeAdd())); + } + } + if (endpointConfigMap.get("production") != null) { + GatewayContentDTO gatewayCustomBackendSequenceDTO = retrieveCustomBackendSequence(api, "PRODUCTION", + extractedPath); + if (gatewayCustomBackendSequenceDTO != null) { + gatewayAPIDTO.setSequenceToBeAdd(addGatewayContentToList(gatewayCustomBackendSequenceDTO, + gatewayAPIDTO.getSequenceToBeAdd())); + } } } } 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/ExportUtils.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/ExportUtils.java index 8f416e17aba4..f4daca72b4d3 100644 --- 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/ExportUtils.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/ExportUtils.java @@ -223,7 +223,7 @@ public static File exportApi(APIProvider apiProvider, APIIdentifier apiIdentifie // TODO: Add Custom Backend to the Archive JsonObject endpointConfig = JsonParser.parseString(api.getEndpointConfig()).getAsJsonObject(); if(APIConstants.ENDPOINT_TYPE_SEQUENCE.equals(endpointConfig.get(API_ENDPOINT_CONFIG_PROTOCOL_TYPE).getAsString())) { - addCustomBackendToArchive(archivePath, apiProvider, api, currentApiUuid, endpointConfig); + addCustomBackendToArchive(archivePath, apiProvider, currentApiUuid, endpointConfig); } addGatewayEnvironmentsToArchive(archivePath, apiDtoToReturn.getId(), exportFormat, apiProvider); @@ -638,27 +638,28 @@ public static void addEndpointCertificatesToArchive(String archivePath, APIDTO a } } - public static void addCustomBackendToArchive(String archivePath, - APIProvider apiProvider, API api, String currentApiUuid, JsonObject endpointConfig) throws APIManagementException { + public static void addCustomBackendToArchive(String archivePath, APIProvider apiProvider, String apiUUID, + JsonObject endpointConfig) throws APIManagementException { try { JsonElement prodElement = endpointConfig.get("production"); CommonUtil.createDirectory(archivePath + File.separator + ImportExportConstants.CUSTOM_BACKEND_DIRECTORY); - if(prodElement != null) { + if (prodElement != null) { String backendUUID = prodElement.getAsJsonObject().get("sequence_id").getAsString(); String sequenceName = prodElement.getAsJsonObject().get("sequence_name").getAsString(); - InputStream sequence = apiProvider.getCustomBackendSequenceOfAPIByUUID(backendUUID, api.getUuid(), "PRODUCTION"); + InputStream sequence = apiProvider.getCustomBackendSequenceOfAPIByUUID(apiUUID, backendUUID, + "PRODUCTION"); exportCustomBackend(sequenceName, IOUtils.toString(sequence), archivePath); } JsonElement sandElement = endpointConfig.get("sandbox"); - if(sandElement != null) { + if (sandElement != null) { String backendUUID = sandElement.getAsJsonObject().get("sequence_id").getAsString(); String sequenceName = sandElement.getAsJsonObject().get("sequence_name").getAsString(); - InputStream sequence = apiProvider.getCustomBackendSequenceOfAPIByUUID(backendUUID, api.getUuid(), "SANDBOX"); + InputStream sequence = apiProvider.getCustomBackendSequenceOfAPIByUUID(apiUUID, backendUUID, "SANDBOX"); exportCustomBackend(sequenceName, IOUtils.toString(sequence), archivePath); } } catch (IOException | APIImportExportException ex) { - throw new APIManagementException("Error adding Custom Backends to the API Directory: " + api.getUuid(), ex); + throw new APIManagementException("Error adding Custom Backends to the API Directory: " + apiUUID, ex); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/resources/publisher-api.yaml index 0cfe04d465fc..f34d23ddbc67 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/resources/publisher-api.yaml @@ -8388,9 +8388,6 @@ components: isDefaultVersion: type: boolean example: false - sequence: - type: string - example: in sequence isRevision: type: boolean example: false diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql index 16a72011705b..8659d12acb7f 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql @@ -1582,6 +1582,17 @@ CREATE TABLE IF NOT EXISTS AM_API ( UNIQUE (API_PROVIDER,API_NAME,API_VERSION,ORGANIZATION) ); +CREATE TABLE IF NOT EXISTS AM_API_CUSTOM_BACKEND ( + ID VARCHAR(60) NOT NULL, + API_UUID VARCHAR(256) NOT NULL, + REVISION_UUID VARCHAR(256) DEFAULT '0', + SEQUENCE LONGBLOB, + NAME VARCHAR(256) NOT NULL, + TYPE VARCHAR(120) NOT NULL, + PRIMARY KEY(ID, API_UUID, REVISION_UUID, TYPE), + FOREIGN KEY(API_UUID) REFERENCES AM_API(API_UUID) ON DELETE CASCADE +); + CREATE TABLE IF NOT EXISTS AM_GRAPHQL_COMPLEXITY ( UUID VARCHAR(256), API_ID INTEGER NOT NULL,