Skip to content

Commit

Permalink
Merge pull request #12061 from ashera96/api-policies
Browse files Browse the repository at this point in the history
Add the implementation of API level policies feature
  • Loading branch information
ashera96 committed Jul 11, 2023
2 parents 59f84fe + debef22 commit c3dfa1a
Show file tree
Hide file tree
Showing 25 changed files with 1,518 additions and 633 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -507,28 +507,28 @@ public enum ExceptionCodes implements ErrorHandler {
INVALID_TENANT_CONFIG(902001, "Invalid tenant-config found", 400, "Invalid tenant-config found with error %s", false),

//Operation Policies related error codes
INVALID_OPERATION_POLICY(902005, "Cannot find the selected operation policy", 400,
"Selected operation policy is not found"),
INVALID_OPERATION_POLICY_SPECIFICATION(902006, "Invalid operation policy specification found", 400,
"Invalid operation policy specification. %s", false),

INVALID_OPERATION_POLICY_PARAMETERS(902007, "Missing required parameters for operation policy specification", 400,
"Required parameter(s) %s for operation policy specification %s are either missing or empty"),
OPERATION_POLICY_NOT_ALLOWED_IN_THE_APPLIED_FLOW(902008, "Operation policy is not allowed in the applied flow", 400,
INVALID_OPERATION_POLICY(902005, "Cannot find the selected api policy", 400,
"Selected api policy is not found"),
INVALID_OPERATION_POLICY_SPECIFICATION(902006, "Invalid api policy specification found", 400,
"Invalid api policy specification. %s", false),

INVALID_OPERATION_POLICY_PARAMETERS(902007, "Missing required parameters for api policy specification", 400,
"Required parameter(s) %s for api policy specification %s are either missing or empty"),
OPERATION_POLICY_NOT_ALLOWED_IN_THE_APPLIED_FLOW(902008, "API policy is not allowed in the applied flow", 400,
"%s policy is not allowed in response flow"),
MISSING_MANDATORY_POLICY_ATTRIBUTES(902009, "Missing mandatory operation policy attribute", 400,
"Required attributes(s) %s for operation policy specification %s are either missing or empty"),
OPERATION_POLICY_NOT_FOUND(902010, "Operation Policy Not Found", 404,
"Requested operation policy with id '%s' not found"),
MISSING_MANDATORY_POLICY_ATTRIBUTES(902009, "Missing mandatory api policy attribute", 400,
"Required attributes(s) %s for api policy specification %s are either missing or empty"),
OPERATION_POLICY_NOT_FOUND(902010, "API Policy Not Found", 404,
"Requested api policy with id '%s' not found"),

OPERATION_POLICY_ALREADY_EXISTS(903001, "The Operation Policy already exists.", 409, "An Operation Policy with name '%s' and version '%s' already exists"),
OPERATION_POLICY_ALREADY_EXISTS(903001, "The API Policy already exists.", 409, "An Operation Policy with name '%s' and version '%s' already exists"),

OPERATION_POLICY_NOT_FOUND_WITH_NAME_AND_VERSION(903004, "Operation Policy Not Found with given name and version", 404,
"Requested operation policy with name '%s' and version '%s not found"),
OPERATION_POLICY_NOT_FOUND_WITH_NAME_AND_VERSION(903004, "API Policy Not Found with given name and version", 404,
"Requested api policy with name '%s' and version '%s not found"),

OPERATION_POLICY_GATEWAY_ERROR(903008,
"Either Synapse or Choreo Gateway Definition files or both should be present", 400,
"Operation Policy cannot be imported due to the missing Gateway files."),
"API Policy cannot be imported due to the missing Gateway files."),
ERROR_VALIDATING_API_POLICY(902011, "Error while validating API policies enforced for the API", 400,
"Error while validating the API policies enforced for the API"),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1463,4 +1463,14 @@ public String getAsyncTransportProtocols() {
public void setAsyncTransportProtocols(String asyncTransportProtocols) {
this.asyncTransportProtocols = asyncTransportProtocols;
}

public List<OperationPolicy> apiPolicies;

public List<OperationPolicy> getApiPolicies() {
return apiPolicies;
}

public void setApiPolicies(List<OperationPolicy> apiPolicies) {
this.apiPolicies = apiPolicies;
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4086,6 +4086,38 @@ public static class OperationPolicyConstants {
public static final String GET_COMMON_OPERATION_POLICY_NAMES_FOR_ORGANIZATION =
"SELECT OP.POLICY_NAME, OP.POLICY_VERSION FROM AM_OPERATION_POLICY OP INNER JOIN AM_COMMON_OPERATION_POLICY COP " +
" ON OP.POLICY_UUID = COP.POLICY_UUID WHERE OP.ORGANIZATION = ?";

public static final String ADD_API_POLICY_MAPPING =
"INSERT INTO AM_API_POLICY_MAPPING " +
" (API_UUID, REVISION_UUID, POLICY_UUID, DIRECTION, PARAMETERS, POLICY_ORDER) " +
" VALUES (?,?,?,?,?,?)";

public static final String DELETE_API_POLICY_MAPPING =
"DELETE FROM AM_API_POLICY_MAPPING WHERE API_UUID = ? AND REVISION_UUID IS null";

public static final String GET_API_POLICIES_FOR_API_REVISION_SQL =
" SELECT " +
" OP.POLICY_NAME, OP.POLICY_VERSION, APM.PARAMETERS, APM.DIRECTION, APM.POLICY_ORDER, APM.POLICY_UUID" +
" FROM " +
" AM_API_POLICY_MAPPING APM " +
" INNER JOIN AM_OPERATION_POLICY OP ON APM.POLICY_UUID = OP.POLICY_UUID " +
" WHERE " +
" APM.API_UUID = ? " +
" AND " +
" APM.REVISION_UUID = ? " +
" ORDER BY APM.API_POLICY_MAPPING_ID ASC ";

public static final String GET_API_POLICIES_OF_API_SQL =
" SELECT " +
" OP.POLICY_NAME, OP.POLICY_VERSION, APM.PARAMETERS, APM.DIRECTION, APM.POLICY_ORDER, APM.POLICY_UUID" +
" FROM " +
" AM_API_POLICY_MAPPING APM " +
" INNER JOIN AM_OPERATION_POLICY OP ON APM.POLICY_UUID = OP.POLICY_UUID " +
" WHERE " +
" APM.API_UUID = ? " +
" AND " +
" APM.REVISION_UUID IS NULL " +
" ORDER BY APM.API_POLICY_MAPPING_ID ASC ";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9889,20 +9889,24 @@ public static OperationPolicySpecification getValidatedOperationPolicySpecificat
throws APIManagementException {

Schema schema = APIUtil.retrieveOperationPolicySpecificationJsonSchema();
org.json.JSONObject policySpecJson = null;
if (schema != null) {
try {
org.json.JSONObject uploadedConfig = new org.json.JSONObject(policySpecAsString);
schema.validate(uploadedConfig);
policySpecJson = new org.json.JSONObject(policySpecAsString);
if (policySpecJson.has(APIConstants.DATA)) {
policySpecJson = policySpecJson.getJSONObject(APIConstants.DATA);
}
schema.validate(policySpecJson);
} catch (ValidationException e) {
List<String> errors = e.getAllMessages();
String errorMessage = errors.size() + " validation error(s) found. Error(s) :" + errors.toString();
throw new APIManagementException("Policy specification validation failure. " + errorMessage,
ExceptionCodes.from(ExceptionCodes.INVALID_OPERATION_POLICY_SPECIFICATION,
errorMessage));
}
return new Gson().fromJson(policySpecAsString, OperationPolicySpecification.class);
return new Gson().fromJson(policySpecJson.toString(), OperationPolicySpecification.class);
}
return null;
throw new APIManagementException("API policy schema not found");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,12 @@
import org.wso2.carbon.apimgt.api.model.Documentation;
import org.wso2.carbon.apimgt.api.model.Documentation.DocumentSourceType;
import org.wso2.carbon.apimgt.api.model.Documentation.DocumentVisibility;
import org.wso2.carbon.apimgt.api.model.DocumentationContent;
import org.wso2.carbon.apimgt.api.model.DocumentationType;
import org.wso2.carbon.apimgt.api.model.KeyManager;
import org.wso2.carbon.apimgt.api.model.OperationPolicy;
import org.wso2.carbon.apimgt.api.model.OperationPolicyData;
import org.wso2.carbon.apimgt.api.model.ResourceFile;
import org.wso2.carbon.apimgt.api.model.SubscribedAPI;
import org.wso2.carbon.apimgt.api.model.Subscriber;
import org.wso2.carbon.apimgt.api.model.Tier;
import org.wso2.carbon.apimgt.api.model.URITemplate;
import org.wso2.carbon.apimgt.api.model.policy.APIPolicy;
import org.wso2.carbon.apimgt.api.model.policy.ApplicationPolicy;
Expand Down Expand Up @@ -99,14 +96,12 @@
import org.wso2.carbon.apimgt.persistence.dto.Organization;
import org.wso2.carbon.apimgt.persistence.dto.PublisherAPI;
import org.wso2.carbon.apimgt.persistence.dto.PublisherAPIInfo;
import org.wso2.carbon.apimgt.persistence.dto.PublisherAPIProduct;
import org.wso2.carbon.apimgt.persistence.dto.PublisherAPISearchResult;
import org.wso2.carbon.apimgt.persistence.dto.UserContext;
import org.wso2.carbon.apimgt.persistence.exceptions.APIPersistenceException;
import org.wso2.carbon.apimgt.persistence.exceptions.MediationPolicyPersistenceException;
import org.wso2.carbon.apimgt.persistence.utils.RegistryPersistenceUtil;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.governance.api.exception.GovernanceException;
import org.wso2.carbon.governance.api.generic.GenericArtifactManager;
import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact;
import org.wso2.carbon.governance.api.util.GovernanceUtils;
Expand Down Expand Up @@ -1364,7 +1359,7 @@ public void testChangeLifeCycleStatusOfAPIProduct() throws APIManagementExceptio
}

@Test
public void testOperationPolicyListingWhenMediationPoliciesExists() throws APIManagementException {
public void testApiPolicyListingWhenMediationPoliciesExists() throws APIManagementException {

APIProviderImplWrapper apiProvider = new APIProviderImplWrapper(apimgtDAO, scopesDAO);
APIIdentifier apiId = new APIIdentifier("admin", "PizzaShackAPI", "1.0.0",
Expand Down Expand Up @@ -1402,17 +1397,15 @@ public void testOperationPolicyListingWhenMediationPoliciesExists() throws APIMa
APIConstants.DEFAULT_POLICY_VERSION, api.getUuid(), null, superTenantDomain, false)).thenReturn(null);

PowerMockito.when(APIUtil.isSequenceDefined(Mockito.anyString())).thenReturn(true);
apiProvider.loadMediationPoliciesAsOperationPoliciesToAPI(api, superTenantDomain);
apiProvider.loadMediationPoliciesFromMigratedAPIToAPI(api, superTenantDomain);

Assert.assertNotNull(uriTemplate1.getOperationPolicies());
Assert.assertNotNull(uriTemplate2.getOperationPolicies());
Assert.assertEquals(uriTemplate1.getOperationPolicies().size(), 3);
Assert.assertEquals(uriTemplate2.getOperationPolicies().size(), 3);
Assert.assertEquals(uriTemplate1.getOperationPolicies().get(0).getPolicyName(), "test-sequence");
Assert.assertNotNull(api.getApiPolicies());
Assert.assertEquals(api.getApiPolicies().size(), 3);
Assert.assertEquals(api.getApiPolicies().get(0).getPolicyName(), "test-sequence");
}

@Test
public void testOperationPolicyListingWhenMediationPoliciesExistsAndPolicyAlreadyMigrated() throws APIManagementException {
public void testApiPolicyListingWhenMediationPoliciesExistsAndPolicyAlreadyMigrated() throws APIManagementException {

APIProviderImplWrapper apiProvider = new APIProviderImplWrapper(apimgtDAO, scopesDAO);
APIIdentifier apiId = new APIIdentifier("admin", "PizzaShackAPI", "1.0.0",
Expand Down Expand Up @@ -1454,25 +1447,24 @@ public void testOperationPolicyListingWhenMediationPoliciesExistsAndPolicyAlread
APIConstants.DEFAULT_POLICY_VERSION, api.getUuid(), null, superTenantDomain, false)).thenReturn(policyData);

PowerMockito.when(APIUtil.isSequenceDefined(Mockito.anyString())).thenReturn(true);
apiProvider.loadMediationPoliciesAsOperationPoliciesToAPI(api, superTenantDomain);

for (URITemplate template : api.getUriTemplates()) {
for (OperationPolicy policy : template.getOperationPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), policyId);
}
if (APIConstants.OPERATION_SEQUENCE_TYPE_RESPONSE.equals(policy.getDirection())) {
Assert.assertNull(policy.getPolicyId());
}
if (APIConstants.OPERATION_SEQUENCE_TYPE_FAULT.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), policyId);
}
apiProvider.loadMediationPoliciesFromMigratedAPIToAPI(api, superTenantDomain);


for (OperationPolicy policy : api.getApiPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), policyId);
}
if (APIConstants.OPERATION_SEQUENCE_TYPE_RESPONSE.equals(policy.getDirection())) {
Assert.assertNull(policy.getPolicyId());
}
if (APIConstants.OPERATION_SEQUENCE_TYPE_FAULT.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), policyId);
}
}
}

