Skip to content

Commit

Permalink
Merge pull request #12660 from RusJaI/master
Browse files Browse the repository at this point in the history
Modify implementation to allow an API and a Common policies with same and version
  • Loading branch information
RusJaI authored Jan 29, 2025
2 parents 0d46a1b + a5c721b commit 9348fff
Showing 14 changed files with 364 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1543,8 +1543,10 @@ EnvironmentPropertiesDTO getEnvironmentSpecificAPIProperties(String apiUuid, Str
void setOperationPoliciesToURITemplates(String apiId, Set<URITemplate> uriTemplates) throws APIManagementException;

/**
* Import an operation policy from the API CTL project. This will either create a new API specific policy,
* update existing API specific policy or return the policyID of existing policy if policy content is not changed.
* Import an operation policy from the API CTL project which is exported from a product version prior to the update
* level which introduced to have an API and a Common policy with identical names and versions.
* This will either create a new API specific policy, update existing API specific policy or return the
* policyID of existing policy if policy content is not changed.
*
* @param operationPolicyData Operation Policy Data
* @param organization Organization name
@@ -1554,6 +1556,21 @@ EnvironmentPropertiesDTO getEnvironmentSpecificAPIProperties(String apiUuid, Str
String importOperationPolicy(OperationPolicyData operationPolicyData, String organization)
throws APIManagementException;

/**
* Import an operation policy of a given policy type, from the API CTL project.
* This will either create a new API specific policy, update existing API specific policy or return the
* policyID of existing policy if policy content is not changed.
*
* @param operationPolicyData Operation Policy Data
* @param organization Organization name
* @param policyType Policy Type
* @return UUID of the imported operation policy
* @throws APIManagementException
*/
String importOperationPolicyOfGivenType(OperationPolicyData operationPolicyData, String policyType,
String organization) throws APIManagementException;


/**
* Add an API specific operation policy
*
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ public class OperationPolicy implements Comparable<OperationPolicy> {

private String policyName = "";
private String policyVersion = "v1";
private String policyType = null;
private String direction = null;
private Map<String, Object> parameters = null;
private String policyId = null;
@@ -50,6 +51,16 @@ public void setPolicyVersion(String policyVersion) {
this.policyVersion = policyVersion;
}

public String getPolicyType() {

return policyType;
}

public void setPolicyType(String policyType) {

this.policyType = policyType;
}

public Map<String, Object> getParameters() {

return parameters;
@@ -98,7 +109,8 @@ public boolean equals(Object o) {
if (o instanceof OperationPolicy) {
OperationPolicy policyObj = (OperationPolicy) o;
return Objects.equals(policyName, policyObj.policyName) && Objects.equals(policyVersion,
policyObj.policyVersion) && Objects.equals(direction, policyObj.direction) && Objects.equals(
policyObj.policyVersion) && Objects.equals(direction, policyObj.direction)
&& policyType.equals(policyObj.policyType) && Objects.equals(
parameters, policyObj.parameters) && Objects.equals(policyId, policyObj.policyId);
}
return false;
Original file line number Diff line number Diff line change
@@ -135,6 +135,7 @@
import org.wso2.carbon.apimgt.impl.importexport.APIImportExportException;
import org.wso2.carbon.apimgt.impl.importexport.ExportFormat;
import org.wso2.carbon.apimgt.impl.importexport.ImportExportAPI;
import org.wso2.carbon.apimgt.impl.importexport.ImportExportConstants;
import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder;
import org.wso2.carbon.apimgt.impl.lifecycle.CheckListItem;
import org.wso2.carbon.apimgt.impl.lifecycle.LCManagerFactory;
@@ -5299,6 +5300,84 @@ public String getSecuritySchemeOfAPI(String uuid, String organization) throws AP
}
}

/**
*
* @param policy
* @param apiOperationPolicyIdToClonedPolicyIdMap
* @return
* @throws APIManagementException
*/
public String getPolicyType(OperationPolicy policy, Map<String, String> apiOperationPolicyIdToClonedPolicyIdMap)
throws APIManagementException {
if (policy.getPolicyId() == null) {
return ImportExportConstants.POLICY_TYPE_API;
} else {
// check if cloned policy id is null
if (apiOperationPolicyIdToClonedPolicyIdMap.get(policy.getPolicyId()) == null) {
return ImportExportConstants.POLICY_TYPE_API;
} else {
return ImportExportConstants.POLICY_TYPE_COMMON;
}
}
}

public String getProductPolicyType(OperationPolicy policy, String apiUUID,
Map<String, String> apiProductOperationPolicyIdToClonedPolicyIdMap)
throws APIManagementException {

String originatedPolicyId = apiProductOperationPolicyIdToClonedPolicyIdMap.get(policy.getPolicyId());
Map<String, String> apiOperationPolicyIdToClonedPolicyIdMap =
getClonedAPISpecificOperationPolicyIdsList(apiUUID);
policy.setPolicyId(originatedPolicyId);
return getPolicyType(policy, apiOperationPolicyIdToClonedPolicyIdMap);
}

public void populatePolicyTypeInAPI(API api) throws APIManagementException {

Map<String, String> apiOperationPolicyIdToClonedPolicyIdMap = getClonedAPISpecificOperationPolicyIdsList(api.getUuid());
Set<URITemplate> uriTemplates = api.getUriTemplates();
for (URITemplate uriTemplate : uriTemplates) {
List<OperationPolicy> operationPolicies = uriTemplate.getOperationPolicies();
if (!operationPolicies.isEmpty()) {
for (OperationPolicy operationPolicy : operationPolicies) {
String policyType = getPolicyType(operationPolicy, apiOperationPolicyIdToClonedPolicyIdMap);
operationPolicy.setPolicyType(policyType);
}
}
}
api.setUriTemplates(uriTemplates);

List<OperationPolicy> apiPolicies = api.getApiPolicies();
if (apiPolicies != null && !apiPolicies.isEmpty()) {
for (OperationPolicy policy : apiPolicies) {
String policyType = getPolicyType(policy, apiOperationPolicyIdToClonedPolicyIdMap);
policy.setPolicyType(policyType);
}
}
api.setApiPolicies(apiPolicies);
}

public void populatePolicyTypeInApiProduct(APIProduct product) throws APIManagementException {

Map<String, String> apiProductOperationPolicyIdToClonedPolicyIdMap =
getClonedAPISpecificOperationPolicyIdsList(product.getUuid());
List<APIProductResource> productResources = product.getProductResources();
for (APIProductResource resource : productResources) {
URITemplate uriTemplate = resource.getUriTemplate();
List<OperationPolicy> operationPolicies = uriTemplate.getOperationPolicies();
if (!operationPolicies.isEmpty()) {
for (OperationPolicy operationPolicy : operationPolicies) {
String policyType = getProductPolicyType(operationPolicy, resource.getApiId(),
apiProductOperationPolicyIdToClonedPolicyIdMap);
operationPolicy.setPolicyType(policyType);
}
}
uriTemplate.setOperationPolicies(operationPolicies);
resource.setUriTemplate(uriTemplate);
}
product.setProductResources(productResources);
}

@Override
public boolean isSubscriptionValidationDisabled(String uuid) throws APIManagementException {
String status = apiMgtDAO.getSubscriptionValidationStatus(uuid);
@@ -5341,6 +5420,7 @@ public API getAPIbyUUID(String uuid, String organization) throws APIManagementEx
populateApiInfo(api);
populateSubtypeConfiguration(api);
populateDefaultVersion(api);
populatePolicyTypeInAPI(api);
return api;
} else {
String msg = "Failed to get API. API artifact corresponding to artifactId " + uuid + " does not exist";
@@ -5520,6 +5600,7 @@ public APIProduct getAPIProductbyUUID(String uuid, String organization) throws A
if (migrationEnabled == null) {
populateDefaultVersion(product);
}
populatePolicyTypeInApiProduct(product);
return product;
} else {
String msg = "Failed to get API Product. API Product artifact corresponding to artifactId " + uuid
@@ -7053,7 +7134,7 @@ public void setOperationPoliciesToURITemplates(String apiId, Set<URITemplate> ur
* If there aren't any existing policies, a new API specific policy will be created.
*
* @param importedPolicyData Imported policy
* @param organization Organization name
* @param organization Organization name
* @return corrosponding policy ID for imported data
* @throws APIManagementException if failed to delete APIRevision
*/
@@ -7116,6 +7197,87 @@ public String importOperationPolicy(OperationPolicyData importedPolicyData, Stri
return policyId;
}

@Override
public String importOperationPolicyOfGivenType(OperationPolicyData importedPolicyData, String policyType,
String organization) throws APIManagementException {

OperationPolicySpecification importedSpec = importedPolicyData.getSpecification();
OperationPolicyData existingOperationPolicy;

String policyId = null;
if (policyType == null) {
/*To handle scenarios where api is exported from a previous U2 version. API and Common policies with
same name and same version is not supported there
*/
policyId = importOperationPolicy(importedPolicyData, organization);
} else if (policyType.equalsIgnoreCase(ImportExportConstants.POLICY_TYPE_COMMON)) {
existingOperationPolicy = getCommonOperationPolicyByPolicyName(importedSpec.getName(),
importedSpec.getVersion(), organization, false);

if (existingOperationPolicy != null) {
if (existingOperationPolicy.getMd5Hash().equals(importedPolicyData.getMd5Hash())) {
if (log.isDebugEnabled()) {
log.debug("Matching common policy found for imported policy and Md5 hashes match.");
}
policyId = existingOperationPolicy.getPolicyId();
} else {
importedSpec.setName(importedSpec.getName() + "_imported");
importedSpec.setDisplayName(importedSpec.getDisplayName() + " Imported");
importedPolicyData.setSpecification(importedSpec);
importedPolicyData.setMd5Hash(APIUtil.getHashOfOperationPolicy(importedPolicyData));
policyId = addAPISpecificOperationPolicy(importedPolicyData.getApiUUID(), importedPolicyData,
organization);
if (log.isDebugEnabled()) {
log.debug("Even though existing common policy name match with imported policy, "
+ "the MD5 hashes does not match in the policy " + existingOperationPolicy.getPolicyId()
+ ". A new policy created with ID " + policyId);
}
}
} else {
importedSpec.setName(importedSpec.getName() + "_imported");
importedSpec.setDisplayName(importedSpec.getDisplayName() + " Imported");
importedPolicyData.setSpecification(importedSpec);
importedPolicyData.setMd5Hash(APIUtil.getHashOfOperationPolicy(importedPolicyData));
policyId = addAPISpecificOperationPolicy(importedPolicyData.getApiUUID(), importedPolicyData,
organization);
if (log.isDebugEnabled()) {
log.debug("There is no common policy currently available for the imported policy. " +
"A new policy created with ID " + policyId);
}
}
} else { //api level policy by default
existingOperationPolicy =
getAPISpecificOperationPolicyByPolicyName(importedSpec.getName(), importedSpec.getVersion(),
importedPolicyData.getApiUUID(), null, organization, false);

if (existingOperationPolicy != null) {
if (existingOperationPolicy.getMd5Hash().equals(importedPolicyData.getMd5Hash())) {
if (log.isDebugEnabled()) {
log.debug("Matching API specific policy found for imported policy and MD5 hashes match.");
}
} else {
if (log.isDebugEnabled()) {
log.debug("Even though existing API specific policy name match with imported policy, "
+ "the MD5 hashes does not match in the policy " + existingOperationPolicy.getPolicyId()
+ ".Therefore updating the existing policy");
}
updateOperationPolicy(existingOperationPolicy.getPolicyId(), importedPolicyData, organization);
}
policyId = existingOperationPolicy.getPolicyId();
} else {
policyId = addAPISpecificOperationPolicy(importedPolicyData.getApiUUID(), importedPolicyData,
organization);
if (log.isDebugEnabled()) {
log.debug(
"There aren't any existing policies for the imported policy. A new policy created with ID "
+ policyId);
}
}
}

return policyId;
}

@Override
public String addAPISpecificOperationPolicy(String apiUUID, OperationPolicyData operationPolicyData,
String tenantDomain)
@@ -7169,6 +7331,13 @@ public OperationPolicyData getAPISpecificOperationPolicyByPolicyId(String policy
.getAPISpecificOperationPolicyByPolicyID(policyId, apiUUID, organization, isWithPolicyDefinition);
}

public Map<String, String> getClonedAPISpecificOperationPolicyIdsList(String apiUUID)
throws APIManagementException {

return apiMgtDAO
.getClonedIdsMappedApiSpecificOperationPolicies(apiUUID);
}

@Override
public OperationPolicyData getCommonOperationPolicyByPolicyId(String policyId, String organization,
boolean isWithPolicyDefinition)
Original file line number Diff line number Diff line change
@@ -20904,6 +20904,50 @@ private OperationPolicyData getAPISpecificOperationPolicyByPolicyID(Connection c
return policyData;
}

/**
* Get the list of API specific operation policy IDs from AM_API_OPERATION_POLICY table where cloned policy ID is
* non null. This method is intended to get the common operation policy IDs which have been attached to the
* given API.
*
* @param apiUUID UUID of the API
* @return operation policy
* @throws APIManagementException
*/
public Map<String, String> getClonedIdsMappedApiSpecificOperationPolicies(String apiUUID)
throws APIManagementException {

try (Connection connection = APIMgtDBUtil.getConnection()) {
return getClonedIdsMappedApiSpecificOperationPolicies(connection, apiUUID);
} catch (SQLException e) {
handleException("Failed to get the API specific operation policy IDs from API "
+ apiUUID, e);
}
return null;
}

private Map<String, String> getClonedIdsMappedApiSpecificOperationPolicies(Connection connection, String apiUUID)
throws SQLException, APIManagementException {

String dbQuery;
boolean isAPIRevision = checkAPIUUIDIsARevisionUUID(apiUUID) != null;
if (isAPIRevision) {
dbQuery = SQLConstants.OperationPolicyConstants.
GET_REVISION_SPECIFIC_OPERATION_POLICY_IDS_FROM_REVISION_UUID;
} else {
dbQuery = SQLConstants.OperationPolicyConstants.GET_API_SPECIFIC_OPERATION_POLICY_IDS_FROM_API_UUID;
}
Map<String, String> policyMap = new HashMap<>();
try (PreparedStatement statement = connection.prepareStatement(dbQuery)) {
statement.setString(1, apiUUID);
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
policyMap.put(rs.getString("POLICY_UUID"), rs.getString("CLONED_POLICY_UUID"));
}
}
}
return policyMap;
}

private List<OperationPolicyDefinition> getPolicyDefinitionForPolicyId(Connection connection, String policyId)
throws SQLException {

@@ -21273,7 +21317,13 @@ public Set<String> getCommonOperationPolicyNames(String organization) throws API
while (rs.next()) {
String policyName = rs.getString("POLICY_NAME");
String policyVersion = rs.getString("POLICY_VERSION");
policyNames.add(APIUtil.getOperationPolicyFileName(policyName, policyVersion));
policyNames.add(APIUtil.getOperationPolicyFileName(policyName, policyVersion, null));
/*since the only usage of this method is to load the common operation policies from the
specifications and we are keeping only the common policies without appending the string "common"
to the file name, it's not required to append the policyType string
(policyNames.add(APIUtil.getOperationPolicyFileName(policyName, policyVersion,
ImportExportConstants.POLICY_TYPE_COMMON));)here as well.
*/
}
}
} catch (SQLException e) {
Loading

0 comments on commit 9348fff

Please sign in to comment.