<commit_before>/*
*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.apimgt.gateway.handlers.throttling;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.apache.neethi.PolicyEngine;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.commons.throttle.core.*;
import org.apache.synapse.commons.throttle.core.factory.ThrottleContextFactory;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.rest.AbstractHandler;
import org.apache.synapse.rest.RESTConstants;
import org.apache.synapse.transport.passthru.PassThroughConstants;
import org.apache.synapse.transport.passthru.util.RelayUtils;
import org.wso2.carbon.apimgt.gateway.handlers.Utils;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityUtils;
import org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext;
import org.wso2.carbon.apimgt.gateway.internal.ServiceReferenceHolder;
import org.wso2.carbon.apimgt.gateway.throttling.publisher.ThrottleDataPublisher;
import org.wso2.carbon.apimgt.gateway.utils.GatewayUtils;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO;

import org.wso2.carbon.databridge.agent.DataPublisher;

import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

import javax.xml.stream.XMLStreamException;

import java.util.List;
import java.util.Map;

/**
 * This class is Handling new throttling check. This class will use inside each API as throttle handler.
 * It will fetch some of data from incoming message and use them to take throttling decisions.
 * To execute this handler requests must go through authentication handler and auth context should be present
 * in message context.
 */
public class ThrottleHandler extends AbstractHandler {

    private static final Log log = LogFactory.getLog(ThrottleHandler.class);
    private static final String HEADER_X_FORWARDED_FOR = "X-FORWARDED-FOR";
    private volatile Throttle throttle;

    private static volatile DataPublisher dataPublisher = null;

    private static volatile ThrottleDataPublisher throttleDataPublisher = null;

    private String policyKeyApplication = null;

    private boolean subscriptionLevelSpikeArrestEnabled;
    /**
     * The key for getting the throttling policy - key refers to a/an [registry] Resource entry
     */
    private String policyKeyResource = null;
    /**
     * The key for getting the throttling policy - key refers to a/an [registry] entry
     */
    private String policyKey = null;
    /**
     * The concurrent access control group id
     */
    private String id;
    /**
     * Version number of the throttle policy
     */

    /**
     * Created throttle handler object.
     */
    private String sandboxUnitTime = "1000";

    private String productionUnitTime = "60000";

    private String sandboxMaxCount;

    private String maxCount;
    private RoleBasedAccessRateController roleBasedAccessController;

    //Throttle Handler rename
    public ThrottleHandler() {
        subscriptionLevelSpikeArrestEnabled = ServiceReferenceHolder.getInstance().getThrottleProperties()
                .isEnabledSubscriptionLevelSpikeArrest();
        if (log.isDebugEnabled()) {
            log.debug("Throttle Handler initialized");
        }
        this.roleBasedAccessController = new RoleBasedAccessRateController();

        /**
         * This method will initialize data publisher and this data publisher will be used to push events to central policy
         * server.
         */
        if (throttleDataPublisher == null) {
            // The publisher initializes in the first request only
            synchronized (this) {
                throttleDataPublisher = new ThrottleDataPublisher();
            }
        }
    }

    /**
     * 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) {

        //Throttle Keys
        String applicationLevelThrottleKey;
        String subscriptionLevelThrottleKey;
        String resourceLevelThrottleKey="";
        String apiLevelThrottleKey = "";

        //Throttle Tiers
        String applicationLevelTier;
        String subscriptionLevelTier;
        String resourceLevelTier ="";
        String apiLevelTier;

        //Other Relevant parameters
        AuthenticationContext authContext = APISecurityUtils.getAuthenticationContext(synCtx);
        String authorizedUser;

        //Throttled decisions
        boolean isThrottled = false;
        boolean isResourceLevelThrottled = false;
        boolean isApplicationLevelThrottled = false;
        boolean isSubscriptionLevelThrottled = false;
        boolean isApiLevelThrottled = false;
        boolean isBlockedRequest;
        String ipLevelBlockingKey = null;
        String appLevelBlockingKey = null;
        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 : "";
        List<String> resourceLevelThrottleConditions;


        //If Authz context is not null only we can proceed with throttling
        if (authContext != null) {
            authorizedUser = authContext.getUsername();
            applicationLevelThrottleKey = authContext.getApplicationId() + ":" + authorizedUser;
            //Following throttle data list can be use to hold throttle data and api level throttle key
            //should be its first element.
            //if ((authContext.getThrottlingDataList() != null) && (authContext.getThrottlingDataList().get(0) != null)) {
                apiLevelThrottleKey = apiContext + ":" +apiVersion; //authContext.getApiTier();
                //Check if request is blocked. If request is blocked then will not proceed further and
                //inform to client.
                //TODO handle blocked and throttled requests separately.

                ipLevelBlockingKey = MultitenantUtils.getTenantDomain(authorizedUser) + ":" + getClientIp(synCtx);
                appLevelBlockingKey = authContext.getSubscriber() + ":" + authContext.getApplicationName();
            //}
            isBlockedRequest = false;
            // isBlockedRequest = ServiceReferenceHolder.getInstance().getThrottleDataHolder().isRequestBlocked(
            //       apiContext, appLevelBlockingKey, authorizedUser,ipLevelBlockingKey);<commit_msg>commiting block request<commit_after>/*
*  Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.apimgt.gateway.handlers.throttling;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.apache.neethi.PolicyEngine;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.commons.throttle.core.*;
import org.apache.synapse.commons.throttle.core.factory.ThrottleContextFactory;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.rest.AbstractHandler;
import org.apache.synapse.rest.RESTConstants;
import org.apache.synapse.transport.passthru.PassThroughConstants;
import org.apache.synapse.transport.passthru.util.RelayUtils;
import org.wso2.carbon.apimgt.gateway.handlers.Utils;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityUtils;
import org.wso2.carbon.apimgt.gateway.handlers.security.AuthenticationContext;
import org.wso2.carbon.apimgt.gateway.internal.ServiceReferenceHolder;
import org.wso2.carbon.apimgt.gateway.throttling.publisher.ThrottleDataPublisher;
import org.wso2.carbon.apimgt.gateway.utils.GatewayUtils;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dto.VerbInfoDTO;

import org.wso2.carbon.databridge.agent.DataPublisher;

import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

import javax.xml.stream.XMLStreamException;

import java.util.List;
import java.util.Map;

/**
 * This class is Handling new throttling check. This class will use inside each API as throttle handler.
 * It will fetch some of data from incoming message and use them to take throttling decisions.
 * To execute this handler requests must go through authentication handler and auth context should be present
 * in message context.
 */
public class ThrottleHandler extends AbstractHandler {

