Skip to content

Instantly share code, notes, and snippets.

@kianting
Created June 26, 2018 04:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kianting/548bb861025637cd9575fa65075fe0d8 to your computer and use it in GitHub Desktop.
Save kianting/548bb861025637cd9575fa65075fe0d8 to your computer and use it in GitHub Desktop.
This is mule 3.9 rate throttling policy, it includes an after tag to enforce actual updating of the message store.
<?xml version="1.0" encoding="UTF-8"?>
<policy id="67891011"
policyName="RateLimitingPolicy"
xmlns="http://www.mulesoft.org/schema/mule/policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mule="http://www.mulesoft.org/schema/mule/core"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:api-platform-gw="http://www.mulesoft.org/schema/mule/api-platform-gw"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/policy http://www.mulesoft.org/schema/mule/policy/current/mule-policy.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/api-platform-gw http://www.mulesoft.org/schema/mule/api-platform-gw/current/mule-api-platform-gw.xsd">
<spring:bean id="cacheEmailRateLimiting" class="net.sf.ehcache.Cache" init-method="initialise">
<spring:constructor-arg name="name" value="cacheEmailRateLimiting" />
<spring:constructor-arg name="maxElementsInMemory" value="1" />
<spring:constructor-arg name="overflowToDisk" value="false" />
<spring:constructor-arg name="eternal" value="false" />
<spring:constructor-arg name="timeToLiveSeconds" value="60" />
<spring:constructor-arg name="timeToIdleSeconds" value="5" />
</spring:bean>
<mule:processor-chain name="notAllowedToPass">
<mule:set-property propertyName="http.status" value="403"/>
<mule:set-property propertyName="Content-Type" value="application/json"/>
<mule:logger message="Calls Rejected as limit is reached" level="DEBUG"/>
<mule:set-payload value="{&quot;message&quot;: &quot;maximum calls reached, subsequent calls would be rejected.&quot;}" />
</mule:processor-chain>
<before>
<scripting:component>
<scripting:script engine="Groovy"><![CDATA[
import org.mule.api.config.MuleProperties;
import java.util.Map;
import net.sf.ehcache.Element;
import org.mule.api.transport.PropertyScope;
import com.mulesoft.gateway.policies.PoliciesConstants;
def maximumRequest = 5
def cache = muleContext.getRegistry().get("cacheEmailRateLimiting")
def key = "totalHits"
def method = message.getInboundProperty("http.method")
//we need to do this in order to avoid reporting a policy violation
message.removeProperty(PoliciesConstants.POLICY_ID_FLOW_VARIABLE_NAME, PropertyScope.INVOCATION)
message.removeProperty(PoliciesConstants.POLICY_NAME_FLOW_VARIABLE_NAME, PropertyScope.INVOCATION)
//message.setInvocationProperty("cache", cache)
message.setInvocationProperty("isAllowedToPass", true)
message.setInvocationProperty("cachePolicyRequestCachingKey", key)
def cacheEntry = cache.get(key);
if (cacheEntry != null)
{
def totalHits = cacheEntry.getObjectValue()
totalHits = (totalHits as Integer) + 1
if ((totalHits as Integer) > maximumRequest){
sleep(60000)
//message.setInvocationProperty("isAllowedToPass", false)
}
}
return payload
]]></scripting:script>
</scripting:component>
<mule:message-filter onUnaccepted="notAllowedToPass">
<mule:expression-filter expression="#[flowVars['isAllowedToPass']]"/>
</mule:message-filter>
</before>
<after>
<scripting:component>
<scripting:script engine="Groovy"><![CDATA[
import org.mule.api.config.MuleProperties
import org.mule.api.store.ObjectAlreadyExistsException
import java.util.Map
import java.util.HashMap
import net.sf.ehcache.Element
import org.mule.transport.NullPayload
def cache = muleContext.getRegistry().get("cacheEmailRateLimiting")
def key = message.getInvocationProperty("cachePolicyRequestCachingKey")
def cacheEntry = cache.get(key);
if (cacheEntry != null)
{
def totalHits = cacheEntry.getObjectValue()
totalHits = (totalHits as Integer) + 1
cache.put(new Element(key, totalHits))
}else{
cache.put(new Element(key, "1" as Integer))
}
return payload
]]></scripting:script>
</scripting:component>
</after>
<!-- Pointcut defines where a policy implements. -->
<pointcut>
<resource uriTemplateRegex="/test.*" />
<resource methodRegex="GET" />
</pointcut>
</policy>
@kianting
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment