Skip to content

Latest commit

 

History

History
315 lines (249 loc) · 18 KB

README_hook.md

File metadata and controls

315 lines (249 loc) · 18 KB

gateleen-hook

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

General configuration

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.

Schema validation

Adding hooks requires a validation against a schema to be positive. Check the schema gateleen_hooking_schema_hook

Route - Hooks

Attention: A route directs all communication from a specific resource to another destination. Per resource may only exist one route a time.

Usage

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.

Add a route

PUT /<url>/<resource>/_hooks/route
{
    "destination": "http://<url>/<target>",
    "methods": [],
    "headersFilter": "x-foo: (A|B)"
}

Remove a route

DELETE /<url>/<resource>/_hooks/route

Example:

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:

Register the route hook.
PUT http://myserver:7012/gateleen/example/resource/_hooks/route
{
    "destination": "http://myserver:7012/gateleen/example/othertarget",
    "methods": []
}
Use the hook
DELETE http://myserver:7012/gateleen/example/resource/anExample

This request will be rerouted to:

DELETE http://myserver:7012/gateleen/example/othertarget/anExample
Deleting the hook
 DELETE http://myserver:7012/gateleen/example/resource/_hooks/route

Create a listable 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"
    ]
}

Listener - Hooks

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.

Usage

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.

Add a listener

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)"
}

Remove a listener

DELETE http://myserver:7012/gateleen/everything/_hooks/listeners/http/myexample

QueueingStrategy

The QueueingStrategy can be configured for listeners only and defines the 'queueing' behaviour. The following strategies are available.

DefaultQueueingStrategy

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.

DiscardPayloadQueueingStrategy

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"
    }    
}
ReducedPropagationQueueingStrategy

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.

Log hook registration changes

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

Query-Based Listener and Route Search

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

Listener Search with q

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": []
}

Route Search with q

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": []
}

Micrometer metrics

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.