use of org.apache.synapse.commons.throttle.core.ThrottleException in project carbon-apimgt by wso2.
the class ThrottleHandler method isHardLimitThrottled.
private boolean isHardLimitThrottled(MessageContext synCtx, AuthenticationContext authContext, String apiContext, String apiVersion) {
boolean status = false;
if (StringUtils.isNotEmpty(sandboxMaxCount) || StringUtils.isNotEmpty(productionMaxCount)) {
ThrottleContext hardThrottleContext = throttle.getThrottleContext(APIThrottleConstants.HARD_THROTTLING_CONFIGURATION);
try {
org.apache.axis2.context.MessageContext axis2MC = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
ConfigurationContext cc = axis2MC.getConfigurationContext();
apiContext = apiContext != null ? apiContext : "";
apiVersion = apiVersion != null ? apiVersion : "";
if (hardThrottleContext != null && authContext.getKeyType() != null) {
String throttleKey = apiContext + ':' + apiVersion + ':' + authContext.getKeyType();
AccessInformation info = null;
hardThrottleContext.setConfigurationContext(cc);
if (APIConstants.API_KEY_TYPE_PRODUCTION.equals(authContext.getKeyType())) {
hardThrottleContext.setThrottleId(id + APIThrottleConstants.PRODUCTION_HARD_LIMIT);
info = getAccessInformation(hardThrottleContext, throttleKey, APIThrottleConstants.PRODUCTION_HARD_LIMIT);
} else if (APIConstants.API_KEY_TYPE_SANDBOX.equals(authContext.getKeyType())) {
hardThrottleContext.setThrottleId(id + APIThrottleConstants.SANDBOX_HARD_LIMIT);
info = getAccessInformation(hardThrottleContext, throttleKey, APIThrottleConstants.SANDBOX_HARD_LIMIT);
}
if (log.isDebugEnabled()) {
log.debug("Throttle by hard limit " + throttleKey);
log.debug("Allowed = " + (info != null ? info.isAccessAllowed() : "false"));
}
if (info != null && !info.isAccessAllowed()) {
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.HARD_LIMIT_EXCEEDED);
log.info("Hard Throttling limit exceeded.");
status = true;
}
}
} catch (ThrottleException e) {
log.warn("Exception occurred while performing role " + "based throttling", e);
synCtx.setProperty(APIThrottleConstants.THROTTLED_OUT_REASON, APIThrottleConstants.HARD_LIMIT_EXCEEDED);
status = true;
}
}
return status;
}
use of org.apache.synapse.commons.throttle.core.ThrottleException in project carbon-apimgt by wso2.
the class APIThrottleHandler method initThrottle.
private void initThrottle(MessageContext synCtx, ConfigurationContext cc) {
if (policyKey == null) {
throw new SynapseException("Throttle policy unspecified for the API");
}
Entry entry = synCtx.getConfiguration().getEntryDefinition(policyKey);
if (entry == null) {
handleException("Cannot find throttling policy using key: " + policyKey);
}
Object entryValue = null;
boolean reCreate = false;
if (entry.isDynamic()) {
if ((!entry.isCached()) || (entry.isExpired()) || throttle == null) {
entryValue = synCtx.getEntry(this.policyKey);
if (this.version != entry.getVersion()) {
// if there is a change, it will recreate
reCreate = true;
}
}
} else if (this.throttle == null) {
entryValue = synCtx.getEntry(this.policyKey);
}
if (reCreate || throttle == null) {
if (entryValue == null || !(entryValue instanceof OMElement)) {
handleException("Unable to load throttling policy using key: " + policyKey);
}
version = entry.getVersion();
// is not null and throttle is not null , then must reload.
if (isClusteringEnable && concurrentAccessController != null && throttle != null) {
// set null ,
concurrentAccessController = null;
// because need to reload
}
try {
// Creates the throttle from the policy
synchronized (this) {
if (throttle == null || reCreate) {
OMElement policyOMElement = (OMElement) entryValue;
throttle = ThrottleFactory.createMediatorThrottle(PolicyEngine.getPolicy(policyOMElement));
// load the resource level tiers
Object resEntryValue = synCtx.getEntry(this.policyKeyResource);
if (resEntryValue == null || !(resEntryValue instanceof OMElement)) {
handleException("Unable to load throttling policy using key: " + this.policyKeyResource);
}
// create throttle for the resource level
Throttle resThrottle = ThrottleFactory.createMediatorThrottle(PolicyEngine.getPolicy((OMElement) resEntryValue));
// get the throttle Context for the resource level
ThrottleContext throttleContext = resThrottle.getThrottleContext(ThrottleConstants.ROLE_BASED_THROTTLE_KEY);
if (throttleContext != null) {
ThrottleConfiguration throttleConfiguration = throttleContext.getThrottleConfiguration();
ThrottleContext resourceContext = createThrottleContext(throttleConfiguration);
throttle.addThrottleContext(RESOURCE_THROTTLE_KEY, resourceContext);
}
OMElement hardThrottlingPolicy = createHardThrottlingPolicy();
if (hardThrottlingPolicy != null) {
Throttle tempThrottle = ThrottleFactory.createMediatorThrottle(PolicyEngine.getPolicy(hardThrottlingPolicy));
ThrottleConfiguration newThrottleConfig = tempThrottle.getThrottleConfiguration(ThrottleConstants.ROLE_BASED_THROTTLE_KEY);
ThrottleContext hardThrottling = createThrottleContext(newThrottleConfig);
throttle.addThrottleContext(APIThrottleConstants.HARD_THROTTLING_CONFIGURATION, hardThrottling);
}
// We check to what tiers allows to continue on quota reached.
OMElement assertionElement = policyOMElement.getFirstChildWithName(APIConstants.ASSERTION_ELEMENT);
Iterator tierElementIterator = assertionElement.getChildrenWithName(APIConstants.POLICY_ELEMENT);
if (continueOnLimitReachedMap == null) {
continueOnLimitReachedMap = new HashMap<String, Boolean>();
} else if (!continueOnLimitReachedMap.isEmpty()) {
continueOnLimitReachedMap.clear();
}
while (tierElementIterator.hasNext()) {
OMElement tierElement = (OMElement) tierElementIterator.next();
String tierName = tierElement.getFirstChildWithName(APIConstants.THROTTLE_ID_ELEMENT).getText();
try {
Map<String, Object> tierAttributes = APIDescriptionGenUtil.getTierAttributes(tierElement);
for (Map.Entry<String, Object> tierEntry : tierAttributes.entrySet()) {
if (APIConstants.THROTTLE_TIER_QUOTA_ACTION_ATTRIBUTE.equalsIgnoreCase(tierEntry.getKey())) {
// We are putting the inverse value of the attribute to the map.
// The reason is that we have the value whether to stop when quota reached.
// The map contains the inverse of this, whether to continue when quota reached.
continueOnLimitReachedMap.put(tierName, !Boolean.parseBoolean((String) tierEntry.getValue()));
break;
}
}
} catch (APIManagementException e) {
// We do not throw the exception. If there is any exception, then the others can
// still function without any issue.
log.warn("Unable to get the action for quota reached of tier : " + tierName);
}
}
}
}
// then must re-initiates
if (throttle != null && (concurrentAccessController == null || !isClusteringEnable)) {
concurrentAccessController = throttle.getConcurrentAccessController();
if (concurrentAccessController != null) {
cc.setProperty(key, concurrentAccessController);
} else {
cc.removeProperty(key);
}
}
} catch (ThrottleException e) {
handleException("Error processing the throttling policy", e);
}
}
}
use of org.apache.synapse.commons.throttle.core.ThrottleException in project wso2-synapse by wso2.
the class ThrottleMediator method init.
public void init(SynapseEnvironment se) {
if (onAcceptMediator instanceof ManagedLifecycle) {
((ManagedLifecycle) onAcceptMediator).init(se);
} else if (onAcceptSeqKey != null) {
SequenceMediator onAcceptSeq = (SequenceMediator) se.getSynapseConfiguration().getSequence(onAcceptSeqKey);
if (onAcceptSeq == null || onAcceptSeq.isDynamic()) {
se.addUnavailableArtifactRef(onAcceptSeqKey);
}
}
if (onRejectMediator instanceof ManagedLifecycle) {
((ManagedLifecycle) onRejectMediator).init(se);
} else if (onRejectSeqKey != null) {
SequenceMediator onRejectSeq = (SequenceMediator) se.getSynapseConfiguration().getSequence(onRejectSeqKey);
if (onRejectSeq == null || onRejectSeq.isDynamic()) {
se.addUnavailableArtifactRef(onRejectSeqKey);
}
}
// reference to axis2 configuration context
configContext = ((Axis2SynapseEnvironment) se).getAxis2ConfigurationContext();
// throttling data holder initialization of
// runtime throttle data eg :- throttle contexts
dataHolder = (ThrottleDataHolder) configContext.getProperty(ThrottleConstants.THROTTLE_INFO_KEY);
if (dataHolder == null) {
log.debug("Data holder not present in current Configuration Context");
synchronized (configContext) {
dataHolder = (ThrottleDataHolder) configContext.getProperty(ThrottleConstants.THROTTLE_INFO_KEY);
if (dataHolder == null) {
dataHolder = new ThrottleDataHolder();
configContext.setNonReplicableProperty(ThrottleConstants.THROTTLE_INFO_KEY, dataHolder);
}
}
}
// initializes whether clustering is enabled an Env. level
ClusteringAgent clusteringAgent = configContext.getAxisConfiguration().getClusteringAgent();
if (clusteringAgent != null) {
isClusteringEnable = true;
}
// static policy initialization
if (inLinePolicy != null) {
log.debug("Initializing using static throttling policy : " + inLinePolicy);
try {
throttle = ThrottleFactory.createMediatorThrottle(PolicyEngine.getPolicy(inLinePolicy));
if (throttle != null && concurrentAccessController == null) {
concurrentAccessController = throttle.getConcurrentAccessController();
if (concurrentAccessController != null) {
dataHolder.setConcurrentAccessController(key, concurrentAccessController);
}
}
} catch (ThrottleException e) {
handleException("Error processing the throttling policy", e, null);
}
}
// access rate controller initialization
accessControler = new AccessRateController();
// replicator for global concurrent state maintenance
if (isClusteringEnable) {
concurrentAccessReplicator = new ConcurrentAccessReplicator(configContext);
}
}
use of org.apache.synapse.commons.throttle.core.ThrottleException in project wso2-synapse by wso2.
the class ThrottleMediator method doThrottleByAccessRate.
/**
* Helper method that handles the access-rate based throttling
*
* @param synCtx MessageContext(Synapse)
* @param axisMC MessageContext(Axis2)
* @param cc ConfigurationContext
* @param synLog the Synapse log to use
* @return ue if the caller can access ,o.w. false
*/
private boolean doThrottleByAccessRate(MessageContext synCtx, org.apache.axis2.context.MessageContext axisMC, ConfigurationContext cc, SynapseLog synLog) {
String callerId = null;
boolean canAccess = true;
// remote ip of the caller
String remoteIP = (String) axisMC.getPropertyNonReplicable(org.apache.axis2.context.MessageContext.REMOTE_ADDR);
// domain name of the caller
String domainName = (String) axisMC.getPropertyNonReplicable(NhttpConstants.REMOTE_HOST);
Map headers = (Map) axisMC.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
if (headers != null) {
String xForwardHeader = (String) headers.get(NhttpConstants.HEADER_X_FORWARDED_FOR);
String xForwardHost = (String) headers.get(NhttpConstants.HEADER_X_FORWARDED_HOST);
remoteIP = (xForwardHeader != null) ? xForwardHeader : remoteIP;
domainName = (xForwardHost != null) ? xForwardHost : domainName;
}
// Using a unique key to identify each api, proxy and inbound endpoint
String uniqueKey;
Object artifactName = synCtx.getProperty(SynapseConstants.ARTIFACT_NAME);
if (artifactName != null && !artifactName.toString().isEmpty()) {
uniqueKey = id + synCtx.getProperty(SynapseConstants.ARTIFACT_NAME);
} else {
uniqueKey = id;
}
uniqueKey = uniqueKey.concat(SYMBOL_UNDERSCORE);
// this domain name ,then throttling will occur according to that configuration
if (domainName != null) {
// do the domain based throttling
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The Domain Name of the caller is :" + domainName);
}
// loads the DomainBasedThrottleContext
ThrottleContext context = throttle.getThrottleContext(ThrottleConstants.DOMAIN_BASED_THROTTLE_KEY);
if (context != null) {
// loads the DomainBasedThrottleConfiguration
ThrottleConfiguration config = context.getThrottleConfiguration();
if (config != null) {
// checks the availability of a policy configuration for this domain name
callerId = config.getConfigurationKeyOfCaller(domainName);
if (callerId != null) {
// If this is a clustered env.
if (isClusteringEnable) {
context.setConfigurationContext(cc);
context.setThrottleId(uniqueKey + callerId);
}
try {
// Checks for access state
AccessInformation accessInformation = accessControler.canAccess(context, uniqueKey + callerId, ThrottleConstants.DOMAIN_BASE);
canAccess = accessInformation.isAccessAllowed();
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Access " + (canAccess ? "allowed" : "denied") + " for Domain Name : " + domainName);
}
// if the access has denied by rate based throttling
if (!canAccess && concurrentAccessController != null) {
concurrentAccessController.incrementAndGet();
if (isClusteringEnable) {
dataHolder.setConcurrentAccessController(key, concurrentAccessController);
}
}
} catch (ThrottleException e) {
handleException("Error occurred during throttling", e, synCtx);
}
}
}
}
} else {
synLog.traceOrDebug("The Domain name of the caller cannot be found");
}
// therefore trying to find a configuration policy based on remote caller ip
if (callerId == null) {
// do the IP-based throttling
if (remoteIP == null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The IP address of the caller cannot be found");
}
canAccess = true;
} else {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The IP Address of the caller is :" + remoteIP);
}
try {
// Loads the IPBasedThrottleContext
ThrottleContext context = throttle.getThrottleContext(ThrottleConstants.IP_BASED_THROTTLE_KEY);
if (context != null) {
// Loads the IPBasedThrottleConfiguration
ThrottleConfiguration config = context.getThrottleConfiguration();
if (config != null) {
// Checks the availability of a policy configuration for this ip
callerId = config.getConfigurationKeyOfCaller(remoteIP);
if (callerId != null) {
// For clustered env.
if (isClusteringEnable) {
context.setConfigurationContext(cc);
context.setThrottleId(uniqueKey + callerId);
}
// Checks access state
AccessInformation accessInformation = accessControler.canAccess(context, uniqueKey + callerId, ThrottleConstants.IP_BASE);
canAccess = accessInformation.isAccessAllowed();
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Access " + (canAccess ? "allowed" : "denied") + " for IP : " + remoteIP);
}
// if the access has denied by rate based throttling
if (!canAccess && concurrentAccessController != null) {
concurrentAccessController.incrementAndGet();
if (isClusteringEnable) {
dataHolder.setConcurrentAccessController(key, concurrentAccessController);
}
}
}
}
}
} catch (ThrottleException e) {
handleException("Error occurred during throttling", e, synCtx);
}
}
}
return canAccess;
}
Aggregations