Remote object storage
Overview
This API is based on the Device Configuration API framework. For guidance on how to use these APIs, please refer to Device Configuration APIs.
Description
The VAPIX® Remote Object Storage API makes it possible for the client to configure storage of recordings on a remote object store. Each store is defined as a destination with settings containing the specific URL and credentials for uploading objects, as well as specific settings for the object store provider. An external authorization server can also be used for retrieving access tokens or credentials using the OpenID Connect protocol.
Recordings uploaded to an object store will use the object storage recording format described in Annex B of ONVIF Recording Control Service Specification.
This API covers the location of object store and credentials for accessing it. For configuration of object key prefix, postfix, recording media format, encryption etc. see the Recording Group API.
Failover configuration
You can configure local failover storage to temporarily store objects that can't be uploaded to a remote object store destination. Once connection is restored, the stored objects are reuploaded automatically. See FailoverConfiguration
-
Objects are cached in memory before being written to failover storage. When failover storage is available, new objects bypass the in-memory cache and are written directly to failover storage after approximately 5 minutes of that recording has accumulated in the cache, or sooner if the cache capacity is reached.
-
If a destination is removed, all objects stored in failover for that destination will also be removed.
-
Unlike normal recordings, failover objects aren't subject to automatic cleanup based on storage capacity. This means a high or unlimited
storageLimitcan starve normal recordings of storage space if connection problems persist for an extended period. -
When connection to the remote object store is restored, failover objects are uploaded in parallel with ongoing recording uploads. The bandwidth used for uploading objects stored in failover can be limited with the
uploadLimitproperty to control the impact on ongoing uploads.
Objects held in memory are lost if the device loses power before they are uploaded or written to failover storage.
The diskSelection property determines the disk selection strategy and can be set to AUTO or MANUAL.
-
By default, failover is enabled with
diskSelectionset toAUTO, with storage managed automatically by the disk selection mode and no upload bandwidth limit. -
In
AUTOmode, a disk is selected depending on availability. If a disk becomes unavailable, a new storage disk will be selected and failover continues operation. TheAUTOmode won't use a larger portion of a disk to keep storage available for other recordings. ThestorageLimitproperty doesn't apply inAUTOmode. -
In
MANUALmode, only the disk specified by the propertydiskIdis used if available. The available disks can be listed using the Disk management API, but disks of NetworkShare type aren't used for failover.diskIdmust be explicitly set inMANUALmode;storageLimitdefaults tonullfor unlimited storage. Failover storage won't use more than 95% of a disk's total capacity.
Authentication
For detailed information on how to authenticate requests to this API, please refer to Authentication.
Use cases
Get all destinations
Storage destinations are stored in remote-object-storage.v1.destinations entity collection. All storage destination can be retrieved with a get operation on this entity collection.
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/destinations
GET /config/rest/remote-object-storage/v1/destinations HTTP/1.1
HOST: my-device
Content-Type: application/json
200 OK
Content-Type: application/json
{
"status": "success",
"data": [
{
"id": "aws1",
"description": "My S3 Destination",
"s3": {
"accessKeyId": "*****",
"secretAccessKey": "*****",
"sessionToken": "*****",
"region": "us-east-1",
"url": "some.domain/some/url",
"bucket": "someBucket"
}
},
{
"id": "azure1",
"description": "My Azure Destination",
"azure": {
"accountName": "someAccountName",
"sharedKey": "*****",
"sas": "",
"url": "some.domain/some/url",
"container": "somecontainer"
}
}
]
}
Add a new storage destination
A new destination can be added by adding a new instance to remote-object-storage.v1.destinations entity collection.
- curl
- HTTP
curl --request POST \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/destinations \
--data '{
"data": {
"id": "myDestination",
"description": "azure destination",
"azure": {
"accountName": "someAccountName",
"container": "acontainer",
"sharedKey": "bXlwYXNzd29yZA==",
"url": "some.domain/example/url"
}
}
}'
POST /config/rest/remote-object-storage/v1/destinations HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"id": "myDestination",
"description": "azure destination",
"azure": {
"accountName": "someAccountName",
"container": "acontainer",
"sharedKey": "bXlwYXNzd29yZA==",
"url": "some.domain/example/url"
}
}
}
201 Created
Content-Type: application/json
{
"status": "success"
}
Add a new storage destination with external authorization
Add a new destination instance to the remote-object-storage.v1.destinations entity collection.
The API expected from the authorization server is described in datatypes.AuthorizationServer
- curl
- HTTP
curl --request POST \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/destinations \
--data '{
"data": {
"id": "myDestination2",
"description": "azure destination with authorization",
"azure": {
"accountName": "someAccountName",
"container": "acontainer",
"url": "some.domain/example/url"
},
"authorizationServer": {
"clientAuthenticationMethod": "private_key_jwt",
"clientId": "myClientId",
"tokenEndpoint": "some.domain/token/endpoint"
}
}
}'
POST /config/rest/remote-object-storage/v1/destinations HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"id": "myDestination2",
"description": "azure destination with authorization",
"azure": {
"accountName": "someAccountName",
"container": "acontainer",
"url": "some.domain/example/url"
},
"authorizationServer": {
"clientAuthenticationMethod": "private_key_jwt",
"clientId": "myClientId",
"tokenEndpoint": "some.domain/token/endpoint"
}
}
}
201 Created
Content-Type: application/json
{
"status": "success"
}
Update a storage destination
A property of a destination can be updated using the id and providing the updated property. Below is a example of updating the sas token for a destination with an azure configuration.
- curl
- HTTP
curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/destinations/myDestination \
--data '{
"data": {
"azure": {
"sas": "newToken"
}
}
}'
PATCH /config/rest/remote-object-storage/v1/destinations/myDestination HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"azure": {
"sas": "newToken"
}
}
}
200 OK
Content-Type: application/json
{
"status": "success"
}
Delete a storage destination
A destination can be removed from the remote-object-storage.v1.destinations entity collection by using the id of the destination.
- curl
- HTTP
curl --request DELETE \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/destinations/myDestination
DELETE /config/rest/remote-object-storage/v1/destinations/myDestination HTTP/1.1
HOST: my-device
Content-Type: application/json
200 OK
Content-Type: application/json
{
"status": "success"
}
Get failover configuration
Get the current failover configuration by using the remote-object-storage.v1.failover property.
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/failover
GET /config/rest/remote-object-storage/v1/failover HTTP/1.1
HOST: my-device
Content-Type: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"data": {
"diskSelection": "AUTO",
"diskId": null,
"storageLimit": null,
"uploadLimit": null
}
}
Set up failover storage on a specific disk
Configure failover to use a specific disk with a storage limit and an upload bandwidth limit.
In this example, diskSelection is set to MANUAL on the disk SD_DISK with a storage limit of 10 GiB and a maximum upload limit of 5000 kbit/s.
- curl
- HTTP
curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/failover \
--data '{
"data": {
"diskSelection": "MANUAL",
"diskId": "SD_DISK",
"storageLimit": 10485760,
"uploadLimit": 5000
}
}'
PATCH /config/rest/remote-object-storage/v1/failover HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"diskSelection": "MANUAL",
"diskId": "SD_DISK",
"storageLimit": 10485760,
"uploadLimit": 5000
}
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Update the failover upload bandwidth limit
Update the upload bandwidth used for failover by using the uploadLimit field.
In this example, the upload limit is set to 1000 kbit/s.
- curl
- HTTP
curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/failover \
--data '{
"data": {
"uploadLimit": 1000
}
}'
PATCH /config/rest/remote-object-storage/v1/failover HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": {
"uploadLimit": 1000
}
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
Disable failover storage
Set the failover configuration to null to disable failover. When disabled, objects that fail to upload to the remote object store won't be stored locally.
- curl
- HTTP
curl --request PATCH \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "Content-Type: application/json" \
http://my-device/config/rest/remote-object-storage/v1/failover \
--data '{
"data": null
}'
PATCH /config/rest/remote-object-storage/v1/failover HTTP/1.1
HOST: my-device
Content-Type: application/json
{
"data": null
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success"
}
API definition
Structure
remote-object-storage.v1 (Root Entity)
├── failover (Property)
├── destinations (Entity Collection)
├── authorizationServer (Property)
├── azure (Property)
├── description (Property)
├── id (Property)
├── s3 (Property)
Entities
remote-object-storage.v1
- Description: Root entity of Remote Object Storage API
- Type: Singleton
- Operations
GET
- Attributes
- Dynamic Support: No
Properties
failover
- Description: Failover configuration. Defaults to
AUTOdisk selection when not explicitly set. Set tonullto disable. See Failover configuration. - Datatype:
FailoverConfiguration - Operations
- Get
- Set
- Attributes
- Nullable: Yes
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions
This entity has no actions.
remote-object-storage.v1.destinations
- Description: Destination collection
- Type: Collection (Key Property: ID)
- Operations
GETADD(Permissions: admin)- Required properties: id
- Optional properties: description, authorizationServer, azure, s3
- Remove (Permissions: admin)
- Attributes
- Dynamic Support: No
When adding a new destination only one of the destination types: azureDestination or s3Destination should be provided. If multiple destination types are provided the request will be
rejected with a Validation error, code 5.
Properties
authorizationServer
- Description: Authorization server configuration
- Datatype:
authorizationServer - Operations
GET(Permissions: admin, operator)SET(Permissions: admin)
- Attributes
- Nullable: Yes
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
azure
- Description: Azure related settings
- Datatype:
azureDestination - Operations
GET(Permissions: admin, operator)SET(Permissions: admin)
- Attributes
- Nullable: Yes
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
description
- Description: Description of the destination
- Datatype: string
- Operations
GET(Permissions: admin, operator)SET(Permissions: admin)
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
id
- Description: ID of the destination
- Datatype:
idString - Operations
GET(Permissions: admin, operator)
- Attributes
- Nullable: No
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
s3
- Description: S3 related settings
- Datatype:
s3Destination - Operations
GET(Permissions: admin, operator)SET(Permissions: admin)
- Attributes
- Nullable: Yes
- Dynamic Support: No / Dynamic Enum: No / Dynamic Range: No
Actions
This entity has no actions.
Data types
authorizationServer
- Type: complex
- Fields
- clientAuthenticationMethod
- Type:
ClientAuthenticationMethod - Nullable: No / Gettable: No
- Type:
- clientId
- Type: string
- Nullable: No / Gettable: No
- tokenEndpoint
- Type: string
- Nullable: No / Gettable: No
- clientAuthenticationMethod
Configuration of an external authorization server.
Retrieve the credentials to the object store with the OAuth 2.0 Client Credentials Flow.
The authorization uses the OpenID Connect 1.0 specification, while clientAuthenticationMethod determines the method that should be used for authentication to the token endpoint configured in the tokenEndpoint field.
Documentation on how the request to the token server, see ClientAuthenticationMethod. The authorization server is expected to reply with a JSON response containing the credentials used to access the Object Store. Example response:
{
"access_token": "secretSASToken",
"expires_in": 3600,
"token_type": "azure"
}
Mandatory fields in the JSON response:
| Key | Description |
|---|---|
access_token | The Azure SAS or S3 session token. |
expires_in | Number of seconds the access token is valid. |
token_type | "s3" or "azure". |
Optional fields in the JSON response:
| Key | Description |
|---|---|
azure_container | The container for an Azure destination. |
azure_url | The url for an Azure destination. |
s3_bucket | The bucket for an S3 destination. |
s3_accesskey | The access key for an S3 destination. |
s3_secretkey | The secret key for an S3 destination. |
s3_region | The region for an S3 destination. |
s3_url | The url for an S3 destination. |
If the authorization server only supplies the mandatory fields the destination needs to be supplemented with the datatypes.AzureDestination or datatypes.S3Destination field set.
The fields returned in the JSON response from the authorization server overrides the values set in the Azure or S3 specific fields.
azureDestination
- Type: complex
- Fields
- accountName
- Type: string
- Nullable: No / Gettable: No
- container
- Type: string
- Nullable: No / Gettable: No
- sas
- Type: string
- Nullable: No / Gettable: No
- sharedKey
- Type: string
- Nullable: No / Gettable: No
- url
- Type: string
- Nullable: No / Gettable: No
- accountName
This data type contains the Azure specific settings. Valid combinations of authorization parameters are accountName, sharedKey or sas. If accountName and sharedKey is supplied url can be omitted. If the destination contains an authorization configuration it is allowed to omit both sharedKey and sas.
All get operations returning the azureDestinationType will hide the contents of the fields sharedKey and sas. Any unset property will be returned as empty strings.
ClientAuthenticationMethod
- Description: The Client Authentication method
- Type: string
- Enum Values:
"private_key_jwt"
This data type describes the valid values for client authentication methods.
The different authentication methods are based on the OpenID Connect 1.0 specification.
If private_key_jwt is used as the client authentication method, a Certificate Set needs to be configured with the certificate used when signing the JWT. When the destination is added with a authorizationServerType included, a Certificate Set is created with the same name as the id field of the destination.
Once the destination is created, add the certificate that should be used with the Certificate Set. The Certificate Set name has to be unused prior to adding the destination, otherwise the Add request will be rejected.
The following request will configure the certificate used by the destination:
http://ip-address/vapix/services
SOAP input parameters:
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:acert="http://www.axis.com/vapix/ws/cert"
xmlns:acertificates="http://www.axis.com/vapix/ws/certificates">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<acertificates:SetCertSet>
<acertificates:CertSetName>authServerDestinationId</acertificates:CertSetName>
<acertificates:CertSet>
<acert:Certificates>
<acert:Id>installedCertID</acert:Id>
</acert:Certificates>
<acert:CACertificates />
<acert:TrustedCertificates />
</acertificates:CertSet>
</acertificates:SetCertSet>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Once the certificate is configured in the CertSet the device will do a POST request to the configured tokenEndpoint with the generated JWT.
As an example, the JWT from the device to the authorization server can look like this:
{
"iss": "clientId",
"sub": "clientId",
"aud": "authServerTokenEndpoint",
"exp": 1618884477,
"jti": "uuid-generated-for-each-request"
}
An example HTTP request to the authorization server can look as follows. This example assumes that clientAuthenticationMethod is set to private_key_jwt, where the client_assertion is a base64 encoded JWT with a signature.
POST /auth_server_path HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth
%3Aclient-assertion-type%3Asaml2-bearer&
client_assertion=PHNhbW...[omitted for brevity]...ZT
DiskIdString
- Description: The disk ID.
- Type: string
- Minimum Length: 1
- Maximum Length: 50
- Pattern:
^[a-zA-Z0-9_-]+$
FailoverConfiguration
- Description: Configuration for local failover storage, used to temporarily store objects that can't be uploaded to the remote object store. When set to null, failover is disabled.
- Type: complex
- Fields
- diskId
- Description: The ID of the disk to store objects for failover in
MANUALmode, where it must be explicitly set. Default: null (not configured). - Type:
DiskIdString - Nullable: Yes / Gettable: Yes
- Description: The ID of the disk to store objects for failover in
- diskSelection
- Description: The failover disk selection mode. Default:
AUTO. - Type:
FailoverDiskSelection - Nullable: No / Gettable: Yes
- Description: The failover disk selection mode. Default:
- storageLimit
- Description: The maximum failover storage size, in kibibytes (KiB). Only applies in
MANUALmode. Default: null (unlimited). - Type:
PositiveInteger - Nullable: Yes / Gettable: Yes
- Description: The maximum failover storage size, in kibibytes (KiB). Only applies in
- uploadLimit
- Description: The maximum upload bandwidth for objects stored in failover, in kbit/s. Default: null (unlimited).
- Type:
PositiveInteger - Nullable: Yes / Gettable: Yes
- diskId
FailoverDiskSelection
- Description: Failover disk selection mode.
- Type: string
- Enum Values: "AUTO", "MANUAL"
idString
- Description: The ID for a destination
- Type: string
- Minimum Length: 1
- Maximum Length: 50
- Pattern:
^[a-zA-Z0-9_]+$
PositiveInteger
- Description: Positive integer value.
- Type: integer
- Minimum Value: 1
s3Destination
- Type: complex
- Fields
- accessKeyId
- Type: string
- Nullable: No / Gettable: No
- bucket
- Type: string
- Nullable: No / Gettable: No
- region
- Type: string
- Nullable: No / Gettable: No
- secretAccessKey
- Type: string
- Nullable: No / Gettable: No
- sessionToken
- Type: string
- Nullable: No / Gettable: No
- url
- Type: string
- Nullable: No / Gettable: No
- accessKeyId
This data type contains the S3 specific settings. The field sessionToken can be left empty if temporary access credentials are not to be used. If the destination contains an authorization configuration the fields accessKeyId, secretAccessKey and sessionToken can be left empty.
All get operations returning the s3DestinationType will hide the contents of the fields accessKeyId, secretAccessKey and sessionToken.
If the field region is empty, us-east-1 will be used as default value instead.
Any unset field will be returned as empty string.