Skip to content

Overview

Concepts and Principles

Development

Overview

IDEs

API Explorer

Releases

Release Notes

TORO Integrate

Coder Studio

Coder Cloud

Bug Reports

Search

Throttling Requests

Throttling is the process of regulating a certain flow - in this case, HTTP requests. TORO Integrate allows developers to control the throughput of incoming HTTP requests based on configured rules.

Consider the following rule configuration:

1
2
3
4
5
limitPerMinute    = 5
dateType          = ROLLING
userType          = INTEGRATE_USERS
groups            = Lannister
urlPattern        = /api/lannister/welcome

When enabled, users under the group Lannister are limited to 5 requests per minute inbound to /api/lannister/welcome. When the limit is reached, the server responds with:

1
2
3
4
5
{
    "result": "ERROR",
    "apiErrorCode": -1,
    "message": "Limit exceeded (2): Invokes per Minute: 5"
}
1
2
3
4
5
<APIException>
    <result>ERROR</result>
    <apiErrorCode>-1</apiErrorCode>
    <message>Limit exceeded (2): Invokes per Minute: 5</message>
</APIException>

Note

The value 2 in the message simply corresponds to the ID of the rule that blocked the request.

Conditional Throttling

When configuring rules, there is a field called service. This corresponds to the service that needs to be invoked when a request is matched. Using this facility, we can implement custom logic for accepting and rejecting HTTP requests.

Similar to endpoints, variables are provided in the service's execution context:

Name Type Description
monitorRule MonitorRule The rule that matched the request
user java.security.Principal The user associated to the current request; null if anonymous
invokeCount InvokeCount Contains statistics such as: invokesLastMonth, invokesLastWeek, invokesLastDay, invokesLastHour, and invokesLastMinute
invokeCost InvokeCost Contains statistics such as: costLastMonth, costLastWeek, costYesterday, costLastHour, and costLastMinute
invokeSummary InvokeSummary An object that encapsulates both invokeCount and invokeCost
packageName String The name of the Integrate Package where the target service resides
serviceName String The name of the service that will be executed if the HTTP request is accepted
serviceGroupName String The name of group whose servce will be executed if the HTTP request is accepted
serviceMeta ServiceMeta An object that encapsulates serviceName and serviceGroupName
url String The URL of the request
request HttpServletRequest The HTTP request object
response HttpServletResponse The HTTP response object

You can use these variables at runtime to determine whether to accept or reject a request. Some reasons could be:

  • Only 1,000 requests per hour between 9:00 am - 5:00 pm
  • No requests once the monthly costs has reached 1,000
  • Only 100 requests per hour once the monthly request total has reached 100,000

Below is an example that rejects any requests during working hours:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/**
 * Sample Monitor Rule invoke service that rejects HTTP requests during working hours
 * (Monday - Friday. 9:00 am - 5:00 pm )
 */
void rejectWorkingHourRequests( MonitorRule monitorRule ) {
    GregorianCalendar gc = new GregorianCalendar()
    int day = gc.get( Calendar.DAY_OF_WEEK );
    int hour = gc.get( Calendar.HOUR_OF_DAY );
    if ( day >= Calendar.MONDAY && day <= Calendar.FRIDAY && hour > 8 && hour < 17 )
        throw new MonitorException( 'Get back to work', monitorRule )
} 

By throwing a MonitorException, the request is rejected.

Debugging Rules

When writing rules, it'll be helpful to enable the property monitor.response.header. This ensures that the response header is populated with the header TORO-Integrate-Monitor-Rule which contains the ID of the rule that matched the request:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
➜  ~ curl -I -H "Authorization: Bearer 7dce685a-b183-4fe4-a8b9-dacb53fb5536" http://localhost:8080/api/monetization/hello/Tyrion
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
TORO-Integrate-Monitor-Rule: 11
Content-Type: application/json;charset=UTF-8
Content-Length: 0
Date: Fri, 06 Jul 2018 08:13:08 GMT
Server: TORO Integrate/3.0.0

Examples

The above is an actual request sent against the examples package shipped with TORO Integrate. The rule is applied to the url /api/monetization/hello and for users under Rule 1.