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;
}
}