Kalisio geofencing service
geoKatcher is a service that allows to monitor geofences between two layers of geospatial data.
for now only the following sources are supported:
- Kalisio Maps (Kano)
Using the feathers framework, and feathers-distributed extension.
GeoKatcher can discover Kano services and query them to retrieve layers and features. Additionally, it can publish its monitor
service, allowing other services to interact with it and receive events.
Summary
Variable | Description | Defaults |
---|---|---|
PORT |
The port to be used when exposing the service | 8080 |
HOSTNAME |
The hostname to be used when exposing the service | localhost |
DB_URL |
The url of the database | mongodb://localhost:27017/geokatcher |
BASE_URL |
The url used when exposing the service | localhost:8080 |
API_PATH |
The path to the API |
Checks for the health of the service, returns a json object with the name of the service (geokatcher) and it's version number.
Method | Endpoint | Description |
---|---|---|
POST | /monitor | Create a new monitor |
GET | /monitor | Get all the monitors |
GET | /monitor/:id | Get a monitor by its id |
PUT | /monitor/:id | Update a monitor by its id (complete) |
PATCH | /monitor/:id | Update a monitor by its id (partial) |
DELETE | /monitor/:id | Delete a monitor by its id |
A monitor is a JSON object with 3 main parts:
Part | Description | Type | Presence |
---|---|---|---|
target | The first layer to monitor | Object |
Required |
zone | The second layer to monitor | Object |
Required |
monitor | The monitor information | Object |
Required |
A layer element (either target or zone) is an object that specifies the layer to monitor and can include filters to select only a subset of the layer.
{
"name": "layer1",
"filter": {
"properties.name" : "layer1name"
}
}
Field | Description | Type | Presence |
---|---|---|---|
name | The name (or id) of the layer to monitor | String |
Required |
filter | An optional filter object (MongoDB query syntax) | Object |
Optional , default : {} |
The layer can be a user defined layer like layer1
or a built-in layer like hubeau_hydro
(or Layers.HUBEAU_HYDRO
)
The monitor element is an object that contains the monitor information.
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
name | The name of the monitor | String |
Required |
|
description | The description of the monitor | String |
Optional , default : '' |
|
enabled | if the monitor is enabled or not | Boolean |
Optional , default : true |
|
type | The type of the monitor | String |
event or cron or dryRun(Only on create) |
Required |
trigger | The trigger of the monitor | Array or String |
array of events or a valid cron expression |
Required |
evaluation | The evaluation of the monitor (what should be the operation to do) | Object |
Required |
|
action | The action of the monitor (what should be done when the monitor alert status changes) | Object |
Optional , default : {} |
dryRun
option is a special type of monitor that allows you to test the monitor without actually saving it in the database, executing any actions, or emitting events.
in case of a dryRun, the following fields are not required :
name
trigger
// dryRun response
{
"monitorObject" : {
// The monitor object
},
"result" : {
// The features that are returned by the evaluation
}
}
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
alertOn | Alert if the data is inside or outside the geofence | String |
data or noData |
Optional , default : data |
type | The type of the evaluation | String |
geoWithin , geoIntersects or near |
Required |
maxDistance | The maximum distance to consider for the near evaluation | Number |
> 0 , only for the near type |
Optional , default : 1000 |
minDistance | The minimum distance to consider for the near evaluation | Number |
> 0 , only for the near type |
Optional , default : 0 |
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
type | The type of the action | String |
slack-webhook , crisis-webhook , custom-request ,no-webhook |
Optional , default : no-webhook |
url | The url of the action | String |
valid url , |
Required when not no-webhook |
cooldown | The cooldown before next Still firing alert |
Number seconds |
>= 0 |
Optional , default : 60 |
additionalProperties | Additional properties for the action | Object |
only for crisis-webhook and custom-request type |
Required |
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
organisation | The organisation id | String |
Required |
|
token | The token to interact with the crisis service | String |
Required |
|
data | The data to send to the crisis service | Object |
Required |
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
name | The name of the data | String |
Optional , default : monitor name |
|
description | The description of the data | String |
Optional , default : monitor description |
|
template | The template of the alert in crisis (id or name) | String |
Required |
Field | Description | Type | Constraints | Presence |
---|---|---|---|---|
method | The method of the request | String |
GET , POST , PUT , PATCH , DELETE |
Required |
headers | The headers of the request | Object |
Optional , default : {} |
|
body | The body of the request | Object |
Optional , default : {} |
The custom-request
action supports basic templating using the %_%
syntax.
placing :
%monitorName%
in the url,body or headers will be replaced by the monitor name.%monitorStatus%
in the url,body or headers will be replaced by the monitor alert status.
The object returned by the service will have the following structure:
{
"_id": "6644cf4f83bf298f8a8bb1ba" // id auto generated by the service
"target": {
"name": "layer1",
"filter": {
"properties.name": "layer1featureA"
},
"layerInfo": { // Generated by the service to determine on which kano service to query
"kanoService": "features", // The kano service to query
"layerId": "663e3593fb7a85c83f5084fe" // The layer id (layer1)
}
},
"zone": {
"name": "layer2",
"filter": {
"properties.name": "layer2featureB"
},
"layerInfo": { // Generated by the service to determine on which kano service to query
"kanoService": "features", // The kano service to query
"layerId": "6628d597151fd9493aedd094" // The layer id (layer2)
}
},
"monitor": {
"description": "description du moniteur",
"type": "event",
"trigger": [
"patched"
],
"name": "nice monitor",
"enabled": true,
"evaluation": {
"alertOn": "data",
"type": "geoIntersects"
},
"action": {
"type": "crisis-webhook",
"url": "https://crisis-service/api/webhooks/events",
"additionalProperties": {
"organisation": "85c83f5084fe6644cf4f83bf",
"token": "euzyfgnzeufhiuzefze",
"data": {
"template": "Webhook alert",
}
},
"cooldown": 1
},
"lastRun": { // Generated by the service after each run of the monitor
"date": "2024-05-17T15:50:19.331Z", // The date of the last run
"lastActionRun": 0, // The date of the last action run
"alert": "not firing", // Last alert status
"status": { // Last status of the monitor
"success": true // if an error occured the name,message and data will be described here
}
}
},
"createdAt": "2024-05-15T15:05:51.534Z", // Generated by the service
"updatedAt": "2024-05-17T15:50:19.334Z" // Generated/updated by the service
}
The following fields are generated by the service and will be ignored if provided by the user
Field | Description |
---|---|
_id |
The service-generated ID for each monitor |
layerInfo |
The service-generated layerInfo object to determine which Kano service to query |
lastRun |
The service-generated lastRun object after each run of the monitor |
createdAt |
The service-generated creation date of the monitor |
updatedAt |
The service-generated last update date of the monitor |
In case of an error, the lastRun status object will contain the following fields:
{
"status": {
"success": false,
"error": {
"message": "Layer not found",
"data": {
"layer": "layer3"
}
}
}
}$
Before any CREATE,PATCH,PUT operation, the service will validate the monitor structure and then run the monitor evaluation
If an error occurs, the monitor will not be saved and the error will be returned to the user.
Error code | Error name | Description |
---|---|---|
400 | Bad Request | The monitor structure is not valid |
404 | Not Found | A layer was not found during evalutation |
404 | Not Found | A monitor was not found during update/patch/delete |
409 | Conflict | A monitor with the same name already exists |
500 | Internal Server Error | Kano service error |
500 | Internal Server Error | Any other error |
When making a request:
- Retrieve the geometries of the features of the target.
- Generate MongoDB queries for each geometry (number of queries equals the number of geometries).
- Query the zone service to find matching features for each geometry.
depending on the type of evaluation, arrange the layers accordingly to get the desired result and least amount of queries.
geoWithin
: the zone should be inside the targetgeoIntersects
: the target and the zone should intersect (target should be the layer with the least amount of features*)near
: the target and the zone should be near each other (target should be the layer with the least amount of features*)
*considering the filters
The patch operation updates only the fields provided in the request. Other fields will remain unchanged. However, certain internal fields need to be re-specified in the request even if they are not being updated, because they can be considered optional.
For example:
- When updating the
layerElement
, it is necessary to provide thefilters
(if specified) again. Otherwise, it will be assumed that the user wants to remove the filters. - When updating the
monitor.action
, it is necessary to provideadditionalProperties
(if specified) again. Otherwise, it will be assumed that the user wants to remove the field.
These constraints apply only if the specific part of the monitor is being updated. If you do not update monitor.action
in the request body, you do not need to provide the additionalProperties
field. The same applies to the layerElement
filters.