API Gateway configuration files
API Gateway configuration files are located in the installation location, by default %ProgramFiles%\Milestone\XProtect API Gateway\
.
These configuration files are relevant for the API Gateway:
-
appsettings.json
: Reverse proxy (routing), CORS, WebRTC, log levels, etc. -
appsettings.Production.json
: Overrides the configuration settings inappsettings.json
. -
nlog.config
: Log layout, log targets, etc.
Editing configuration files
Use a validating editor to edit configuration files. Most popular code editors support JSON and XML syntax validation, either by default or through extensions.
appsettings.json and appsettings.Production.json
Do not edit appsettings.json
manually. This file is created by the product installer and maintained by the Server Configurator.
If you need to override a configuration setting in appsettings.json
, create appsettings.Production.json
and add configuration overrides here. appsettings.Production.json
will not be removed or changed by product updates.
To override configuration settings in appsettings.json
, copy the complete top level property from appsettings.json
to appsettings.Production.json
and remove the nested properties that you don't want to change.
For example, to change the management server host address but no other ReverseProxy
settings, include this in appsettings.Production.json
:
{
"ReverseProxy": {
"Clusters": {
"managementserver": {
"Destinations": {
"hostname": {
"Address": "https://test-02.example.com/"
}
}
}
}
}
}
If you add several properties to appsettings.Production.json
, remember to include a comma between the properties, but no trailing comma:
{
"Logging": {
"LogLevel": {
"Yarp": "Information"
}
},
"ReverseProxy": {
"Clusters": {
"managementserver": {
"Destinations": {
"hostname": {
"Address": "https://test-02.example.com/"
}
}
}
}
}
}
Reverse proxy
The reverse proxy (routing) functionality of the API Gateway is implemented using YARP.
This part of appsettings.json
is related to the reverse proxy functionality. The configuration is created by the product installer and maintained by the Server Configurator.
"ReverseProxy": {
"Routes": {
"well-known": {
"ClusterId": "managementserver",
"Match": {
"Path": "/.well-known/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/ManagementServer/.well-known/{**remainder}"
}
]
},
"rest-api": {
"ClusterId": "managementserver",
"Match": {
"Path": "/rest/v1/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/ManagementServer/Rest/{**remainder}"
}
]
},
"alarm-definitions-rest-api": {
"ClusterId": "managementserver",
"Match": {
"Path": "/rest/v1/alarmDefinitions/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/ManagementServer/Rest/alarmDefinitions/{**remainder}"
}
]
},
"events-rest-api": {
"ClusterId": "eventserver",
"Match": {
"Path": "/rest/v1/events/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/rest/events/v1/events/{**remainder}"
}
]
},
"alarms-rest-api": {
"ClusterId": "eventserver",
"Match": {
"Path": "/rest/v1/{resource:regex(^alarm.*)}/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/rest/alarms/v1/{resource}/{**remainder}"
}
]
},
"ws-messages": {
"ClusterId": "eventserver",
"Match": {
"Path": "/ws/messages/v1/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/ws/messages/v1/{**remainder}"
}
]
},
"ws-events": {
"ClusterId": "eventserver",
"Match": {
"Path": "/ws/events/v1/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/ws/events/v1/{**remainder}"
}
]
},
"idp": {
"ClusterId": "managementserver",
"Match": {
"Path": "/IDP/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/IDP/{**remainder}"
}
]
},
"share": {
"ClusterId": "managementserver",
"Match": {
"Path": "/share/{**remainder}"
},
"Transforms": [
{
"PathPattern": "/share/{**remainder}"
},
{
"X-Forwarded": "Append",
"Prefix": "Off"
},
{
"RequestHeader": "X-Forwarded-Prefix",
"Append": "/api/share"
}
]
}
},
"Clusters": {
"managementserver": {
"Destinations": {
"hostname": {
"Address": "https://test-02.example.com/"
}
}
}
}
}
For more information about YARP, please refer to YARP: Yet Another Reverse Proxy. 1
Cross-Origin Resource Sharing (CORS)
The API Gateway can be configured to support Cross-Origin Resource Sharing (CORS). The following response headers are supported:
CORS is disabled by default. You enable and configure CORS support by creating and editing appsettings.Production.json
.
-
Create
appsettings.Production.json
(if not already created). -
Enable and configure CORS response headers similar to this:
{ "CORS": { "Enabled": true, "Access-Control-Allow-Origin": "yourdomain1.com,yourdomain2.com", "Access-Control-Allow-Headers": "Content-Type", "Access-Control-Allow-Methods": "*" } }
-
Restart the IIS, or at least recycle
VideoOS ApiGateway AppPool
.
Only required response headers should be defined. Each response header can have multiple values, provided as a list of comma-separated values.
In a production system, always specify the Access-Control-Allow-Origin
value with explicit origins. Never use wildcard (*) or null in your origin as this can put the security of your system at risk.
For development and test purposes, you can use a very permissive policy:
{
"CORS": {
"Enabled": true,
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*"
}
}
This will allow calls from any origin, including a local file system, to the API Gateway.
For more information about CORS, please refer to Cross-Origin Resource Sharing (CORS)5.
WebRTC
WebRTC is a peer-to-peer protocol for streaming data, for example video.
STUN and TURN server addresses
To help establish a connection through NATs, WebRTC uses STUN (Session Traversal Utilities for NAT) and/or TURN (Traversal Using Relays around NAT) servers.
A STUN server is used to discover the public IP address and port number of a device behind a NAT.
A TURN server is used to relay traffic between peers when a direct connection is not possible due to firewall or NAT restrictions. TURN servers can also act as STUN servers.
No default STUN or TURN server URLs are configured API Gateway-side.
To specify STUN and/or TURN servers:
-
Create
appsettings.Production.json
(if not already created). -
Add a WebRTC object and add STUN and TURN server URLs, for example:
{ "WebRTC": { "iceServers": [ { "url": "stun:mystun.zyx:3478" }, { "url": "turn:mystun.zyx:5349" }, ] } }
-
Restart the IIS, or at least recycle
VideoOS ApiGateway AppPool
.
For more information about WebRTC, please refer to WebRTC API6
Logging
The API Gateway uses NLog for logging.
Logging is configured in two places:
-
appsettings.json
andappsettings.Production.json
: Log levels -
nlog.config
: Log layout, log targets, etc.
Log levels
This part of appsettings.json
is related to logging:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Yarp": "Warning"
}
}
}
To include YARP routing log messages, add a log level setting in appsettings.Production.json
for Yarp
, for example, Information
:
-
Create
appsettings.Production.json
(if not already created). -
Add the configuration that you want to override, for example:
{ "Logging": { "LogLevel": { "Yarp": "Information" } } }
-
Restart the IIS, or at least recycle
VideoOS ApiGateway AppPool
.
Log layout, log targets, etc
This is the default NLog configuration file nlog.config
:
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Warn"
internalLogFile="internal-nlog.txt">
<variable
name="logDirectory"
value="C:\ProgramData\Milestone\ApiGateway\Logs" />
<variable
name="archiveDirectory"
value="${var:logDirectory}\Archive" />
<variable
name="defaultLayout"
value="${date:format=yyyy-MM-dd HH\:mm\:ss.fffzzz} [${threadid:padding=6}] ${level:uppercase=true:padding=-10} - ${message} ${exception:format=tostring}" />
<targets>
<target
name="logfile"
xsi:type="File"
fileName="${var:logDirectory}\gateway.log"
archiveFileName="${var:archiveDirectory}\gateway-{####}.log"
archiveNumbering="Rolling"
maxArchiveFiles="20"
archiveEvery="Day"
archiveAboveSize="1000000"
archiveOldFileOnStartup="true"
createDirs="true"
layout="${var:defaultLayout}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
With the configuration setting autoReload="true"
,
NLog will monitor and reload the configuration file whenever it is modified. You can change the log configuration on the fly without restarting anything.
For more information about NLog configuration, please refer to NLog Configuration options.7