@Test
public void testMigrationOfMediationPoliciesToOperationPolicies()
public void testMigrationOfMediationPoliciesToAPIPolicies()
throws APIManagementException, MediationPolicyPersistenceException {

String apiuuid = "63e1e37e-a5b8-4be6-86a5-d6ae0749f131";
Expand Down Expand Up @@ -1509,24 +1501,26 @@ public void testMigrationOfMediationPoliciesToOperationPolicies()
appliedPolicy.setOrder(1);
appliedPolicy.setDirection(APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST);

List<OperationPolicy> policyList = new ArrayList<>();
policyList.add(APIProviderImpl.cloneOperationPolicy(appliedPolicy));

URITemplate uriTemplate1 = new URITemplate();
uriTemplate1.setHTTPVerb("POST");
uriTemplate1.setAuthType("Application");
uriTemplate1.setUriTemplate("/add");
uriTemplate1.setThrottlingTier("Gold");
uriTemplate1.addOperationPolicy(APIProviderImpl.cloneOperationPolicy(appliedPolicy));
uriTemplates.add(uriTemplate1);

URITemplate uriTemplate2 = new URITemplate();
uriTemplate2.setHTTPVerb("PUT");
uriTemplate2.setAuthType("Application");
uriTemplate2.setUriTemplate("/update");
uriTemplate2.setThrottlingTier("Gold");
uriTemplate2.addOperationPolicy(APIProviderImpl.cloneOperationPolicy(appliedPolicy));
uriTemplates.add(uriTemplate2);

api.setUriTemplates(uriTemplates);
api.setInSequence("in-policy");
api.setApiPolicies(policyList);

PowerMockito.when(APIUtil.isSequenceDefined(api.getInSequence())).thenReturn(true);

Expand All @@ -1538,13 +1532,11 @@ public void testMigrationOfMediationPoliciesToOperationPolicies()

apiProvider.migrateMediationPoliciesOfAPI(api, superTenantDomain, false);

for (URITemplate template : api.getUriTemplates()) {
for (OperationPolicy policy : template.getOperationPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), "11111");
} else {
Assert.fail("template " + template.getUriTemplate() + " should not contain other paths for operation policies");
}
for (OperationPolicy policy : api.getApiPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), "11111");
} else {
Assert.fail("should not contain other paths for api policies");
}
}
Assert.assertNull(api.getInSequence());
Expand All @@ -1553,7 +1545,7 @@ public void testMigrationOfMediationPoliciesToOperationPolicies()