    private static final Log log = LogFactory.getLog(ThrottleHandler.class);
    private static final String HEADER_X_FORWARDED_FOR = "X-FORWARDED-FOR";
    private volatile Throttle throttle;

    private static volatile DataPublisher dataPublisher = null;

    private static volatile ThrottleDataPublisher throttleDataPublisher = null;

    private String policyKeyApplication = null;

    private boolean subscriptionLevelSpikeArrestEnabled;
    /**
     * The key for getting the throttling policy - key refers to a/an [registry] Resource entry
     */
    private String policyKeyResource = null;
    /**
     * The key for getting the throttling policy - key refers to a/an [registry] entry
     */
    private String policyKey = null;
    /**
     * The concurrent access control group id
     */
    private String id;
    /**
     * Version number of the throttle policy
     */

    /**
     * Created throttle handler object.
     */
    private String sandboxUnitTime = "1000";

    private String productionUnitTime = "60000";

    private String sandboxMaxCount;

    private String maxCount;
    private RoleBasedAccessRateController roleBasedAccessController;

    //Throttle Handler rename
    public ThrottleHandler() {
        subscriptionLevelSpikeArrestEnabled = ServiceReferenceHolder.getInstance().getThrottleProperties()
                .isEnabledSubscriptionLevelSpikeArrest();
        if (log.isDebugEnabled()) {
            log.debug("Throttle Handler initialized");
        }
        this.roleBasedAccessController = new RoleBasedAccessRateController();

        /**
         * This method will initialize data publisher and this data publisher will be used to push events to central policy
         * server.
         */
        if (throttleDataPublisher == null) {
            // The publisher initializes in the first request only
            synchronized (this) {
                throttleDataPublisher = new ThrottleDataPublisher();
            }
        }
    }

    /**
     * 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) {

        //Throttle Keys
        String applicationLevelThrottleKey;
        String subscriptionLevelThrottleKey;
        String resourceLevelThrottleKey="";
        String apiLevelThrottleKey = "";

        //Throttle Tiers
        String applicationLevelTier;
        String subscriptionLevelTier;
        String resourceLevelTier ="";
        String apiLevelTier;

        //Other Relevant parameters
        AuthenticationContext authContext = APISecurityUtils.getAuthenticationContext(synCtx);
        String authorizedUser;

        //Throttled decisions
        boolean isThrottled = false;
        boolean isResourceLevelThrottled = false;
        boolean isApplicationLevelThrottled = false;
        boolean isSubscriptionLevelThrottled = false;
        boolean isApiLevelThrottled = false;
        boolean isBlockedRequest;
        String ipLevelBlockingKey = null;
        String appLevelBlockingKey = null;
        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 : "";
        List<String> resourceLevelThrottleConditions;


        //If Authz context is not null only we can proceed with throttling
        if (authContext != null) {
            authorizedUser = authContext.getUsername();
            applicationLevelThrottleKey = authContext.getApplicationId() + ":" + authorizedUser;
            //Following throttle data list can be use to hold throttle data and api level throttle key
            //should be its first element.
            //if ((authContext.getThrottlingDataList() != null) && (authContext.getThrottlingDataList().get(0) != null)) {
                apiLevelThrottleKey = apiContext + ":" +apiVersion; //authContext.getApiTier();
                //Check if request is blocked. If request is blocked then will not proceed further and
                //inform to client.
                //TODO handle blocked and throttled requests separately.

                ipLevelBlockingKey = MultitenantUtils.getTenantDomain(authorizedUser) + ":" + getClientIp(synCtx);
                appLevelBlockingKey = authContext.getSubscriber() + ":" + authContext.getApplicationName();
            //}
            isBlockedRequest = ServiceReferenceHolder.getInstance().getThrottleDataHolder().isRequestBlocked(
                   apiContext, appLevelBlockingKey, authorizedUser,ipLevelBlockingKey);
{'fraction_non_alphanumeric': 0.0793960364894621, 'fraction_numerical': 0.004529726329034287, 'mean_word_length': 3.3826854149434795, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2377406', 'n_tokens_mistral': 4391, 'n_tokens_neox': 4249, 'n_words': 1165}