CamTrace metadata connector API v1
Overview
This document describes the process of creating a CamTrace metadata connector.
Change log
Version | Date | Author | Changes |
---|---|---|---|
1.0-01 | 25/01/2017 | Olivier PELET | First version |
1.0-02 | 03/08/2022 | Romain RIGOT | Multiple adaptations for CT-Server v16.0.0 new metadata system |
1.0-03 | 14/03/2023 | Romain RIGOT | Fixed schema and parameter description of WS SEND event, GET /events/labels and POST /events/search |
1.0-04 | 29/03/2023 | Romain RIGOT | Event types names agreement |
1.0-05 | 30/03/2023 | Romain RIGOT | Event search mandatory criteria |
1.0-06 | 22/05/2023 | Romain RIGOT | Event search response order |
1.0-07 | 20/07/2023 | Romain RIGOT | POST /events route, total number of events in search result |
1.0-08 | 14/02/2024 | Romain RIGOT | GET /events/labels route, params translation |
What is a metadata connector ?
A metadata connector is a module which is able to retrieve, store and notify events coming from a device. It takes the form of an web application which can requests and responds to HTTP requests, using JSON messages (REST paradigm).
The application has an HTTP entrypoint and must implement a set of mandatory routes. It is also a websocket server on which CT-Server will connect to receive Events notifications (pull point)
It is langage agnostic and can be hosted on any computer on your network.
Architecture
Global architecture
Exchanges between CamTrace server and connector
Authentication
All mandatory routes implemented in your connector must be authenticated using HTTP basic authentication.
If your connector uses on static ressources, such as css or javascript files, you have to put these files behind the route /static and disable authentication for this route and subroutes.
Register a connector
-
In order to register your connector, you have to go to the CamTrace server administration interface in Manage/Metadata and click on Add new device
-
Enter the name of your device, select "External connector" as the Connector type, indicate the entrypoint URL of your API, this is from where your implemented routes will be called. You have to specify a name, optionnaly a login / password and an associated camera which will be associated to your connector and used in CT-Client displays. Then click on save button.
-
Your connector is now registered with the CamTrace server
HTTP status codes
-
200
OK
Successful request -
201
Created
New object saved -
400
Bad Request
Bad request input -
401
Unauthorized
Error in request authentication -
404
Not found
No such object -
500
Internal Server Error
Something went wrong -
503
Service Unavailable
The service is currently unavailable
Configuration ¶
The configuration allows the CT-Server to retreive the websocket endpoint of your connector in order to establish a permanant connection (as long as CT-Server video services are up and connector is not ignored).
GET configuration ¶
Update configurationGET/config
This route is called when you register your add or edit your connector into the CT server (see Register a connector). It gives your connector the credentials and the endpoint needed to communicate with the CamTrace server’s API.
Example URI
200
Headers
Content-Type: application/json
Body
{
"pullpointUrl": "http://127.0.0.1:8090/ws/events",
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"apiEndpoint": {
"type": "string",
"description": "Connector websocket endpoint for events notifications"
}
}
}
Health ¶
HealthGET/health
This route is called by the CamTrace web interface is order to check the connector status.
When everything is fine you must return the HTTP code 200.
If there is an issue somewhere in your connector (missing database, down devices…) you must return the HTTP code 503.
Example URI
200
Headers
Content-Type: application/json
Body
{
"status": "The connector is up and running"
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status message"
}
},
"required": [
"status"
]
}
503
Headers
Content-Type: application/json
Body
{
"status": "One of the device is not ready"
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status message"
}
},
"required": [
"status"
]
}
Admin ¶
adminGET/admin
This route is not part of the API and is optionnal
This uri can serve your connector administration webpage if needed. If it exists, it create a links to this page in the CT-Server webadmin connector section.
To show it's difference from the API, this URL must directly takes place under the root virtual directory of the connector server and port.
Example URI
Events ¶
Get labels ¶
Get labelsGET/events/labels
The CamTrace client needs to know which label to display when it receive new event from a connector. This method must return a labels object, a descriptions object and a params object containing a label and a more verbose description of all events handled by your connector.
Every property of the label
, description
and params
objects refers to an event type. Event types names are up to the connector creators but all of this events belongs to an external
prefix / property which is the external events category name in Camtrace system.
Every value of a property is a string. For the descriptions
part, it may contains one or several JSON pointers to event arguments present in the description part of your events (ex: %{/customParams/demoParam}). These tags will be replaced dynamically by Camtrace clients during display of live events.
Example URI
200
Headers
Content-Type: application/json
Body
{
"labels": {
"external.camtracetest1": "CamTrace event test 1",
"external.camtracetest2": "CamTrace event test 2"
},
"descriptions": {
"external.camtracetest1": "CamTrace event test 1 from %{/customParams/demoParam}",
"external.camtracetest2": "CamTrace event test 2 from %{/customParams/demoParam}"
},
"params": {
"external": {
"camtracetest1": "Test 1",
"camtracetest2": "Test 2 "
}
}
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"labels": {
"type": "object",
"properties": {
"external.camtracetest1": {
"type": "string"
},
"external.camtracetest2": {
"type": "string"
}
},
"description": "An object describing the label for each event handled by the connector"
},
"descriptions": {
"type": "object",
"properties": {
"external.camtracetest1": {
"type": "string"
},
"external.camtracetest2": {
"type": "string"
}
},
"description": "An object describing the description for each event handled by the connector"
}
},
"params": {
"type": "object",
"properties": {
"external": {
"type": "object",
"properties": {
"camtracetest1": {
"type": "string"
},
"camtracetest2": {
"type": "string"
}
},
},
"description": "An object describing names of possible parameters of each event handled by the connector"
}
},
"required": [
"labels",
"descriptions",
"params"
]
}
Get event details ¶
Get event detailsGET/events
This method must return an HTML page containing information about the event requested.
The page is embedded into the CamTrace client when a user is requesting details about an event that occurred. You are free to choose what elements to display and how to display them.
If you want to include static ressources files (images, css, javascript files, …) in your HTML page, they must be placed behind the /static path. All files and folders behind this path have to be reachable without authentication.
Example URI
- eventid
string
(required) Example: 7ee96ce3-a311-4f14-a22f-a7e20cea2170UUID V4 of the event requested
200
Headers
Content-Type: text/html
Body
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/bootstrap.min.css">
</head>
<body>
Event of type <b>external.camtracetest1</b> occurred at 15:49:31
</body>
</html>
Create events report ¶
Create events reportPOST/events
This method must return an HTML page containing informations about the events requested.
The page is embedded into the CamTrace client or transformed into a PDF document when a user is requesting informations about an events list that occurred. You are free to choose what informations to display and how to display them.
If you want to include static ressources files (images, css, javascript files, …) in your HTML page, they must be placed behind the /static path. All files and folders behind this path have to be reachable without authentication.
Example URI
Headers
Content-Type: application/json
Body
{
"ids": [
"eee2e165-688d-4b13-9e97-670dd1c08e21",
"31cadd2d-1051-4f78-beda-b73b3918f722"
]
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"ids": {
"type": "array",
"description": "Array containing list of event ids",
"items": {
"type": "UUIDv4"
}
},
},
"required": [
"ids"
]
}
200
Headers
Content-Type: text/html
Body
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/bootstrap.min.css">
</head>
<body>
Event of type <b>external.camtracetest1</b> occurred at 15:49:31
<hr>
Event of type <b>external.camtracetest1</b> occurred at 15:50:07
</body>
</html>
Notify event ¶
Notify eventWS SEND{json-event}
Your connector websocket server must have accepted and kept alive the CT-Server connection
When new events are created/recevied by your connector, it must notify the CamTrace server that a new event occured by send the event json parameters to the CT-Server.
Your connector websocket server adress
has been proviously sent to the CT-SERVER via the configuration route.
Example of json event
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"eventId": {
"type": "string",
"description": "UUID v4 of the event"
},
"type": {
"type": "string",
"description": "Type of the event"
},
"timestamp": {
"type": "string",
"description": "Timestamp of the event"
},
"description": {
"type": "object",
"properties": {
"args": {
"type": "object",
"description": "Object containing the event arguments"
}
}
},
"required": [
"eventId",
"type",
"timestamp"
]
},
}
None
Purge events ¶
Purge eventsPOST/events/purge
This route is optionnal
The CamTrace server has a mechanism to automatically purge events older than "DBP" days (30 days by default). This parameter is configurable during the connector registration in CT-Server admin.
When this mechanism is triggered, the server calls this route to inform that it purged all events occurred before purgeBefore
.
The purgeBefore
argument is a string formatted in ISO 8601.
Example URI
Headers
Content-Type: application/json
Body
{
"purgeBefore": "2022-05-27T00:00:00.000000Z"
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"purgeBefore": {
"type": "string"
}
},
"required": [
"purgeBefore"
]
}
200
Headers
Content-Type: application/json
Body
{
"totalPurged": 1
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"totalPurged": {
"type": "number",
"description": "The number of purged events"
}
}
}
Searching ¶
Theses routes are used by the CamTrace client for querying events matching one or several criteria.
Get events criteriaGET/events/search/criteria
This route returns a list of criteria. A criterion is an event property on which a filter can be applied.
The JSON schema below explains what properties and how the criteria must be returned in your connector response. We advise that you include at least a timestamp
criteria for searching events by date and a type
criteria if you manage several different types in your connector. Other specific search event parameters criteria names may be prefixed with external.
Example URI
200
Headers
Content-Type: application/json
Body
{
"criteria": [
{
"name": "type",
"description": "Event type",
"format": "enum",
"values": [
"external.camtracetest1",
"external.camtracetest2"
],
"texts": [
"Event test 1",
"Event test 2"
]
},
{
"name": "timestamp",
"description": "Event date",
"format": "datetime"
},
{
"name": "external.demoParam",
"description": "Demo parameter",
"format": "integer"
}
]
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"criteria": {
"type": "array",
"description": "Array containing list of criteria",
"items": {
"type": "object",
"description": "A criteria object",
"properties": {
"name": {
"type": "string",
"description": "The name of the event property"
},
"description": {
"type": "string",
"description": "A string describing the event property"
},
"format": {
"type": "string",
"description": "Value format",
"enum": [
"string",
"integer",
"datetime",
"boolean"
]
},
"values": {
"type": "array",
"description": "Array of string containing all valid values when the format is enum",
"items": {
"type": "string"
}
},
"texts": {
"type": "array",
"description": "Array of string containing labels for valid values when the format is enum",
"items": {
"type": "string"
}
}
},
"required": [
"name",
"description",
"format"
]
}
}
},
"required": [
"criteria"
]
}
Search eventPOST/events/search
This route allows to perform a search with specified criteria. It returns the event list matching the criteria and the result’s pagination information.
Events order may be requested by client, setting request parameter descOrder
. If true
, events must be sorted by date in descending order (more recent to less recent). If the parameter is false
or not specified, events must be sorted by date in ascending order in your response.
Example URI
Headers
Content-Type: application/json
Body
{
"criteria": [
{
"name": "type",
"value": "external.camtracetest1",
"comparator": "="
}
],
"paging": {
"offset": 0,
"limit": 25
}
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"criteria": {
"type": "array",
"description": "Array containing list of criteria",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": " Name of the event property to filter on"
},
"value": {
"type": "string",
"description": "Value of the event property to filter on"
},
"comparator": {
"type": "string",
"description": "Comparator. If omitted it will be assumed as '='",
"enum": [
"!=",
"=",
">=",
">",
"<=",
"<",
"LIKE"
]
}
},
"required": [
"name",
"value"
]
}
},
"paging": {
"type": "object",
"description": "Pagination parameters",
"properties": {
"offset": {
"type": "number",
"description": "Offset from the beginning of the resultset"
},
"limit": {
"type": "number",
"description": "Result limit"
}
}
}
},
"required": [
"criteria"
]
}
200
Headers
Content-Type: application/json
Body
{
"paging": {
"next": {
"offset": 25,
"limit": 25
}
},
"total": 197,
"events": [
{
"id": "68017368-37b2-4698-9ac3-12cbb9a51ecf",
"type": "external.camtracetest1",
"timestamp": "2022-07-15T14:48:00.000Z",
"description": {
"customParams": {
"demoParam": 1
},
},
"label": "CamTrace event test with param 1"
}
]
}
Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"paging": {
"type": "object",
"description": "Pagination parameters"
"properties": {
"next": {
"type": "object",
"description": "Object containing parameters for the next resultset"
"properties": {
"offset": {
"type": "integer",
"description": "Offset parameter for the next resultset"
},
"limit": {
"type": "integer"
"description": "Limit parameter for the next resultset"
}
},
"required": [
"offset",
"limit"
]
}
},
"required": [
"next"
]
},
"total": {
"type": "integer",
"description": "Total number of searched events",
"required": [
"total"
]
},
"events": {
"type": "array",
"description": "List of events matching the specified criteria"
"items": {
"type": "object",
"properties": {
"id": {
"type": "UUIDv4",
"description": "Event id"
},
"type": {
"type": "string",
"description": "Event type"
},
"timestamp": {
"type": "date",
"description": "Datetime of the event creation, formatted in ISO 8601"
},
"description": {
"type": "object",
"description": "Event JSON description details"
},
"label": {
"type": "string",
"description": "Textual description of the event with dynamic params already included (no JSON pointers)"
}
}
}
}
},
"required": [
"events"
]
}