This feature allows you to set either dynamical generated routes or listeners called hooks to a specific resource or a collection.
Two types of this hooks exists:
- routes
- listeners
During the instantiation of the HookHandler you have the possibility to specify the collection where your hooks will be saved in the storage. To do so, you have to set the parameter hookRootUri in the constructor.
Adding hooks requires a validation against a schema to be positive. Check the schema gateleen_hooking_schema_hook
Attention: A route directs all communication from a specific resource to another destination. Per resource may only exist one route a time.
Information: The suffix /_hooks/route always indicates a route registration. The HookHandler will use this suffix to identify either a registration or an unregistration of a route hook.
Payload
Property | Required | Description |
---|---|---|
destination | yes | A valid URL (absolute) where the requests should be redirected to. |
methods | no | An array of valid HTTP methods (PUT, GET, DELETE, ...) to define for which requests the redirection should be performed. As a default all requests will be redirected. |
expireAfter | no | DEPRECATED - Hooks don't manipulate or set the x-expire-after header any more. Use HeaderFunctions instead |
staticHeaders | no | (deprecated - use headers) This property allows you to set static headers passed down to every request. The defined static headers will overwrite given ones! |
headers | no | array of request header manipulations: set, remove, complete (set-if-absent) and override (set-if-present) |
headersFilter | no | A regular expression to define which requests headers must be present for the route to be used. Each request header entry is validated in the format <KEY>: <VALUE> , so you are able to filter for request header names and values. |
collection | no | This property specifies if the given URL is a resource or a collection. If this property is not set, the default is true (collection). |
listable | no | This property specifies if a route is listed if a GET is performed on its parent or not. The default is false or set by the value passed during the initialization. |
translateStatus | no | This property defines a mapping to translate http respond status values. |
connectionPoolSize | no | This property defines the max number of TCP connections which will be open in parallel to the destination system (Default 50) |
maxWaitQueueSize | no | This property defines the max number of requests allowed in the wait queue of the connection pool to the destination. If set to 0 then new incoming requests are rejected immediately if the pool is full (max connectionPoolSize reached), otherwise the requests are queued until the maxWaitQueueSize is reached and dispatched once connections in the pool become available. (Default -1, unbounded) |
timeout | no | This property defines the request timeout in seconds (Default 30 seconds) applied to requests established over the route |
Attention: A route has a default expiration time of 1 hour. After this time the route will expire and be removed from the storage, as well as the HookHandler.
To update / refresh a route, simply perform another registration.
To change the expiration time of a route, just pass a X-Expire-After header with the registration PUT request.
PUT /<url>/<resource>/_hooks/route
{
"destination": "http://<url>/<target>",
"methods": [],
"headersFilter": "x-foo: (A|B)"
}
DELETE /<url>/<resource>/_hooks/route
The following example will show you, how to set a route for a specific resource / collection.
Assumption: We’d like to set a dynamic route for the resource /gateleen/example/resource. The target destination should be /gateleen/example/othertarget.
To do so, we have to perform the following steps:
PUT http://myserver:7012/gateleen/example/resource/_hooks/route
{
"destination": "http://myserver:7012/gateleen/example/othertarget",
"methods": []
}
DELETE http://myserver:7012/gateleen/example/resource/anExample
This request will be rerouted to:
DELETE http://myserver:7012/gateleen/example/othertarget/anExample
DELETE http://myserver:7012/gateleen/example/resource/_hooks/route
Normally a created rout will not be listed, if their parent collection is requested.
PUT http://myserver:7012/gateleen/example/resource/_hooks/route
{
"destination": "http://myserver:7012/gateleen/example/othertarget"
}
The request will lead to a 404.
GET http://myserver:7012/gateleen/example/
In order to be able to list one or more routes, we have to tell the HookHandler, that we wish the rout to be listable.
PUT http://myserver:7012/gateleen/example/resource/_hooks/route
{
"destination": "http://myserver:7012/gateleen/example/othertarget",
"methods": [],
"listable" : true,
"collection" : true
}
Now the request will lead to:
GET http://myserver:7012/gateleen/example/
{
"example" : [
"resource"
]
}
Attention: A listener registers an additional destination for a resource, which also will get a copy of the original request. You may registers as many listeners per resource as you wish. Requests forwarded to a listener are always enqueued and delivered as soon as the target destination is available.
Information: The suffix /_hooks/listeners/http/<id> always indicates a route registration. The HookHandler will use this suffix to identify either a registration or an unregistration of a listener hook.
Payload
Property | Required | Description |
---|---|---|
destination | yes | A valid URL (relative) where the requests should be redirected to. |
methods | no | An array of HTTP methods (namely: GET, HEAD, PUT, POST, DELETE, OPTIONS and PATCH) to define for which requests the redirection should be performed. As a default all requests will be redirected. Requests with not whitelisted methods will not be redirected and get dropped instead. |
expireAfter | no | DEPRECATED - Hooks don't manipulate or set the x-expire-after header any more. Use HeaderFunctions instead |
queueExpireAfter | no | A copied and forwarded request to a listener is always putted into a queue. To ensure to have an expiration time for each request within the given listener queue, you can set a default value (in seconds) with this property. This way you can prevent a queue overflow. The property will only be used for requests, which doesn’t have a x-queue-expire-after header. |
staticHeaders | no | (deprecated - use headers) This property allows you to set static headers passed down to every request. The defined static headers will overwrite given ones! |
headers | no | array of request header manipulations: set, remove, complete (set-if-absent) and override (set-if-present) |
headersFilter | no | A regular expression to define which requests headers must be present for the listener to be used. Each request header entry is validated in the format <KEY>: <VALUE> , so you are able to filter for request header names and values. |
filter | no | This property allows you to refine the requests with a regular expression, which you want to receive for the given destination. |
type | no | Default: before This property allows you to set, if the request to a listener will be sent before or after the original request was performed. The valid settings are: after => request will be forwarded to listener after the original request was performed before => (default) request will be forwarded to a listener before the original request was performed This can be useful if you want to use your listeners with the delegate feature and expect a request to be already executed as soon as you execute a delegate. |
fullUrl | no | Default: false Defines whether the hook forwards using the full initial url or only the appendix Example: hooked url = http://a/b/c request.uri() = http://a/b/c/d/e.x url appendix = /d/e.x |
queueingStrategy | no | Default: DefaultQueueingStrategy Configures the 'queueing' behaviour of the HookHandler. See chapter QueueingStrategy for detailed information. |
Attention: A listener has a default expiration time of 30 seconds. After this time the listener will expire and be removed from the storage, as well as the HookHandler.
To update / refresh a listener, simply perform another registration.
To change the expiration time of a listener, just pass a X-Expire-After header with the registration PUT request.
PUT http://myserver:7012/gateleen/everything/_hooks/listeners/http/myexample
{
"methods": [
"PUT"
],
"destination": "/gateleen/example/thePosition",
"filter": "/gateleen/everything/.*/position.*",
"headers": [
{ "header":"X-Expire-After", "value":"3600", "mode":"complete"}
],
"headersFilter": "x-foo: (A|B)"
}
DELETE http://myserver:7012/gateleen/everything/_hooks/listeners/http/myexample
The QueueingStrategy can be configured for listeners only and defines the 'queueing' behaviour. The following strategies are available.
The DefaultQueueingStrategy does not change anything in the 'queueing' behaviour. Requests are enqueued without any modification. This strategy is used when no (or no valid) QueueingStrategy is configured.
The DiscardPayloadQueueingStrategy removes the payload from the request before enqueueing. When a Content-Length header is provided, the value will be changed to 0.
To activate this strategy, the following configuration has to be added when adding a listener:
{
"queueingStrategy": {
"type": "discardPayload"
}
}
The ReducedPropagationQueueingStrategy is used to reduce the amount of hooked resource changes by only propagating 1 resource change over a configurable amount of time (intervalMs). Typically this strategy is used to not overwhelm a client with thousands of hooked resource changes. As in the DiscardPayloadQueueingStrategy, the payload will be removed before enqueueing.
To activate this strategy, the following configuration has to be added when adding a listener:
{
"queueingStrategy": {
"type": "reducedPropagation",
"intervalMs": 60000
}
}
The intervalMs defines the amount of time in milliseconds to wait before propagate a single resource change.
To log the payload of changes to the hook registrations, the RequestLogger can be used.
Make sure to instantiate the RequestLoggingConsumer by calling
RequestLoggingConsumer requestLoggingConsumer = new RequestLoggingConsumer(vertx, loggingResourceManager);
To enable the logging of the hook registration changes, make sure the url to the hook registrations is enabled in the logging resource.
Example:
{
"headers": [],
"payload": {
"filters": [
{
"url": "/playground/server/.*/_hooks/.*",
"method": "PUT"
}
]
}
}
Also you have to enable the logging on the HookHandler by calling
hookHandler.enableResourceLogging(true);
Gateleen allows searching for listeners and routes using the query parameter q
. This simplifies filtering the registered hooks based on query parameters.
The search will be based on the value registered of the destination property
Search for listeners based on a query parameter like this:
GET http://myserver:7012/playground/server/hooks/v1/registrations/listeners?q=mylistener
The response will contain the matching listeners. If no match is found, an empty list is returned:
Example response with matches:
{
"listeners": [
"first+playground+server+test+nemo+origin+mylistener"
]
}
Example response with no matches:
{
"listeners": []
}
Similarly, you can search for routes using a query parameter:
GET http://myserver:7012/playground/server/hooks/v1/registrations/routes/?q=myroute
The response contains the matching routes, or an empty list if no match is found.
Example response with matches:
{
"routes": [
"first+playground+server+test+nemo+origin+myroute"
]
}
Example response with no matches:
{
"routes": []
}
The hook feature is monitored with micrometer. The following metrics are available:
- gateleen_listener_count
- gateleen_routes_count
Example metrics:
# HELP gateleen_listener_count Amount of listener hooks currently registered
# TYPE gateleen_listener_count gauge
gateleen_listener_count 577.0
# HELP gateleen_routes_count Amount of route hooks currently registered
# TYPE gateleen_routes_count gauge
gateleen_routes_count 15.0
To enable the metrics, set a MeterRegistry
instance by calling setMeterRegistry(MeterRegistry meterRegistry)
method in HookHandler
class.