Search in sources :

Example 11 with ThrottleException

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;
}
Also used : ThrottleContext(org.apache.synapse.commons.throttle.core.ThrottleContext) ConfigurationContext(org.apache.axis2.context.ConfigurationContext) AccessInformation(org.apache.synapse.commons.throttle.core.AccessInformation) ThrottleException(org.apache.synapse.commons.throttle.core.ThrottleException) Axis2MessageContext(org.apache.synapse.core.axis2.Axis2MessageContext)

Example 12 with ThrottleException

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);
        }
    }
}
Also used : ThrottleContext(org.apache.synapse.commons.throttle.core.ThrottleContext) SynapseException(org.apache.synapse.SynapseException) ThrottleConfiguration(org.apache.synapse.commons.throttle.core.ThrottleConfiguration) OMElement(org.apache.axiom.om.OMElement) Throttle(org.apache.synapse.commons.throttle.core.Throttle) Entry(org.apache.synapse.config.Entry) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) ThrottleException(org.apache.synapse.commons.throttle.core.ThrottleException) Iterator(java.util.Iterator) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 13 with ThrottleException

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);
    }
}
Also used : ThrottleDataHolder(org.apache.synapse.commons.throttle.core.ThrottleDataHolder) ThrottleException(org.apache.synapse.commons.throttle.core.ThrottleException) SequenceMediator(org.apache.synapse.mediators.base.SequenceMediator) AccessRateController(org.apache.synapse.commons.throttle.core.AccessRateController) ClusteringAgent(org.apache.axis2.clustering.ClusteringAgent) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator)

Example 14 with ThrottleException

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;
}
Also used : ThrottleContext(org.apache.synapse.commons.throttle.core.ThrottleContext) AccessInformation(org.apache.synapse.commons.throttle.core.AccessInformation) ThrottleException(org.apache.synapse.commons.throttle.core.ThrottleException) ThrottleConfiguration(org.apache.synapse.commons.throttle.core.ThrottleConfiguration) Map(java.util.Map)

Aggregations

ThrottleException (org.apache.synapse.commons.throttle.core.ThrottleException)14 ThrottleContext (org.apache.synapse.commons.throttle.core.ThrottleContext)9 Throttle (org.apache.synapse.commons.throttle.core.Throttle)6 ThrottleConfiguration (org.apache.synapse.commons.throttle.core.ThrottleConfiguration)6 AccessInformation (org.apache.synapse.commons.throttle.core.AccessInformation)5 Map (java.util.Map)4 OMElement (org.apache.axiom.om.OMElement)4 ConfigurationContext (org.apache.axis2.context.ConfigurationContext)3 AuthenticationContext (org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext)3 HashMap (java.util.HashMap)2 QName (javax.xml.namespace.QName)2 ConcurrentAccessController (org.apache.synapse.commons.throttle.core.ConcurrentAccessController)2 ThrottleDataHolder (org.apache.synapse.commons.throttle.core.ThrottleDataHolder)2 Entry (org.apache.synapse.config.Entry)2 Axis2MessageContext (org.apache.synapse.core.axis2.Axis2MessageContext)2 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 List (java.util.List)1 TreeMap (java.util.TreeMap)1 ClusteringAgent (org.apache.axis2.clustering.ClusteringAgent)1