# ThrottleEnguageUtils.java

    package org.apache.synapse.commons.throttle.module;

    import org.apache.axis2.AxisFault;
    import org.apache.axis2.context.ConfigurationContext;
    import org.apache.axis2.description.*;
    import org.apache.axis2.engine.AxisConfiguration;
    import org.apache.axis2.util.PolicyUtil;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.neethi.Policy;
    import org.apache.neethi.PolicyEngine;
    import org.apache.neethi.builders.xml.XmlPrimtiveAssertion;
    import org.apache.synapse.commons.throttle.core.ConcurrentAccessController;
    import org.apache.synapse.commons.throttle.core.Throttle;
    import org.apache.synapse.commons.throttle.core.ThrottleConstants;
    import org.apache.synapse.commons.throttle.core.ThrottleException;
    import org.apache.synapse.commons.throttle.core.ThrottleFactory;
    import javax.xml.namespace.QName;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;

    public class ThrottleEnguageUtils {
        private static Log log = LogFactory.getLog(ThrottleEnguageUtils.class.getName());

        public static void enguage(AxisDescription axisDescription, ConfigurationContext configctx,
                                   Throttle defaultThrottle) throws AxisFault {
            String currentServiceName;
            if (axisDescription instanceof AxisService) {
                Throttle throttle = null;
                AxisService currentService = ((AxisService) axisDescription);
                PolicySubject policySubject = currentService.getPolicySubject();
                if (policySubject != null) {
                    try {
                        List policies = new ArrayList(policySubject.getAttachedPolicyComponents());
                        Policy currentPolicy = PolicyUtil.getMergedPolicy(policies, currentService);
                        if (currentPolicy != null) {
                            throttle = ThrottleFactory.createServiceThrottle(currentPolicy);
                            if(throttle == null) {
                                //this is for the scenario when throttle policy is empty rather than
                                // null (eg: removing the throttle policy via policy editor)
                                throttle = defaultThrottle;
                            }
                            //todo - done by isuru, recheck
                        } else {
                            AxisConfiguration axisConfig = configctx.getAxisConfiguration();
                            AxisModule throttleModule = axisConfig.getModule(
                                    ThrottleConstants.THROTTLE_MODULE_NAME);
                            policySubject = throttleModule.getPolicySubject();
                            if (policySubject != null) {
                                currentPolicy = ThrottleEnguageUtils.getThrottlePolicy(
                                        policySubject.getAttachedPolicyComponents());
                                if (currentPolicy != null) {
                                    throttle = ThrottleFactory.createModuleThrottle(currentPolicy);
                                }
                            }
                            //todo - done by isuru
                        }
                    } catch (ThrottleException e) {

                        log.error("Error was occurred when engaging throttle module for" +
                                  " the service :" +
                                  currentService.getName() + e.getMessage());
                        log.info("Throttling will occur using default module policy");
                        throttle = defaultThrottle;
                    }
                    if (throttle != null) {
                        Map throttles =
                                (Map) configctx.getPropertyNonReplicable(
                                        ThrottleConstants.THROTTLES_MAP);
                        if (throttles == null) {
                            throttles = new HashMap();
                            configctx.setNonReplicableProperty(
                                    ThrottleConstants.THROTTLES_MAP, throttles);
                        }
                        String serviceName = currentService.getName();
                        throttle.setId(serviceName);
                        throttles.put(serviceName, throttle);
                        ConcurrentAccessController cac = throttle.getConcurrentAccessController();
                        if (cac != null) {
                            String cacKey = ThrottleConstants.THROTTLE_PROPERTY_PREFIX
                                            + serviceName + ThrottleConstants.CAC_SUFFIX;
                            configctx.setProperty(cacKey, cac);
                        }
                    }
                }
            } else if (axisDescription instanceof AxisOperation) {

                Throttle throttle = null;
                AxisOperation currentOperation = ((AxisOperation) axisDescription);
                AxisService axisService = (AxisService) currentOperation.getParent();
                if (axisService != null) {
                    currentServiceName = axisService.getName();
                    PolicySubject policySubject = currentOperation.getPolicySubject();
                    if (policySubject != null) {
                        try {
                            List policies = new ArrayList(policySubject.getAttachedPolicyComponents());
                            Policy currentPolicy = PolicyUtil.getMergedPolicy(policies,
                                                                              currentOperation);
                            if (currentPolicy != null) {
                                throttle = ThrottleFactory.createOperationThrottle(currentPolicy);
                            }
                        } catch (ThrottleException e) {
                            log.error("Error was occurred when engaging throttle module " +
                                      "for operation : " +
                                      currentOperation.getName() + " in the service :" +
                                      currentServiceName + e.getMessage());
                            log.info("Throttling will occur using default module policy");
                        }

                        // if current throttle is null, use the default throttle
                        if (throttle == null) {
                            throttle = defaultThrottle;
                        }

                        Map throttles = (Map) configctx
                                .getPropertyNonReplicable(ThrottleConstants.THROTTLES_MAP);
                        if (throttles == null) {
                            throttles = new HashMap();
                            configctx.setNonReplicableProperty(ThrottleConstants.THROTTLES_MAP
                                    , throttles);
                        }
                        QName opQName = currentOperation.getName();
                        if (opQName != null) {
                            String opName = opQName.getLocalPart();
                            String key = currentServiceName + opName;
                            throttle.setId(key);
                            throttles.put(key, throttle);
                            ConcurrentAccessController cac =
                                    throttle.getConcurrentAccessController();
                            if (cac != null) {
                                String cacKey = ThrottleConstants.THROTTLE_PROPERTY_PREFIX
                                        + key + ThrottleConstants.CAC_SUFFIX;
                                configctx.setProperty(cacKey, cac);
                            }
                        }
                    }
                }
            }

        }

        //todo - done by isuru, recheck
        private static Policy getThrottlePolicy(Collection components) throws AxisFault {
            QName assertionName;
            //Finds the policy for throttling
            Iterator i = components.iterator();
            while (i.hasNext()) {
                Object comp = i.next();
    //        }
    //        for (Object comp : components) {
                Policy policy = (Policy) comp;
                for (Iterator iterator = policy.getAlternatives();
                     iterator.hasNext();) {
                    Object object = iterator.next();
                    if (object instanceof List) {
                        List list = (List) object;
                        Iterator j = list.iterator();
                        while (j.hasNext()) {
    //                    for (Object assertObj : list) {
                            Object assertObj = j.next();
                            if (assertObj instanceof XmlPrimtiveAssertion) {
                                XmlPrimtiveAssertion primitiveAssertion = (XmlPrimtiveAssertion)
                                        assertObj;
                                assertionName = primitiveAssertion.getName();
                                if (assertionName.equals(ThrottleConstants
                                        .SERVICE_THROTTLE_ASSERTION_QNAME) || assertionName
                                        .equals(ThrottleConstants.MODULE_THROTTLE_ASSERTION_QNAME)) {
                                    if (log.isDebugEnabled()) {
                                        log.debug("Existing ThrottleAssertion found");
                                    }
                                    return policy;
                                }
                            }
                        }
                    }
                }
            }
            return null;
        }

        /**
         * Checks whether the given service group is a special service
         *
         * @param axisServiceGroup - ServiceGroup instance
         * @return - true if this is a filtered service
         */
        public static boolean isFilteredOutService(AxisServiceGroup axisServiceGroup) {
            String adminParamValue = (String) axisServiceGroup
                    .getParameterValue(ThrottleConstants.ADMIN_SERVICE_PARAM_NAME);
            String hiddenParamValue = (String) axisServiceGroup
                    .getParameterValue(ThrottleConstants.HIDDEN_SERVICE_PARAM_NAME);
            String dynamicParamValue = (String) axisServiceGroup
                    .getParameterValue(ThrottleConstants.DYNAMIC_SERVICE_PARAM_NAME);
            if (adminParamValue != null && adminParamValue.length() != 0) {
                if (Boolean.parseBoolean(adminParamValue.trim())) {
                    return true;
                }
            } else if (hiddenParamValue != null && hiddenParamValue.length() != 0) {
                if (Boolean.parseBoolean(hiddenParamValue.trim())) {
                    return true;
                }
            } else if (dynamicParamValue != null && dynamicParamValue.length() != 0){
                if(Boolean.parseBoolean(dynamicParamValue.trim())) {
                    return true;
                }
            }
            return false;
        }

        /**
         * An external policy can be configured using a parameter in the axis2.xml which points to the
         * absolute path of the policy file. This method reads the policy file and creates a
         * PolicySubject.
         *
         * @param axisConfig - AxisConfiguration instance
         * @return - PolicySubject instance if the file found. Otherwise null..
         */
        public static PolicySubject readExternalGlobalPolicy(AxisConfiguration axisConfig) {
            PolicySubject extPolicySubject = null;
            // read the global throttle parameter from axisConfig
            Parameter globalThrottlePolicyParam = axisConfig
                    .getParameter(ThrottleConstants.GLOBAL_THROTTLE_PATH_PARAM);
            if (globalThrottlePolicyParam != null &&
                    !"".equals(globalThrottlePolicyParam.getValue())) {
                // If the path found, try to read the file
                String policyPath = (String) globalThrottlePolicyParam.getValue();
                File policyFile = new File(policyPath);
                if (policyFile.exists()) {
                    try {
                        // If the file exists, try to build the policy
                        Policy globalPolicy = PolicyEngine.getPolicy(new FileInputStream(policyFile));
                        extPolicySubject = new PolicySubject();
                        extPolicySubject.attachPolicy(globalPolicy);
                    } catch (FileNotFoundException e) {
                        log.error("Error while reading global policy file..", e);
                    }
                }
            }
            return extPolicySubject;
        }

    }