Skip to content

Commit

Permalink
Merge pull request wso2#12169 from GihanAyesh/master
Browse files Browse the repository at this point in the history
Revision deployment approval workflow
  • Loading branch information
GihanAyesh authored Dec 14, 2023
2 parents 0babf46 + 7c7a2e4 commit c578caa
Show file tree
Hide file tree
Showing 39 changed files with 1,132 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1694,4 +1694,26 @@ boolean isValidContext(String providerName, String apiName, String contextTempla
*/
boolean validateAppliedPolicyWithSpecification(OperationPolicySpecification policySpecification, OperationPolicy
appliedPolicy, String apiType) throws APIManagementException;

/**
* Resume API revision deployment process
*
* @param apiId API Id using for the revision deployment
* @param organization organization identifier
* @param revisionUUID revision UUID
* @param revisionId revision number
* @param environment environment the deployment is happening
*/
void resumeDeployedAPIRevision(String apiId, String organization, String revisionUUID, String revisionId,
String environment);

/***
* Cleanup pending or rejected revision workflows
*
* @param apiId Id of the API
* @param externalRef external Id of the revision
* @throws APIManagementException if an exception occurs while cleaning up revision deployment
*/
void cleanupAPIRevisionDeploymentWorkflows(String apiId, String externalRef) throws APIManagementException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.wso2.carbon.apimgt.api.model;

import org.wso2.carbon.apimgt.api.WorkflowStatus;

import java.io.Serializable;

public class APIRevisionDeployment implements Serializable {
Expand All @@ -26,6 +28,7 @@ public class APIRevisionDeployment implements Serializable {
private String revisionUUID;
private String deployment;
private String vhost;
private WorkflowStatus status;
private boolean isDisplayOnDevportal;
private String deployedTime;
private String successDeployedTime;
Expand Down Expand Up @@ -85,4 +88,12 @@ public String getSuccessDeployedTime() {
public void setSuccessDeployedTime(String successDeployedTime) {
this.successDeployedTime = successDeployedTime;
}

public WorkflowStatus getStatus() {
return status;
}

public void setStatus(WorkflowStatus status) {
this.status = status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,14 @@ public static class ApplicationStatus {
public static final String DELETE_PENDING = "DELETE_PENDING";
}

public static class APIRevisionStatus {

public static final String API_REVISION_CREATED = "CREATED";
public static final String API_REVISION_APPROVED = "APPROVED";
public static final String API_REVISION_REJECTED = "REJECTED";
public static final String API_REVISION_DELETE_PENDING = "DELETE_PENDING";
}

public static class AppRegistrationStatus {

public static final String REGISTRATION_CREATED = "CREATED";
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5658,6 +5658,55 @@ public WorkflowDTO retrieveWorkflowFromInternalReference(String workflowReferenc
return workflowDTO;
}

/**
* Returns a workflow object for a given internal workflow reference and the workflow type.
*
* @param workflowReference Internal workflow reference
* @param workflowType Workflow type
* @return List<WorkflowDTO> List of workflow objects
* @throws APIManagementException if failed to retrieve workflow details
*/
public List<WorkflowDTO> retrieveAllWorkflowFromInternalReference(String workflowReference, String workflowType)
throws APIManagementException {

List<WorkflowDTO> workflowDTOList = new ArrayList<>();

try (Connection connection = APIMgtDBUtil.getConnection();
PreparedStatement statement = connection
.prepareStatement(SQLConstants.GET_ALL_WORKFLOW_ENTRY_FROM_INTERNAL_REF_SQL)) {
statement.setString(1, workflowReference);
statement.setString(2, workflowType);
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
WorkflowDTO workflowDTO = WorkflowExecutorFactory.getInstance()
.createWorkflowDTO(rs.getString("WF_TYPE"));
workflowDTO.setStatus(WorkflowStatus.valueOf(rs.getString("WF_STATUS")));
workflowDTO.setExternalWorkflowReference(rs.getString("WF_EXTERNAL_REFERENCE"));
workflowDTO.setCreatedTime(rs.getTimestamp("WF_CREATED_TIME").getTime());
workflowDTO.setWorkflowReference(rs.getString("WF_REFERENCE"));
workflowDTO.setTenantDomain(rs.getString("TENANT_DOMAIN"));
workflowDTO.setTenantId(rs.getInt("TENANT_ID"));
workflowDTO.setWorkflowDescription(rs.getString("WF_STATUS_DESC"));
workflowDTOList.add(workflowDTO);
InputStream metadataBlob = rs.getBinaryStream("WF_METADATA");

if (metadataBlob != null) {
String metadata = APIMgtDBUtil.getStringFromInputStream(metadataBlob);
Gson metadataGson = new Gson();
JSONObject metadataJson = metadataGson.fromJson(metadata, JSONObject.class);
workflowDTO.setMetadata(metadataJson);
} else {
JSONObject metadataJson = new JSONObject();
workflowDTO.setMetadata(metadataJson);
}
}
}
} catch (SQLException e) {
handleException("Error while retrieving workflow details for " + workflowReference, e);
}
return workflowDTOList;
}

private void setPublishedDefVersion(APIIdentifier apiId, Connection connection, String value)
throws APIManagementException {

Expand Down Expand Up @@ -16741,6 +16790,37 @@ public void addDeployedAPIRevision(String apiRevisionId, List<DeployedAPIRevisio
}
}

/**
* Update the status of the Revision deployment process
*
* @param revisionUUID UUID of the Revision
* @param status Status of the Revision deployment
* @param environment Environment of the Revision deployment
* @throws APIManagementException if an error occurs when updating the status of the Revision deployment
*/
public void updateAPIRevisionDeploymentStatus(String revisionUUID, String status, String environment)
throws APIManagementException {

try (Connection connection = APIMgtDBUtil.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement statement = connection
.prepareStatement(SQLConstants.APIRevisionSqlConstants.UPDATE_API_REVISION_STATUS_SQL)) {
statement.setString(1, status);
statement.setString(2, revisionUUID);
statement.setString(3, environment);
statement.executeUpdate();
connection.commit();
} catch (SQLException e) {
connection.rollback();
handleException(
"Failed to update API Revision deployment mapping details for revision: " + revisionUUID, e);
}
} catch (SQLException e) {
handleException("Could not open database connection", e);
}

}

/**
* Get APIRevisionDeployment details by providing deployment name and revision uuid
*
Expand Down Expand Up @@ -16807,6 +16887,38 @@ public List<APIRevisionDeployment> getAPIRevisionDeploymentByRevisionUUID(String
return apiRevisionDeploymentList;
}

/**
* Get APIRevisionDeployment details
*
* @param apiUUID API UUID
* @param workflowStatus Workflow status
* @return List<APIRevisionDeployment> APIRevisionDeployment list
* @throws APIManagementException if an error occurs while retrieving revision deployment mapping details
*/
public List<APIRevisionDeployment> getAPIRevisionDeploymentsByWorkflowStatusAndApiUUID(String apiUUID,
String workflowStatus) throws APIManagementException {

List<APIRevisionDeployment> apiRevisionDeploymentList = new ArrayList<>();
try (Connection connection = APIMgtDBUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(
SQLConstants.APIRevisionSqlConstants.GET_API_REVISION_DEPLOYMENT_MAPPINGS_BY_REVISION_STATUS_AND_API_UUID)) {
statement.setString(1, workflowStatus);
statement.setString(2, apiUUID);
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
APIRevisionDeployment apiRevisionDeployment = new APIRevisionDeployment();
String environmentName = rs.getString("NAME");
apiRevisionDeployment.setDeployment(environmentName);
apiRevisionDeployment.setRevisionUUID(rs.getString("REVISION_UUID"));
apiRevisionDeploymentList.add(apiRevisionDeployment);
}
}
} catch (SQLException e) {
handleException("Failed to get API Revision deployment mapping details", e);
}
return apiRevisionDeploymentList;
}

/**
* Get APIRevisionDeployment details by providing API uuid
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3695,24 +3695,30 @@ public static class APIRevisionSqlConstants {
= "SELECT * FROM AM_DEPLOYMENT_REVISION_MAPPING WHERE NAME = ? AND REVISION_UUID = ? ";
public static final String GET_API_REVISION_DEPLOYMENT_MAPPING_BY_REVISION_UUID
= "SELECT * FROM AM_DEPLOYMENT_REVISION_MAPPING WHERE REVISION_UUID = ?";
public static final String GET_API_REVISION_DEPLOYMENT_MAPPINGS_BY_REVISION_STATUS_AND_API_UUID =
"SELECT ADR.NAME, ADR.REVISION_UUID FROM AM_DEPLOYMENT_REVISION_MAPPING AS ADR JOIN "
+ "AM_REVISION AS AM ON ADR.REVISION_UUID = AM.REVISION_UUID WHERE "
+ "ADR.REVISION_STATUS = ? AND AM.API_UUID = ?";
public static final String UPDATE_API_REVISION_STATUS_SQL =
" UPDATE AM_DEPLOYMENT_REVISION_MAPPING SET REVISION_STATUS = ? WHERE REVISION_UUID = ? AND NAME = ?";
static final String GET_API_REVISION_DEPLOYMENTS
= "(SELECT NAME, VHOST, REVISION_UUID, DEPLOYED_TIME, 0 AS DISPLAY_ON_DEVPORTAL, NULL AS DEPLOY_TIME " +
"FROM AM_DEPLOYED_REVISION DR " +
= "(SELECT NAME, VHOST, REVISION_UUID, DEPLOYED_TIME, 0 AS DISPLAY_ON_DEVPORTAL, NULL AS DEPLOY_TIME, "
+ "NULL AS REVISION_STATUS FROM AM_DEPLOYED_REVISION DR " +
"UNION " +
"SELECT NAME, VHOST, REVISION_UUID, NULL AS DEPLOYED_TIME, DISPLAY_ON_DEVPORTAL, " +
"DEPLOYED_TIME AS DEPLOY_TIME " +
"DEPLOYED_TIME AS DEPLOY_TIME, REVISION_STATUS " +
"FROM AM_DEPLOYMENT_REVISION_MAPPING DRM) ";
public static final String GET_API_REVISION_DEPLOYMENTS_BY_API_UUID
= "SELECT * FROM " + GET_API_REVISION_DEPLOYMENTS + "AD " +
"WHERE AD.REVISION_UUID " +
"IN " +
"(SELECT REVISION_UUID FROM AM_REVISION WHERE API_UUID = ?)";
static final String GET_API_REVISION_DEPLOYMENTS_POSTGRES
= "(SELECT NAME, VHOST, REVISION_UUID, DEPLOYED_TIME, false AS DISPLAY_ON_DEVPORTAL, NULL AS DEPLOY_TIME " +
"FROM AM_DEPLOYED_REVISION DR " +
= "(SELECT NAME, VHOST, REVISION_UUID, DEPLOYED_TIME, false AS DISPLAY_ON_DEVPORTAL, " +
"NULL AS DEPLOY_TIME, NULL AS REVISION_STATUS FROM AM_DEPLOYED_REVISION DR " +
"UNION " +
"SELECT NAME, VHOST, REVISION_UUID, NULL AS DEPLOYED_TIME, DISPLAY_ON_DEVPORTAL, " +
"DEPLOYED_TIME AS DEPLOY_TIME " +
"DEPLOYED_TIME AS DEPLOY_TIME, REVISION_STATUS " +
"FROM AM_DEPLOYMENT_REVISION_MAPPING DRM) ";
public static final String GET_API_REVISION_DEPLOYMENTS_BY_API_UUID_POSTGRES
= "SELECT * FROM " + GET_API_REVISION_DEPLOYMENTS_POSTGRES + "AD " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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.impl.dto;

import org.wso2.carbon.apimgt.api.model.APIRevision;

/**
* APIRevision DTO class for workflow
*/
public class APIRevisionWorkflowDTO extends WorkflowDTO {
private APIRevision revision;
private String userName;
private String environment;
private String revisionId;
private String apiName;
private String apiProvider;
private String apiVersion;

public APIRevision getAPIRevision() {
return revision;
}

public void setAPIRevision(APIRevision revision) {
this.revision = revision;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getEnvironment() {
return environment;
}

public void setEnvironment(String environment) {
this.environment = environment;
}

public String getRevisionId() {
return revisionId;
}

public void setRevisionId(String revisionId) {
this.revisionId = revisionId;
}

public String getApiProvider() {
return apiProvider;
}

public void setApiProvider(String apiProvider) {
this.apiProvider = apiProvider;
}

public String getApiName() {
return apiName;
}

public void setApiName(String apiName) {
this.apiName = apiName;
}

public String getApiVersion() {
return apiVersion;
}

public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIManagerDatabaseException;
import org.wso2.carbon.apimgt.api.WorkflowStatus;
import org.wso2.carbon.apimgt.api.model.APIRevisionDeployment;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
Expand Down Expand Up @@ -245,11 +246,30 @@ public static List<APIRevisionDeployment> mergeRevisionDeploymentDTOs(ResultSet
String revisionUuid = rs.getString("REVISION_UUID");
String uniqueKey = (environmentName != null ? environmentName : "") +
(vhost != null ? vhost : "") + (revisionUuid != null ? revisionUuid : "");
String revisionStatus = rs.getString("REVISION_STATUS");
WorkflowStatus status = null;
if (revisionStatus != null) {
switch (revisionStatus) {
case "CREATED":
status = WorkflowStatus.CREATED;
break;
case "APPROVED":
status = WorkflowStatus.APPROVED;
break;
case "REJECTED":
status = WorkflowStatus.REJECTED;
break;
default:
// Handle the case where revisionStatus is not one of the expected values
break;
}
}
if (!uniqueSet.containsKey(uniqueKey)) {
apiRevisionDeployment = new APIRevisionDeployment();
apiRevisionDeployment.setDeployment(environmentName);
apiRevisionDeployment.setVhost(vhost);
apiRevisionDeployment.setRevisionUUID(revisionUuid);
apiRevisionDeployment.setStatus(status);
apiRevisionDeployment.setDisplayOnDevportal(rs.getBoolean("DISPLAY_ON_DEVPORTAL"));
apiRevisionDeployment.setDeployedTime(rs.getString("DEPLOY_TIME"));
apiRevisionDeployment.setSuccessDeployedTime(rs.getString("DEPLOYED_TIME"));
Expand Down
Loading

0 comments on commit c578caa

Please sign in to comment.