Skip to content

Toro Cloud Dev Center


HTTP filter endpoint

The HTTP filter endpoint allows developers to invoke services upon the receipt of a request. The invocation of the endpoint's service is conditional. The received request must match the conditions defined in the HTTP filter endpoint's configuration; otherwise, it is ignored and therefore, does not trigger the configured service.

Behind the scenes, Martini registers a filter for each HTTP filter endpoint1. HTTP filter endpoints are simply a convenient means to add filters to Martini.

Properties

General configuration

Property Default Description
Name (required) The name of the endpoint.
Service (required) The service to execute when the endpoint is triggered.
Run As Anonymous The user to run the service in behalf of. This is logged to Tracker.
Document Type <Name of endpoint type> The document type to be used when adding documents to Tracker as this endpoint is triggered.
Auto Start true Whether or not to automatically start the endpoint upon package startup.
Log To Tracker false Flag determining whether executions should be logged to Tracker.
Replicated true If this endpoint is configured on a Martini instance that's running in a cluster, replicated will determine whether to run the endpoint on all instances, or only the elected leader node in the cluster. When this is checked, all instances will run the endpoint. When it's unchecked, only the leader node will run the endpoint.

HTTP filter-specific configuration

Property Default Description
Priority 2147483647 A numeric value used to guarantee the order of execution of HTTP filter endpoints of the same filter order. The lower the number, the higher the priority.
Filter order (required) Indicates whether Martini will authenticate the request before or after the filter.
Path pattern type (required) Indicates the type of the path patterns to match. A pattern can only either be a glob pattern, or a regular expression pattern.
Path patterns (required) A collection of request path patterns that incoming requests must satisfy. To trigger the configured service, a request's path must match at least one of these patterns.
Case sensitive true When true, path patterns must be matched case sensitively.
Request methods (required) A collection of request methods that incoming requests must satisfy. To trigger the configured service, a request must use one of these methods.

Service

When the endpoint is triggered, the following variables are exposed to the configured service:

General parameters

Name Type Description
$trackerId java.lang.String The Tracker document internal ID. If the endpoint was configured to not track, this value will be null.
$tracker io.toro.martini.tracker.Tracker The Tracker object. If the endpoint was configured to not track, this value will be null.
martiniPackage MartiniPackage The Martini package that contains the endpoint.
parameters java.util.Map A map containing all the endpoint specific parameters.
properties java.util.Map A map containing containing all the properties associated with the endpoint.

HTTP filter-specific parameters

Name Type Description
$__request javax.servlet.http.HttpServletRequest The request which matched the conditions of the HTTP filter endpoint.
$__response javax.servlet.http.HttpServletResponse The corresponding response for the request.
$__chain javax.servlet.FilterChain The object responsible for invoking the next filter.
uri java.lang.String The URI of the matching request.
url java.lang.String The URL of the matching request.
method java.lang.String The method used by the matching request.
user java.security.Principal The authenticated user of the request, if any. Will always be null for services invoked before the authentication filter.

Return values

To alter filter chain logic, an HTTP filter endpoint service may return any of the following values. It is imperative for the value to match the prescribed type. For Gloop and Flux services returning more than one value (or output property2, rather), each property must also follow the prescribed name.

Name Type Description
$__newRequest javax.servlet.http.HttpServletRequest Returning a non-null HttpServletRequest prompts Martini to replace the original intercepted request object with this new request object. In other words, succeeding filters in the chain will receive this request object instead of the original one. This will not take effect if the service discontinues the implicit call for the next filter in the chain.
$__newResponse javax.servlet.http.HttpServletResponse Returning a non-null HttpServletResponse prompts Martini to replace the original intercepted response object with this new response object. In other words, succeeding filters in the chain will receive this response object instead of the original one. This will not take effect if the service discontinues the implicit call for the next filter in the chain.
$__discontinueChain boolean A boolean flag which Martini uses to determine whether or not to implicitly call the next filter in the chain. If this property's value is true, then Martini runs with the assumption that the service will execute the succeeding filter chain call by itself. In other words, Martini won't call $__chain.doFilter( $__request, $__response ) implicitly.
You can use any name for your property if you're returning only one property

If your service has only one output property declared, Martini only checks if its type matches any of the types in the table below. It no longer checks for the property's name.

Consider the following service, which returns a boolean property named result to discontinue the execution of the next filter:

HTTP filter endpoint service which discontinues the filter chain by returning a property named `result` whose value is `true`

Return a Gloop model in Groovy to "return multiple values"

An HTTP filter endpoint Groovy service is allowed to return a GloopModel instance whose properties match any of the above names and types.

Examples

Gloop as service

Consider this application using Gloop. This service returns an altered copy of the response. 'X'-prefixed request headers are re-injected as response headers in the new response, albeit with their values in UPPERCASE.

Response-altering service

Want more examples?

Martini ships with a Martini package called examples, which contains services (including the above example) demonstrating more use cases.

Groovy method as service

The following method does the same, but in Groovy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletResponseWrapper

class HttpFilterExamples {

    /**
     * Alters the response to inject 'X'-prefixed headers from the request;
     * albeit with values in uppercase. 
     * 
     * @param $__request the matched request
     * @param $__response the response for the matched request
     * @return an altered copy of the response
     */
    static HttpServletResponse toUppercaseXPrefixedHeaders(
        HttpServletRequest $__request, HttpServletResponse $__response ) {

        $__response = new HttpServletResponseWrapper( $__response );
        Enumeration<String> headers = $__request.getHeaderNames();
        while ( headers.hasMoreElements() ) {
            String header = headers.nextElement();
            "Checking header [$header]".trace()
            if ( !header.toUpperCase().startsWith( "X-" ) ) {
                continue;
            }

            Enumeration<String> values = $__request.getHeaders( header );
            while ( values.hasMoreElements() ) {
                String value = values.nextElement();
                "Transforming value [$value] of header [$header] to uppercase".info()
                $__response.addHeader( header , value.toUpperCase() )
            }
        }

        return $__response
    }

}

  1. An endpoint's corresponding filter is registered only when the endpoint is started. It is consequently de-registered when the endpoint is stopped. 

  2. Technically speaking, Gloop and Flux services do not really return multiple values. Both return a single GloopModel, comprised of output properties declared by the service.