@Test
public void testMigrationOfMediationPoliciesToOperationPoliciesIfPoliciesAlreadyMigrated()
public void testMigrationOfMediationPoliciesToAPIPoliciesIfPoliciesAlreadyMigrated()
throws APIManagementException, MediationPolicyPersistenceException {

String apiuuid = "63e1e37e-a5b8-4be6-86a5-d6ae0749f131";
Expand Down Expand Up @@ -1590,24 +1582,26 @@ public void testMigrationOfMediationPoliciesToOperationPoliciesIfPoliciesAlready
appliedPolicy.setOrder(1);
appliedPolicy.setDirection(APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST);

List<OperationPolicy> policyList = new ArrayList<>();
policyList.add(APIProviderImpl.cloneOperationPolicy(appliedPolicy));

URITemplate uriTemplate1 = new URITemplate();
uriTemplate1.setHTTPVerb("POST");
uriTemplate1.setAuthType("Application");
uriTemplate1.setUriTemplate("/add");
uriTemplate1.setThrottlingTier("Gold");
uriTemplate1.addOperationPolicy(APIProviderImpl.cloneOperationPolicy(appliedPolicy));
uriTemplates.add(uriTemplate1);

URITemplate uriTemplate2 = new URITemplate();
uriTemplate2.setHTTPVerb("PUT");
uriTemplate2.setAuthType("Application");
uriTemplate2.setUriTemplate("/update");
uriTemplate2.setThrottlingTier("Gold");
uriTemplate2.addOperationPolicy(APIProviderImpl.cloneOperationPolicy(appliedPolicy));
uriTemplates.add(uriTemplate2);

api.setUriTemplates(uriTemplates);
api.setInSequence("in-policy");
api.setApiPolicies(policyList);

PowerMockito.when(APIUtil.isSequenceDefined(api.getInSequence())).thenReturn(true);

Expand All @@ -1616,13 +1610,11 @@ public void testMigrationOfMediationPoliciesToOperationPoliciesIfPoliciesAlready

apiProvider.migrateMediationPoliciesOfAPI(api, superTenantDomain, false);

for (URITemplate template : api.getUriTemplates()) {
for (OperationPolicy policy : template.getOperationPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), "11111");
} else {
Assert.fail("template " + template.getUriTemplate() + " should not contain other paths for operation policies");
}
for (OperationPolicy policy : api.getApiPolicies()) {
if (APIConstants.OPERATION_SEQUENCE_TYPE_REQUEST.equals(policy.getDirection())) {
Assert.assertEquals(policy.getPolicyId(), "11111");
} else {
Assert.fail("Should not contain other paths for API policies");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,7 @@ public void testCommonPolicyCloneToAPI() throws Exception {
api.setUriTemplates(getUriTemplateSetWithPolicies(policyList));
apiMgtDAO.updateAPI(api);
apiMgtDAO.updateURITemplates(api, -1234);
apiMgtDAO.updateAPIPoliciesMapping(api.getUuid(), api.getUriTemplates(), api.getApiPolicies(), "carbon.super");

String clonedPolicyUUID = null;

Expand Down Expand Up @@ -1628,6 +1629,7 @@ public void testClonePolicyDeleteIfNotUsed() throws Exception {
api.setUriTemplates(getUriTemplateSetWithPolicies(policyList));
apiMgtDAO.updateAPI(api);
apiMgtDAO.updateURITemplates(api, -1234);
apiMgtDAO.updateAPIPoliciesMapping(api.getUuid(), api.getUriTemplates(), api.getApiPolicies(), "carbon.super");

String clonedAddHeaderPolicyUUID = null;

Expand All @@ -1645,6 +1647,7 @@ public void testClonePolicyDeleteIfNotUsed() throws Exception {
api.setUriTemplates(getUriTemplateSetWithPolicies(newPolicyList));
apiMgtDAO.updateAPI(api);
apiMgtDAO.updateURITemplates(api, -1234);
apiMgtDAO.updateAPIPoliciesMapping(api.getUuid(), api.getUriTemplates(), api.getApiPolicies(), "carbon.super");

Set<URITemplate> updatedUriTemplates = apiMgtDAO.getURITemplatesWithOperationPolicies(api.getUuid());
String clonedLogPolicyUUID = null;
Expand Down
Loading

0 comments on commit c3dfa1a

Please sign in to comment.