use of org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO in project carbon-apimgt by wso2.
the class ThrottleConditionEvaluatorTest method testRetrievingEmptyApplicableConditionsWhenConditionsAreNotAvailableInConditionGroup.
@Test
public void testRetrievingEmptyApplicableConditionsWhenConditionsAreNotAvailableInConditionGroup() {
ConditionDTO[] conditionDTOs = new ConditionDTO[0];
ConditionGroupDTO conditionGroupDTO = new ConditionGroupDTO();
conditionGroupDTO.setConditions(conditionDTOs);
ConditionGroupDTO[] conditionGroupDTOS = { conditionGroupDTO };
List<ConditionGroupDTO> conditionGroupDTOList = throttleConditionEvaluator.getApplicableConditions(TestUtils.getMessageContext(apiContext, apiVersion), new AuthenticationContext(), conditionGroupDTOS);
// Should return empty Condition group in the Condition group array
Assert.assertNull(conditionGroupDTOList.get(0));
}
use of org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO in project carbon-apimgt by wso2.
the class ThrottleConditionEvaluatorTest method testApplicabilityOfMatchingQueryParameterTypeCondition.
@Test
public void testApplicabilityOfMatchingQueryParameterTypeCondition() {
ConditionGroupDTO conditionGroupDTO = new ConditionGroupDTO();
conditionGroupDTO.setConditionGroupId("QueryParameterTypeConditionGroup");
ConditionDTO matchingCondition = new ConditionDTO();
matchingCondition.setConditionType("QueryParameterType");
matchingCondition.setConditionName("city");
matchingCondition.setConditionValue("colombo");
ConditionDTO[] conditionDTOS = { matchingCondition };
conditionGroupDTO.setConditions(conditionDTOS);
ConditionGroupDTO[] conditionGroupDTOS = { conditionGroupDTO };
MessageContext messageContext = TestUtils.getMessageContext(apiContext, apiVersion);
((Axis2MessageContext) messageContext).getAxis2MessageContext().setProperty("REST_URL_POSTFIX", "/temperature?city=colombo");
List<ConditionGroupDTO> matchingConditionGroups = throttleConditionEvaluator.getApplicableConditions(messageContext, new AuthenticationContext(), conditionGroupDTOS);
Assert.assertEquals(matchingConditionGroups.get(0).getConditionGroupId(), "QueryParameterTypeConditionGroup");
}
use of org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO in project carbon-apimgt by wso2.
the class ThrottleHandler method doRoleBasedAccessThrottlingWithCEP.
/**
* This method is responsible for throttle incoming messages. This method will perform Application, Subscription
* and Resource level throttling.
*
* @param synCtx Synapse message context that contains message details.
* @param cc Configuration context which holds current configuration context.
* @return
*/
private boolean doRoleBasedAccessThrottlingWithCEP(MessageContext synCtx, ConfigurationContext cc, AuthenticationContext authenticationContext) {
// Throttle Keys
// applicationLevelThrottleKey key is combination of {applicationId}:{authorizedUser}
String applicationLevelThrottleKey;
// subscriptionLevelThrottleKey key for an api subscription is combination of {applicationId}:{apiContext}:{apiVersion}
// subscriptionLevelThrottleKey key for an api subscription is combination of {applicationId}:{productName}:{productProvider}
// Todo: add product version to key when versioning is supported
String subscriptionLevelThrottleKey;
// The key is combination of {apiContext}/ {apiVersion}{resourceUri}:{httpMethod} if policy is user level then authorized user will append at end
String resourceLevelThrottleKey = "";
// apiLevelThrottleKey key is combination of {apiContext}:{apiVersion}
String apiLevelThrottleKey;
// Throttle Tiers
String applicationLevelTier;
String subscriptionLevelTier;
String resourceLevelTier = "";
String apiLevelTier;
// Other Relevant parameters
AuthenticationContext authContext = authenticationContext;
String authorizedUser;
// Throttled decisions
boolean isThrottled = false;
boolean isResourceLevelThrottled = false;
boolean isOperationLevelThrottled = false;
boolean isApplicationLevelThrottled;
boolean isSubscriptionLevelThrottled;
boolean isSubscriptionLevelSpikeThrottled = false;
boolean isApiLevelThrottled = false;
boolean isBlockedRequest = false;
boolean apiLevelThrottledTriggered = false;
boolean policyLevelUserTriggered = false;
String ipLevelBlockingKey;
String appLevelBlockingKey = "";
String subscriptionLevelBlockingKey = "";
boolean stopOnQuotaReach = true;
String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
apiContext = apiContext != null ? apiContext : "";
apiVersion = apiVersion != null ? apiVersion : "";
String clientIp = GatewayUtils.getClientIp(synCtx);
String subscriberTenantDomain = "";
String apiTenantDomain = getTenantDomain();
ConditionGroupDTO[] conditionGroupDTOs;
String applicationId = authContext.getApplicationId();
// If Authz context is not null only we can proceed with throttling
if (authContext != null) {
authorizedUser = authContext.getUsername();
// Check if the tenant domain is appended with authorizedUser and append if it is not there
if (!StringUtils.contains(authorizedUser, apiTenantDomain)) {
authorizedUser = authContext.getUsername() + "@" + apiTenantDomain;
}
// Do blocking if there are blocking conditions present
if (getThrottleDataHolder().isBlockingConditionsPresent()) {
appLevelBlockingKey = authContext.getSubscriber() + ":" + authContext.getApplicationName();
subscriptionLevelBlockingKey = apiContext + ":" + apiVersion + ":" + authContext.getSubscriber() + "-" + authContext.getApplicationName() + ":" + authContext.getKeyType();
Timer timer = getTimer(MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), BLOCKED_TEST));
Timer.Context context = timer.start();
isBlockedRequest = getThrottleDataHolder().isRequestBlocked(apiContext, appLevelBlockingKey, authorizedUser, clientIp, apiTenantDomain, subscriptionLevelBlockingKey);
context.stop();
}
if (isBlockedRequest) {
String msg = "Request blocked as it violates defined blocking conditions, for API: " + apiContext + " ,application:" + appLevelBlockingKey + " ,user:" + authorizedUser;
if (log.isDebugEnabled()) {
log.debug(msg);
}
synCtx.setProperty(APIThrottleConstants.BLOCKED_REASON, msg);
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.REQUEST_BLOCKED);
isThrottled = true;
} else {
subscriberTenantDomain = authContext.getSubscriberTenantDomain();
applicationLevelThrottleKey = applicationId + ":" + authorizedUser;
apiLevelThrottleKey = apiContext + ":" + apiVersion;
stopOnQuotaReach = authContext.isStopOnQuotaReach();
applicationLevelTier = authContext.getApplicationTier();
subscriptionLevelTier = authContext.getTier();
apiLevelTier = authContext.getApiTier();
VerbInfoDTO throttledResource = new VerbInfoDTO();
// If request is not blocked then only we perform throttling.
List<VerbInfoDTO> verbInfoDTOList = (List<VerbInfoDTO>) synCtx.getProperty(APIConstants.VERB_INFO_DTO);
// If API level tier is not present only we should move to resource level tiers.
if (verbInfoDTOList == null) {
log.warn("Error while getting throttling information for resource and http verb");
return false;
}
for (VerbInfoDTO verbInfoDTO : verbInfoDTOList) {
boolean isUnlimittedTier = false;
resourceLevelThrottleKey = verbInfoDTO.getRequestKey();
resourceLevelTier = verbInfoDTO.getThrottling();
if (APIConstants.UNLIMITED_TIER.equalsIgnoreCase(resourceLevelTier)) {
isUnlimittedTier = true;
}
// If API level throttle policy is present then it will apply and no resource level policy will apply for it
if (!StringUtils.isEmpty(apiLevelTier) && !APIConstants.UNLIMITED_TIER.equalsIgnoreCase(apiLevelTier)) {
resourceLevelThrottleKey = apiLevelThrottleKey;
apiLevelThrottledTriggered = true;
}
// If verbInfo is present then only we will do resource level throttling
if (isUnlimittedTier && !apiLevelThrottledTriggered) {
// If unlimited tier throttling will not apply at resource level and pass it
if (log.isDebugEnabled()) {
log.debug("Resource level throttling set as unlimited and request will pass " + "resource level");
}
} else {
if (APIConstants.API_POLICY_USER_LEVEL.equalsIgnoreCase(verbInfoDTO.getApplicableLevel())) {
resourceLevelThrottleKey = resourceLevelThrottleKey + "_" + authorizedUser;
policyLevelUserTriggered = true;
}
// If tier is not unlimited only throttling will apply.
List<String> resourceLevelThrottleConditions = new ArrayList<>();
resourceLevelThrottleConditions = verbInfoDTO.getThrottlingConditions();
conditionGroupDTOs = verbInfoDTO.getConditionGroups();
Timer timer1 = getTimer(MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), RESOURCE_THROTTLE));
Timer.Context context1 = timer1.start();
if (getThrottleDataHolder().isAPIThrottled(resourceLevelThrottleKey)) {
if (getThrottleDataHolder().isConditionsAvailable(resourceLevelThrottleKey)) {
Map<String, List<ConditionDto>> conditionDtoMap = getThrottleDataHolder().getConditionDtoMap(resourceLevelThrottleKey);
if (log.isDebugEnabled()) {
log.debug("Conditions available" + conditionDtoMap.size());
}
String throttledCondition = getThrottleConditionEvaluator().getThrottledInCondition(synCtx, authContext, conditionDtoMap);
if (StringUtils.isNotEmpty(throttledCondition)) {
if (log.isDebugEnabled()) {
log.debug("Throttled with Condition :" + throttledCondition);
}
String combinedResourceLevelThrottleKey = resourceLevelThrottleKey + "_" + throttledCondition;
if (log.isDebugEnabled()) {
log.debug("Checking condition : " + combinedResourceLevelThrottleKey);
}
if (getThrottleDataHolder().isThrottled(combinedResourceLevelThrottleKey)) {
if (!apiLevelThrottledTriggered) {
isResourceLevelThrottled = isThrottled = true;
} else {
isApiLevelThrottled = isThrottled = true;
}
long timestamp = getThrottleDataHolder().getThrottleNextAccessTimestamp(combinedResourceLevelThrottleKey);
synCtx.setProperty(APIThrottleConstants.THROTTLED_NEXT_ACCESS_TIMESTAMP, timestamp);
}
}
} else {
if (conditionGroupDTOs != null && conditionGroupDTOs.length > 0) {
if (log.isDebugEnabled()) {
log.debug("Evaluating Conditional Groups for " + apiLevelThrottleKey);
}
// Then we will apply resource level throttling
List<ConditionGroupDTO> applicableConditions = getThrottleConditionEvaluator().getApplicableConditions(synCtx, authContext, conditionGroupDTOs);
for (ConditionGroupDTO conditionGroup : applicableConditions) {
String combinedResourceLevelThrottleKey = resourceLevelThrottleKey + conditionGroup.getConditionGroupId();
if (log.isDebugEnabled()) {
log.debug("Checking condition : " + combinedResourceLevelThrottleKey);
}
if (getThrottleDataHolder().isThrottled(combinedResourceLevelThrottleKey)) {
if (!apiLevelThrottledTriggered) {
isResourceLevelThrottled = isThrottled = true;
} else {
isApiLevelThrottled = isThrottled = true;
}
long timestamp = getThrottleDataHolder().getThrottleNextAccessTimestamp(combinedResourceLevelThrottleKey);
synCtx.setProperty(APIThrottleConstants.THROTTLED_NEXT_ACCESS_TIMESTAMP, timestamp);
break;
}
}
} else {
log.warn("Unable to find throttling information for resource and http verb. Throttling " + "will not be applied");
}
}
}
context1.stop();
if (isThrottled) {
throttledResource = verbInfoDTO;
break;
}
}
}
if (!isApiLevelThrottled) {
Timer timer2 = getTimer(MetricManager.name(APIConstants.METRICS_PREFIX, this.getClass().getSimpleName(), RESOURCE_THROTTLE));
Timer.Context context2 = timer2.start();
// if resource level not throttled then move to subscription level
if (!isResourceLevelThrottled) {
// Subscription Level Throttling
subscriptionLevelThrottleKey = getSubscriptionLevelThrottleKey(subscriptionLevelTier, authContext, apiContext, apiVersion);
isSubscriptionLevelThrottled = getThrottleDataHolder().isThrottled(subscriptionLevelThrottleKey);
if (!isSubscriptionLevelThrottled && authContext.getSpikeArrestLimit() > 0) {
isSubscriptionLevelSpikeThrottled = isSubscriptionLevelSpike(synCtx, subscriptionLevelThrottleKey);
}
// Stop on quata reach
if (!isSubscriptionLevelThrottled && !isSubscriptionLevelSpikeThrottled) {
// Application Level Throttling
isApplicationLevelThrottled = getThrottleDataHolder().isThrottled(applicationLevelThrottleKey);
// if application level not throttled means it does not throttled at any level.
if (!isApplicationLevelThrottled) {
for (VerbInfoDTO verbInfo : verbInfoDTOList) {
resourceLevelThrottleKey = verbInfo.getRequestKey();
resourceLevelTier = verbInfo.getThrottling();
boolean keyTemplatesAvailable = getThrottleDataHolder().isKeyTemplatesPresent();
if (!keyTemplatesAvailable || !validateCustomPolicy(authorizedUser, applicationLevelThrottleKey, resourceLevelThrottleKey, apiLevelThrottleKey, subscriptionLevelThrottleKey, apiContext, apiVersion, subscriberTenantDomain, apiTenantDomain, applicationId, clientIp, getThrottleDataHolder().getKeyTemplateMap(), synCtx)) {
// publish event to Global Policy Server
if (isHardLimitThrottled(synCtx, authContext, apiContext, apiVersion)) {
isThrottled = true;
} else {
ServiceReferenceHolder.getInstance().getThrottleDataPublisher().publishNonThrottledEvent(applicationLevelThrottleKey, applicationLevelTier, apiLevelThrottleKey, apiLevelTier, subscriptionLevelThrottleKey, subscriptionLevelTier, resourceLevelThrottleKey, resourceLevelTier, authorizedUser, apiContext, apiVersion, subscriberTenantDomain, apiTenantDomain, applicationId, synCtx, authContext);
}
} else {
log.debug("Request throttled at custom throttling");
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.CUSTOM_POLICY_LIMIT_EXCEED);
isThrottled = true;
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("Request throttled at application level for throttle key" + applicationLevelThrottleKey);
}
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.APPLICATION_LIMIT_EXCEEDED);
long timestamp = getThrottleDataHolder().getThrottleNextAccessTimestamp(applicationLevelThrottleKey);
synCtx.setProperty(APIThrottleConstants.THROTTLED_NEXT_ACCESS_TIMESTAMP, timestamp);
isThrottled = isApplicationLevelThrottled = true;
}
} else {
if (!stopOnQuotaReach) {
// limit has reached.
if (synCtx.getProperty(APIConstants.API_USAGE_THROTTLE_OUT_PROPERTY_KEY) == null) {
synCtx.setProperty(APIConstants.API_USAGE_THROTTLE_OUT_PROPERTY_KEY, Boolean.TRUE);
}
isThrottled = false;
if (log.isDebugEnabled()) {
log.debug("Request throttled at subscription level for throttle key" + subscriptionLevelThrottleKey + ". But subscription policy " + subscriptionLevelTier + " allows to continue to serve requests");
}
} else {
if (log.isDebugEnabled()) {
log.debug("Request throttled at subscription level for throttle key" + subscriptionLevelThrottleKey);
}
if (!isSubscriptionLevelSpikeThrottled) {
long timestamp = getThrottleDataHolder().getThrottleNextAccessTimestamp(subscriptionLevelThrottleKey);
synCtx.setProperty(APIThrottleConstants.THROTTLED_NEXT_ACCESS_TIMESTAMP, timestamp);
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.API_LIMIT_EXCEEDED);
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.SUBSCRIPTION_LIMIT_EXCEEDED);
}
isThrottled = true;
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("Request throttled at resource level for throttle key" + throttledResource.getRequestKey());
}
// is throttled and resource level throttling
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.RESOURCE_LIMIT_EXCEEDED);
}
context2.stop();
} else {
if (log.isDebugEnabled()) {
log.debug("Request throttled at api level for throttle key" + apiLevelThrottleKey);
if (policyLevelUserTriggered) {
log.debug("Request has throttled out in the user level for the throttle key" + apiLevelThrottleKey);
}
}
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.API_LIMIT_EXCEEDED);
}
}
}
// if we need to publish throttled level or some other information we can do it here. Just before return.
return isThrottled;
}
use of org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO in project carbon-apimgt by wso2.
the class ThrottleConditionEvaluator method isConditionGroupApplicable.
private boolean isConditionGroupApplicable(org.apache.synapse.MessageContext synapseContext, AuthenticationContext authenticationContext, ConditionGroupDTO conditionGroup) {
ConditionDTO[] conditions = conditionGroup.getConditions();
boolean evaluationState = true;
if (conditions.length == 0) {
evaluationState = false;
}
// When multiple conditions have been specified, all the conditions should occur.
for (ConditionDTO condition : conditions) {
evaluationState = evaluationState & isConditionApplicable(synapseContext, authenticationContext, condition);
// If one of the conditions are false, rest will evaluate to false. So no need to check the rest.
if (!evaluationState) {
return false;
}
}
return evaluationState;
}
use of org.wso2.carbon.apimgt.api.dto.ConditionGroupDTO in project carbon-apimgt by wso2.
the class SubscriptionValidationDAO method populateApiPolicyList.
private List<APIPolicy> populateApiPolicyList(ResultSet resultSet) throws SQLException {
List<APIPolicy> apiPolicies = new ArrayList<>();
Map<Integer, APIPolicy> temp = new ConcurrentHashMap<>();
if (resultSet != null) {
while (resultSet.next()) {
int policyId = resultSet.getInt(ThrottlePolicyConstants.COLUMN_POLICY_ID);
APIPolicy apiPolicy = temp.get(policyId);
if (apiPolicy == null) {
apiPolicy = new APIPolicy();
apiPolicy.setId(policyId);
apiPolicy.setName(resultSet.getString(ThrottlePolicyConstants.COLUMN_NAME));
apiPolicy.setQuotaType(resultSet.getString(ThrottlePolicyConstants.COLUMN_DEFAULT_QUOTA_POLICY_TYPE));
apiPolicy.setTenantId(resultSet.getInt(ThrottlePolicyConstants.COLUMN_TENANT_ID));
String tenantDomain = APIUtil.getTenantDomainFromTenantId(apiPolicy.getTenantId());
apiPolicy.setTenantDomain(tenantDomain);
apiPolicy.setApplicableLevel(resultSet.getString(ThrottlePolicyConstants.COLUMN_APPLICABLE_LEVEL));
setCommonProperties(apiPolicy, resultSet);
apiPolicies.add(apiPolicy);
}
APIPolicyConditionGroup apiPolicyConditionGroup = new APIPolicyConditionGroup();
int conditionGroup = resultSet.getInt(ThrottlePolicyConstants.COLUMN_CONDITION_ID);
apiPolicyConditionGroup.setConditionGroupId(conditionGroup);
apiPolicyConditionGroup.setQuotaType(resultSet.getString(ThrottlePolicyConstants.COLUMN_QUOTA_POLICY_TYPE));
apiPolicyConditionGroup.setPolicyId(policyId);
ApiMgtDAO apiMgtDAO = ApiMgtDAO.getInstance();
ConditionGroupDTO conditionGroupDTO = null;
try {
conditionGroupDTO = apiMgtDAO.createConditionGroupDTO(conditionGroup);
} catch (APIManagementException e) {
log.error("Error while processing api policies for policyId : " + policyId, e);
}
ConditionDTO[] conditionDTOS = conditionGroupDTO.getConditions();
apiPolicyConditionGroup.setConditionDTOS(Arrays.asList(conditionDTOS));
setCommonProperties(apiPolicyConditionGroup, resultSet);
apiPolicy.addConditionGroup(apiPolicyConditionGroup);
temp.put(policyId, apiPolicy);
}
}
return apiPolicies;
}
Aggregations