This is the multi-page printable view of this section. Click here to print.
Agile Content
- 1: Agile Processing
- 1.1: StreamBuilder
- 1.1.1: Repackaging (esb3002)
- 1.1.2: Live-ingest (esb3003)
- 1.1.3:
- 1.1.4: VoD to Linear (esb3019)
- 1.1.4.1: General
- 1.1.4.2: Details
- 1.1.4.3: Installation
- 1.1.4.3.1: Upgrades
- 1.1.4.4: Configuration and command-line arguments
- 1.1.4.4.1: Startup Configuration
- 1.1.4.4.2: Content Templates
- 1.1.4.4.3: Assets
- 1.1.4.4.3.1: Asset Track Matching
- 1.1.4.4.4: Repackager configuration
- 1.1.4.4.5: Channels
- 1.1.4.4.6: Licensing
- 1.1.4.5: Monitoring and Logging
- 1.1.4.6: how-to
- 1.1.4.6.1: Looping channels
- 1.1.4.6.2: Dynamic Channels
- 1.1.4.6.3: Test Output
- 1.1.4.7: API Reference
- 1.1.4.7.1: Channel REST API v1
- 1.1.4.7.2: Old API references
- 1.1.4.7.2.1: REST API v1 - release 1.0
- 1.1.4.7.2.2: REST API v1 - release 1.2.0
- 1.1.4.7.2.3: REST API v1 - release 0.10
- 1.1.4.7.2.4: REST API v1 - release 0.8
- 1.1.4.8: Credits
- 1.1.4.9: Releases
- 1.1.4.9.1: Release 1.6.0
- 1.1.4.9.2: Release 1.4.0
- 1.1.4.9.3: Release 1.2.0
- 1.1.4.9.4: Release 1.0.0
- 1.1.4.9.5: Release 0.10.0
- 1.1.4.9.6: Release 0.8.1
- 1.1.4.9.7: Release 0.8.0
- 1.1.4.9.8: Release 0.6.1
- 1.1.4.9.9: Release 0.6.0
- 1.1.5: Manifest Manipulation (esb3020)
- 1.1.5.1: Introduction
- 1.1.5.2: Installation
- 1.1.5.2.1: Upgrades
- 1.1.5.3: Configuration
- 1.1.5.3.1: Licensing
- 1.1.5.4: Monitoring and Logging
- 1.1.5.5: How-to guides
- 1.1.5.5.1: Pre-rolls
- 1.1.5.5.2: HLS Target Duration
- 1.1.5.6: Releases
- 1.1.5.6.1: Release 1.0.1
- 1.1.5.6.2: Release 1.0.0
- 1.1.5.6.3: Release 0.10.0
- 1.1.5.6.4: Release 0.8.1
- 1.1.5.6.5: Release 0.8.0
- 1.1.5.6.6: Release 0.6.0
- 1.1.5.7: Credits
- 1.1.6: VoD Ingest (esb3021)
- 1.1.6.1: Introduction
- 1.1.6.2: Installation
- 1.1.6.3: Tools
- 1.1.6.4: Convoy integrating
- 1.1.6.5: Performance
- 1.1.6.6: SMIL manifest
- 1.1.6.7: Supported codecs
- 1.1.6.8: HDR10 support
- 1.1.6.9: AWS S3 Cloud Usage
- 1.1.6.10: Releases
- 1.1.6.10.1: Release 1.12.0
- 1.1.6.10.2: Release 1.10.0
- 1.1.6.10.3: Release 1.8.0
- 1.1.6.10.4: Release 1.6.0
- 1.1.6.10.5: Release 1.4.0
- 1.1.6.10.6: Release 1.2.0
- 1.1.6.10.7: Release 1.0.0
- 1.1.6.10.8: Release 0.6.2
- 1.1.6.11: Licensing
- 1.1.7: VoD to JIT (esb3022)
- 1.1.7.1: Introduction
- 1.1.7.2: Configuration and Command Line Options
- 1.1.7.3: Credits
- 1.1.7.4: Releases
- 1.1.7.4.1: Release 1.0.0
- 1.1.7.5: Licensing
- 1.1.7.6: Logging
- 1.1.8: HLS Ingest (esb3023)
- 1.1.8.1: Introduction
- 1.1.8.2: Installation and Upgrades
- 1.1.8.3: Configuration and command-line arguments
- 1.1.8.4: Logging
- 1.1.8.5: Credits
- 1.1.8.6: Releases
- 1.1.8.6.1: Release 0.6.0
- 1.1.9:
- 1.1.10: Solutions
- 1.1.11: General
- 1.1.11.1: Monitoring and Logging
- 1.1.11.2: CCMI URLs
- 1.1.11.3: ESF Format
- 1.1.11.4: Licensing
- 1.2: Automatic Speech Recognition (as a service)
- 1.2.1: Getting Started
- 1.2.2: ASR Engine Configuration
- 1.2.3: Integrate ASR output with Cavena STU
- 1.2.4: API Reference
- 2: Agile Content Delivery
- 2.1: Components
- 2.1.1: ESB3024 Router
- 2.1.1.1: Getting Started
- 2.1.1.2: Installation
- 2.1.1.2.1: Installing a 1.14 release
- 2.1.1.2.1.1: Configuration changes between 1.12.1 and 1.14
- 2.1.1.2.2: Installing a 1.12 release
- 2.1.1.2.2.1: Configuration changes between 1.10.2 and 1.12
- 2.1.1.2.3: Installing release 1.10.x
- 2.1.1.2.3.1: Configuration changes between 1.8.0 and 1.10.x
- 2.1.1.2.4: Installing release 1.8.0
- 2.1.1.2.4.1: Configuration changes between 1.6.0 and 1.8.0
- 2.1.1.2.5: Installing release 1.6.0
- 2.1.1.2.5.1: Configuration changes between 1.4.0 and 1.6.0
- 2.1.1.3: Firewall
- 2.1.1.4: API Overview
- 2.1.1.5: Configuration
- 2.1.1.5.1: WebUI Configuration
- 2.1.1.5.2: Confd and Confcli
- 2.1.1.5.3: Session Groups and Classification
- 2.1.1.5.4: Advanced features
- 2.1.1.5.4.1: Content popularity
- 2.1.1.5.4.2: Consistent Hashing
- 2.1.1.5.4.3: Security token verification
- 2.1.1.5.4.4: Subnets API
- 2.1.1.5.4.5: Lua Features
- 2.1.1.5.4.5.1: Built-in Lua Functions
- 2.1.1.5.4.5.2: Global Lua Tables
- 2.1.1.5.4.5.3: Request Translation Function
- 2.1.1.5.4.5.4: Session Translation Function
- 2.1.1.5.4.5.5: Host Request Translation Function
- 2.1.1.5.4.5.6: Response Translation Function
- 2.1.1.5.5: Trusted proxies
- 2.1.1.5.6: Confd Auto Upgrade Tool
- 2.1.1.6: Operations
- 2.1.1.6.1: Services
- 2.1.1.7: Convoy Bridge
- 2.1.1.8: Monitoring
- 2.1.1.8.1: System troubleshooting
- 2.1.1.8.2: Scraping data with Prometheus
- 2.1.1.8.3: Visualizing data with Grafana
- 2.1.1.8.3.1: Managing Grafana
- 2.1.1.8.3.2: Grafana Dashboards
- 2.1.1.8.4: Alarms and Alerting
- 2.1.1.8.5: Monitoring multiple routers
- 2.1.1.8.6: Routing Rule Evaluation Metrics
- 2.1.1.8.7: Metrics
- 2.1.1.8.7.1: Internal Metrics
- 2.1.1.9: Releases
- 2.1.1.9.1: Release esb3024-1.14.2
- 2.1.1.9.2: Release esb3024-1.14.0
- 2.1.1.9.3: Release esb3024-1.12.1
- 2.1.1.9.4: Release esb3024-1.12.0
- 2.1.1.9.5: Release esb3024-1.10.2
- 2.1.1.9.6: Release esb3024-1.10.1
- 2.1.1.9.7: Release esb3024-1.10.0
- 2.1.1.9.8: Release esb3024-1.8.0
- 2.1.1.9.9: Release esb3024-1.6.0
- 2.1.1.9.10: Release esb3024-1.4.0
- 2.1.1.9.11: Release acd-router-1.2.3
- 2.1.1.9.12: Release acd-router-1.2.0
- 2.1.1.9.13: Release acd-router-1.0.0
- 2.1.1.10: Glossary
- 2.1.2: ESB3032 ACD Aggregator
- 2.1.2.1: Getting Started
- 2.1.2.2: Releases
- 2.1.2.2.1: Release esb3032-0.2.0
- 2.1.2.2.2: Release esb3032-1.0.0
- 2.1.2.2.3: Release esb3032-1.2.1
- 2.1.2.2.4: Release esb3032-1.4.0
- 2.1.3: ACD Cache
- 2.1.4: ESB3013 BGP Sniffer
- 2.1.5: Edgeware CDN Management System
- 2.1.6: ESB3008 Edgeware CDN Request Router
- 2.2: Introduction
- 2.3: Solutions
- 2.3.1: Cache hardware metrics: monitoring and routing
- 2.3.2: Private CDN Offload Routing with DNS
- 2.3.3: Monitor ACD with Prometheus, Grafana and Alert Manager
- 2.4: Use Cases
- 2.4.1: Route on GeoIP/ASN
- 2.4.2: Route on Subnet
- 2.4.3: Route on Content Type
- 2.4.4: Route on Content Popularity
- 2.4.5: Route on Selection Input
- 2.4.6: Adapt to multi-CDN
- 2.4.7: How to use ACD router for EDNS routing
- 2.4.8: How to use ESB3024 Router with Edgeware CDN Request Router
- 2.4.9: How to use ESB3024 Router with CoreDNS
- 2.4.10: How to use the Director as a replacement for Edgeware CDN Request Router
- 2.4.11: Use In-Stream Sessions
- 2.5: Ready for Production?
- 2.5.1: Setup for Redundancy
- 2.5.2: HTTPS Certificates
1 - Agile Processing
1.1 - StreamBuilder
1.1.2 - Live-ingest (esb3003)
1.1.3 -
1.1.4 - VoD to Linear (esb3019)
1.1.4.1 - General
The core of the ESB3019
product is ew-vod2cbm
.
The ew-vod2cbm
service provides linear video or audio channels via the Edgeware CBM HTTP interface from playlists of VoD assets.
The benefit of using the CBM
interface is that the EW repackager sees the source as an
ordinary live channel as a normal Edgeware
live channel as would originate from the Catchup Buffer Manager
(CBM)
and can thereby encrypt and package content in all its
usual output formats.
The HTTP interface also allows for running the ew-vod2cbm
service
on a different machine than the EW repackager ESB3002.
Main concepts
To get an efficient and versatile service, it is essential to prepare content in a stream-lined way so that playlists and other metadata content can be minimal and stitching of content can be done on GoP boundaries with no alignment issues.
The main concepts for such a solution are:
- Prepare content in a homogeneous way.
- Ingest content using ESB3005 into CMAF/ESF format or use DASH OnDemand assets
- Start up the server with or without assets and channels configured
- Use CBM HTTP interface for repackager integration
- Update the assets, channels, and schedules of the channels dynamically via the REST API.
Step 1 and 2 may be fulfilled by a recording of a live channel.
Such a recording can be made using the ew-recorder
tool of ESB3005 as described
in the ESB3005 user guide.
You can also start with VoD assets. If the VoD asset is already in DASH OnDemand
format it may work as it is, but otherwise it needs to be converted to ESF
format using the ESB3005 ew-recorder
component.
If the asset consists of SMIL + mp4 + subtitle files, it can also be ingested using
the new ESB3021 ew-vodingest
tool. That tool can also ingest a directory containing
mp4 and subtitle files without referring to a SMIL file.
Supported codecs and formats
The VoD assets must be in DASH OnDemand or Edgeware’s ESF format. In both cases, the audio and video should be in CMAF track files. For subtitles, the DASH OnDemand ingest uses one complete non-segmented side-car file per language, while ESF uses a CMAF track with wvtt segments
The supported codecs are
- video: AVC/H.264 and HEVC/H.265
- audio: AAC-LC, HE-AACv1, HE-AACv2
- DASH OnDemand subtitles: TTML, WebVTT, SRT, STL
- ESF subtitles: wvtt
1.1.4.2 - Details
ew-vod2cbm
service works1. Prepare content
All content must be reasonably similar in order to be stitched into a
continuous channel. For each channel a content template
is used to
define how the output linear channel will look when it comes to signaled
tracks, codecs, languages, bitrate, variant names etc. The
content template format is described in the Content Templates section.
For flexible content handling, the restrictions are rather loose and should be fulfilled by much content out there
- Constant video GoP duration, such as 1.92s, 2s, or 2.002s
- Constant sample duration (frame rate) in all input MP4 files
- Compatible tracks in all ingested content that should go into one channel. The track matching is described in the Asset Track Matching section
These requirements are quite relaxed compared to the early restrictions (v0.6.x) that required that audio and video had exactly the same segment duration, and segments were built by combining these.
2. Store content as ESF VoD assets
To get content in ESF/CMAF format, one can either use a recording or ingest
video using the Edgeware ESB3005 tool CMAF/ESF.
One can also ingest using the new ESB3021 ew-vodingest
tool.
However, it is beneficial that all VoD assets are very similar when it comes to resolutions, bit rates, SPS/PPS etc., so using a fixed encoding recipe is recommended.
To make it possible to combine sources with somewhat different
video parameter sets, the parameter sets are extracted for each
asset and signaled in band. This makes it possible for most players
to handle possible changes in encoding parameters.
Signaling-wise, this means that our output is compatible with
inband parameter codec configurations corresponding to avc3
and hev1
, respectively.
Alternatively, DASH OnDemand assets may be used.
3. Create channels as schedule playlists with ad periods
The live channels are defined by some fixed parameters and a schedule that may be dynamically updated via a REST API.
All entries in the schedule are specified in units of GoPs.
The playlist supports arbitrary GoP intervals of an asset and
will wrap if going beyond end of asset. One can also specify
the full asset by giving length=0, or specify to start with
the n
last GoPs by specifying the negative offset -n
.
A slate or filler asset of duration 1 GoP, may be set to
length N
and thereby repeat N
times.
An important part is to be able to split and rebuild output
segments from input GoPs. For example, one may have
4s segments with 2s GoPs as input and desire 6s segments as output.
This is achieved by splitting the input segments into GoPs and
build new segments from these GoPs.
This is specified by the parameters for a channel:
gopDurMS=2000
and nrGopsPerSegment=3
. At an ad boundary,
the actual duration of a segment will be changed so that an
ad period always start and end at a combined segment boundary.
For this to work, each
ad asset and asset between ads must consist of at least
nrGopsPerSegment
GoPs.
An ad in the schedule is indicated by a non-zero scteEventID
value.
If two “programs” in a row have the same scteEventID
, they are considered
to be one ad “pod”, with a CUE-OUT at the start of the pod, and a
CUE-IN at the end of the pod. When updating the schedule to remove ads, it
is important that full pods are removed.
If scteEventID
is set to -1, a unique event ID corresponding to the GoP number
where the ad break starts will be inserted in the output.
The assets referred to in the schedule need to be located and fetched.
This done by creating a map that maps assetIDs
to assetPaths
.
An initial mapping can be provided in config file, but more importantly,
the asset paths can be updated using a REST API.
The assetPaths
supports can be mounted file systems, HTTP URLs,
and S3 URLs. The metadata of the assets is loaded in an
LRU cache as part of the scanning of the schedule of a schedule.
Asset paths can be removed from the asset cache by sending a DELETE
command via the REST API, but only if the assets are not included in any schedule.
4. CBM HTTP interface for repackager integration
The EW repackager gets upstream live channels via an HTTP interface
towards CBM. The HTTP interface provides list of channels,
content_info.json, segment_times.json and actual “live” segments.
Since ew-vod2cbm
provides the same interface as the CBM, no change
is needed in the repackager to support ew-vod2cbm
.
The CBM segment_times.json data should be enough for signaling ads. The emsg boxes in segments should not be needed and are not added to the segments.
5. Repackager configuration
An ingestServer
needs to be configured in order for the repackager to know
where to fetch the vod2live channel. That configuration is described in
Configuration Repackager.
Finally, content should now be available from the repackager as
https://<server>/__cl/cg:vod2live/__c/<channel>/__op/default/__f/index.m3u8
where the cg:vod2live
is the channel group for the vod2live channel.
6. Schedule update of a channel
Once a channel is created, its top level parameters cannot be changed. However, it is possible to change the schedule of a channel, but replacing it. The replacement must be done in a careful way to achieve a manifest which are consistently changed over time. There are more details on how to do this in the Dynamic Channels How-To guide.
1.1.4.3 - Installation
The vod2cbm service is distributed as a CentOS/Red Hat RPM and is available
as ew-vod2cbm.service
when installed. It works both on RH 7 and 8 and
compatible versions.
To install version x.y.z, the rpm
command can be used as follows:
yum install ./ew-vod2cbm-x.y.z-1.el8.x86_64.rpm
The service can be controlled with the standard systemctl
commands:
systemctl start ew-vod2cbm
systemctl stop ew-vod2cbm
systemctl status ew-vod2cbm
Logs from the service can be seen using journalctl -u ew-vod2cbm
.
The unit file is available in /usr/lib/systemd/system/ew-vod2cbm.service
and
starts ew-vod2cbm
, serving port 8090 by default.
When run as a service, ew-vod2cbm reads its initial configuration from
/etc/edgeware/ew-vod2cbm/config.json
. The configuration may contain a schedule
for looping channels. Non-looping channels must be created over the Channel
REST API. For details on scheduling please refer to the
API Reference
To uninstall the service, do:
yum remove ew-vod2cbm
When uninstalling or upgrading it is recommended to first stop the service.
1.1.4.3.1 - Upgrades
Upgrade to v1.2.x from v1.0.x
There is a new parameter padLastGop
in the REST API,
as well as the local JSON configuration for a channel/schedule.
If that is not set, a last shorter GoP will be truncated from
an asset. Set it if you want the new padding functionality to
be applied.
Upgrade to v1.0.x from v0.10.x
The main new thing is the online license file that must be available in order to run the service fully.
Upgrade to v0.10.x from v.0.8.x
The command-line parameter -gopdurms
is no longer needed or supported.
The config file is also no longer mandatory.
The command-line parameter -s3
has changed name to -s3file
.
Upgrade to v0.8.x from v.0.6.x
The segmentation and splicing is now based on GoPs instead of segments.
There is a new mandatory parameter, defaultGopDurMS
that must
be provided in the configuration file, or provided as a command line option
-gopdurms
.
The config file has changed to be based on GoPs instead of segments. Therefore, there are a few new parameters for each channel:
"segDurMS" -> "gopDurMS"
"combineNrSegs" -> "nrGopsPerSegment":
Here, the gopDurMS
must be the GoP duration for all input
video variants of all input content. The actual segment duration
of the content is not relevant. The end GoP may be shorter,
but is then dropped.
The input segment duration is not fixed, as long each video segment consists
of an integral number of GoP. The output segments are generated by combining
nrGopsPerSegment
GoPs, with a possible adjustment where ads start and stop.
Another update of the channel configuration is inside “schedule” where
"Programs" -> "Entries"
For dynamics schedules, it is recommended to use the REST API to handle channels.
1.1.4.4 - Configuration and command-line arguments
The ew-vod2cbm
global service parameters can be specified in the following ways:
- On the command-line
- As environment variables
- In the configuration file (when specified by the command-line)
- Default values
This also shows the order of precedence from top to bottom, where values on the command-line will override all other values.
The global service parameters cannot change during execution,
except for logging
.
An example configuration file is available in Example Configuration.
Note that the typical way of creating and configuring channels and assets is over the
REST API. It is also possible to configure
assets and channels in the configuration file. This can be handy mostly for testing.
A channel parameter, when present, will override the corresponding global
parameter. For example the global parameter defaultMaxliveWin
would be overridden
by the channel parameter maxLiveWindowS
.
The command-line
All command line parameters and environment variables can be seen by running:
ew-vod2cbm -h Usage of ew-vod2cbm: ew-vod2cbm produces linear video channels from VoD assets with the same interface as the ESB3003 catchup buffer mgr (CBM). Run ew-vod2cbm with options: -cachedcfg string Location of cached channel/assetpath configuration file -cfg string Config file -defaultMaxBitratePercentAbove int Global fallback percentage value for max higher allowed bitrate compared to a matching master track -defaultMaxBitratePercentBelow int Global fallback percentage value for max lower allowed bitrate compared to a matching master track -defaultMaxliveWin int Max live window [seconds] (default 14400) -licenseFile string Location of ew-vod2cbm license file (default "/etc/edgeware/ew-vod2cbm/license.json") -logformat string Format and type of log: [consolejson consolepretty journald discard] (default "consolejson") -loglevel string Initial log level (default "info") -port int Server TCP port (default 8090) -routes Generate a markdown file with HTTP routes -s3file string S3 credentials file -timeout int Maximum time in seconds before HTTP requests fail. Set to 0 to disable (default 60) -timesubs Generate time subtitles -version Get version, date, and possible expiration date The corresponding environment variables are: EW_ESB3019_PORT EW_ESB3019_DEFAULT_MAX_LIVE_WIN EW_ESB3019_TIMEOUT EW_ESB3019_LICENSE_PATH EW_ESB3019_CFG EW_ESB3019_DEFAULT_MAX_BITRATE_PERCENT_ABOVE EW_ESB3019_LOG_FORMAT EW_ESB3019_CACHED_CFG_PATH EW_ESB3019_S3_FILE EW_ESB3019_DEFAULT_MAX_BITRATE_PERCENT_BELOW EW_ESB3019_LOG_LEVEL Command-line parameters will always override envirionment variables and configured values.
1.1.4.4.1 - Startup Configuration
When starting the ew-vod2cbm service, a configuration file may be provided. This file enables starting ew-vod2cbm with predefined assets, channels and schedules. These items can also be added and updated via the REST API when the service is running.
If a path to a cached configuration is set, any change of the configuration via the REST API results in that the complete configuration of asset paths, channels and their schedules are written to a file at that path. On restart, an existing file at this path is used to restore the last dynamic configuration, while any static configuration of these settings is skipped.
However, if a path to a cached configuration is set, either via a command line parameter -cachedcfg
or the corresponding environment variable, such a file will be used to restore the last
dynamic configuration of asset paths and channels.
The static configuration of these entities will then be ignored, unless the parsing of the cache
configuration fails.
JSON Schema for configuration file
The JSON snippet below provides a description of the schema and the parameters that applies to configuration file for ew-vod2cbm.
The masterAssetID
will be deprecated in a future release.
{
"defaultMaxBitratePercentAbove": {
"description": "When matching a variant, this sets the maximum upper boundary in percent for the bitrate",
"type": "integer",
"minimum": 0,
},
"defaultMaxBitratePercentBelow": {
"description": "When matching a variant, this sets the maximum lower boundary in percent for the bitrate",
"type": "integer",
"minimum": 0,
"maximum": 100,
},
"defaultMaxLiveWindowS": {
"description": "The maximum length of the live window in seconds",
"type": "integer",
"minimum": 10,
"maximum": 36000,
},
"assets": {
"description": "list of assets",
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"path"
],
"properties": {
"id": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
},
"channels": {
"description": "Channels for ew-vod2cbm at startup",
"type": "array",
"items": {
"type": "object",
"required": [
"gopDurMS",
"name",
"nrGopsPerSegment",
"schedule"
],
"properties": {
"doLoop": {
"description": "Loop schedule or not",
"type": "boolean"
},
"gopDurMS": {
"description": "Exact millisecond duration of all video GoPs in all assets",
"type": "integer",
"minimum": 320,
"example": 2000
}
"contentTemplatePath": {
"description": "Path to the content template file. If this is used, masterAssetID should not be specified.",
"type": "string"
},
"masterAssetID": {
"description": "ID of the asset to use as a content template. If this is used, contentTemplatePath should not be specified.",
"type": "string"
},
"maxBitratePercentAbove": {
"description": "Percent diff above for when matching a track from the content template",
"type": "integer"
},
"maxBitratePercentBelow": {
"description": "Percent diff below for when matching a track from the content template",
"type": "integer"
},
"name": {
"description": "Unique name",
"type": "string",
"minLength": 2,
"example": "Channel 1"
},
"nrGopsPerSegment": {
"description": "How many GoPs to include in an average output segment",
"type": "integer",
"minimum": 1,
"example": 3
},
"schedule": {
"description": "The current scedule of the channel",
"type": "object",
"required": [
"entries"
],
"properties": {
"entries": {
"description": "list of programs or other entries",
"type": "array",
"items": {
"type": "object",
"required": [
"assetID",
"length",
"name"
],
"properties": {
"assetID": {
"description": "Asset identifier",
"type": "string",
"minLength": 2,
"example": "asset1234568-22"
},
"length": {
"description": "How many GoPs to play in asset. 0 is until end of asset. Beyond end results in wrap to start",
"type": "integer",
"example": 2400
},
"name": {
"description": "Name to include in EPG",
"type": "string",
"minLength": 2,
"example": "The Shark"
},
"offset": {
"description": "Zero-based GoP nr to start in asset. Negative value means from end",
"type": "integer"
},
"scteEventID": {
"description": "SCTE-35 Event ID in SCTE message. A non-zero value signals an ad. If scteEventID is set to -1, a unique event ID corresponding to the GoP number where the ad break starts will be inserted in the output.",
"type": "integer",
"minimum": -1
}
}
}
},
"gopNrAfterLastAd": {
"type": "integer"
},
"gopNrAtScheduleStart": {
"type": "integer"
}
}
},
"startTimeS": {
"description": "Start time relative epoch (1970-01-01) in seconds",
"type": "integer",
"minimum": 0
}
}
}
}
}
Example configuration
An example configuration file for two channels where all assets have relative paths may look like:
{
"defaultMaxBitratePercentAbove": 5,
"defaultMaxBitratePercentBelow": 20,
"assets": [
{"id": "bbb", "path": "app/testdata/assets/bbb"},
{"id": "slates/slate_pre_ad", "path": "app/testdata/assets/slates/slate_pre_ad"},
{"id": "slates/slate_post_ad", "path": "app/testdata/assets/slates/slate_post_ad"},
{"id": "slates/slate_black", "path": "app/testdata/assets/slates/slate_black"},
{"id": "whistler", "path": "app/testdata/assets/whistler"},
{"id": "ed", "path": "app/testdata/assets/ed"}
],
"channels": [
{
"name": "quick",
"gopDurMS": 1920,
"nrGopsPerSegment": 2,
"contentTemplatePath": "location/of/content_template.json"
"startTimeS": 0,
"doLoop": true,
"maxBitratePercentAbove": 10,
"maxBitratePercentBelow": 30,
"schedule": {
"GopNrAtScheduleStart": 0,
"GopNrAfterLastAd": 0,
"Entries": [
{
"name": "Big Buck Bunny",
"assetID": "bbb",
"offset": -3,
"length": 3
},
{
"name": "Ad upcoming",
"assetID": "slates/slate_pre_ad",
"offset": 0,
"length": 1,
"scteEventID": 123
},
{
"name": "Whistler ad",
"assetID": "whistler",
"offset": 0,
"length": 4,
"scteEventID": 123
},
{
"name": "Ad finished",
"assetID": "slates/slate_post_ad",
"offset": 0,
"length": 1,
"scteEventID": 123
},
{
"name": "Elephants dream",
"assetID": "ed",
"offset": 3,
"length": 4
}
]
}
},
{
"name": "test",
"gopDurMS": 1920,
"nrGopsPerSegment": 3,
"contentTemplatePath": "location/of/content_template.json"
"startTimeS": 0,
"doLoop": true,
"schedule": {
"GopNrAtScheduleStart": 0,
"GopNrAfterLastAd": 0,
"Entries": [
{
"name": "Big Buck Bunny",
"assetID": "bbb",
"length": 0
},
{
"name": "Black 10s",
"assetID": "slates/slate_black",
"offset": 0,
"length": 5
},
{
"name": "Whistler ad",
"assetID": "whistler",
"length": 0,
"scteEventID": 123
},
{
"name": "Elephants dream",
"assetID": "ed",
"offset": 0,
"length": 0
}
]
}
}
]
}
1.1.4.4.2 - Content Templates
Contents templates are used in ew-vod2cbm to specify the output segmentation and tracks of a channel, but also serve as measures to check if asset entries in a schedule are compatible with the channel. They are further used to generate the manifest and playlist media data properties as well as the media init segments. Therefore, bitrate, resolution, frame rate, video parameter sets, number audio channels are included in the template. The assets do not need to have exactly the same parameter values, but are allowed to vary as described later.
The generally preferred way of creating content templates, is to use
ew-content-template-tool
, described below.
JSON Schema for Content Template
The JSON schema of the content template contains core parameters of the
content_info.json
schema, and some additional parameters for bitrate matching.
It can contain variants of video, audio, and subtitles as signaled in the media_type
field.
The variant array can contain multiple variants
of each type. The table below the schema shows the required parameters for each
media type.
{
"type": "object",
"properties": {
"version": {
"type": "string"
},
"constant_gop_duration_ms": {
"type": "integer"
},
"variants": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"media_type": {
"type": "string"
},
"subtype": {
"type": "string"
},
"name": {
"type": "string"
},
"bitrate": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
},
"sample_aspect_ratio": {
"type": "string"
},
"picture_aspect_ratio": {
"type": "string"
},
"scan_type": {
"type": "string"
},
"sps": {
"type": "string"
},
"pps": {
"type": "string"
},
"codec": {
"type": "string"
},
"frame_rate_fraction": {
"type": "array",
"items": [
{
"type": "integer"
},
{
"type": "integer"
}
]
},
"num_channels": {
"type": "integer"
},
"samplerate": {
"type": "integer"
},
"decoder_config": {
"type": "string"
},
"lang": {
"type": "string"
},
"max_bitrate": {
"type": "integer"
},
"min_bitrate": {
"type": "integer"
}
},
"required": [
"media_type",
"name",
"bitrate",
"codec"
]
}
]
}
}
}
Depending on the media type, there are required fields for a variant. The table below lists all the required fields depending on media type.
Media type | Required fields |
---|---|
Video | media_type subtype name bitrate width height sample_aspect_ratio picture_aspect_ratio scan_type sps pps codec frame_rate_fraction |
Audio | media_type subtype name bitrate codec num_channels samplerate decoder_config lang |
Subtitles | media_type name bitrate lang codec |
The fields max_bitrate
and min_bitrate
are optional for all media types.
Example content template
{
"version": "1.0",
"constant_gop_duration_ms": 1920,
"variants": [
{
"media_type": "video",
"subtype": "h264",
"name": "V1000",
"bitrate": 1000000,
"width": 640,
"height": 360,
"sample_aspect_ratio": "1:1",
"picture_aspect_ratio": "16:9",
"scan_type": "progressive",
"sps": "6764001eacb201405ff2a0",
"pps": "68ebccb22c",
"codec": "avc1.64001E",
"frame_rate_fraction": [
25,
1
],
"max_bitrate": 1500000,
"min_bitrate": 900000
},
{
"media_type": "video",
"subtype": "h264",
"name": "V1500",
"bitrate": 1500000,
"width": 768,
"height": 432,
"sample_aspect_ratio": "1:1",
"picture_aspect_ratio": "16:9",
"scan_type": "progressive",
"sps": "6764001eacb201806f20",
"pps": "68ebccb22c",
"codec": "avc1.64001E",
"frame_rate_fraction": [
25,
1
],
"max_bitrate": 1600000,
"min_bitrate": 1400000
},
{
"media_type": "audio",
"subtype": "aac",
"name": "A128",
"bitrate": 128000,
"codec": "mp4a.40.2",
"num_channels": 2,
"samplerate": 48000,
"decoder_config": "1190",
"lang": "eng"
},
{
"media_type": "subtitles",
"name": "eng_1",
"bitrate": 1000,
"lang": "eng",
"codec": "wvtt"
}
]
}
Creating a Content Template: ew-content-template-tool
A content template does not need to created by hand. It can be created from an ingested asset with:
$ ew-content-template-tool
Usage: bin/ew-content-template-tool [OPTIONS] <content info path> <content_template_path> ...
Options:
-gop-dur-ms int
GOP Duration for template
-version
Get version and build date
For example:
$ ew-content-template-tool -gop-dur-ms 1920 content_info.json content_template.json
Note: The tool makes no verification that the media files actually fulfill the specified GOP duration.
Verifying Assets Before Scheduling: ew-verify-asset
Before attempting to schedule an asset, it can be verified that it matches a specific content template, with:
$ ew-verify-asset
Usage: ew-verify-asset [options]
-i, --input string Asset path
-t, --template string Content template file for the asset(s)
For example:
$ ew-verify-content -i media/matrix-revolutions/ -t content-templates/template_4sGOP_hevc.json
This tool will verify that the asset with regards to video-tracks, codecs etc. Missing subtitle tracks, and (secondary) audio tracks are allowed, and yield warnings.
Non-constant GOP lengths are detected, and rejected, for assets ingested with ew-vodingest
. Such irregularities are not detected for assets ingested with the older ew-recorder
.
1.1.4.4.3 - Assets
The video content of a ew-vod2cbm
consists of VoD video assets. Assets
are added to the server and then added to the schedule of a channel (this is
done either using the Schedule API or the Config) to the schedule of a channel. The way an asset is
specified for vod2cbm, is using a file path or URL to either a directory that contains a
content_info.json
file or directly to a DASH OnDemand manifest (must end with
file extension .mpd
). The content_info or manifest file of the asset contains the
necessary metadata to start processing it.
Asset requirements
The media tracks must be in one of the supported codecs and formats.
All assets of a channel must have a GoP duration that is “compatible” with the value specified in
the channel
configuration. Compatible here means that the channel
GoP duration must be a multiple
of the asset GoP duration. For example, an asset with 1s GoP duration is compatible with a channel with 2s
GoP duration.
That value is specified in the channel
configuration as gopDurMS
.
As a schedule is updated, all included assets’ metadata as well as the first part of each
video track is loaded in order to derive a GoP duration for that asset.
The metadata is cached for future use, while the actual video and audio media data
is not.
Another requirement is that all media samples
in an mp4 files must have the
same duration.
This is normally no problem if the content has fixed frame rate
and a timescale that is compatible with the frame rate and audio sample rate.
Padding the last asset GoP
It is not a requirement that the last GoP of an asset has the same duration as the others. It is natural
that the last GoP is shorter. Using the boolean padLastGop
parameter
in the channel/schedule configuration it is possible to determine whether
that last GoP will either be discarded or padded with silent audio and black video frames
to become as long as the others. The GoP duration in this context is the channel’s GoP
duration.
The padding influences the length of the asset.
As an example, consider an asset that has 32.5s duration, and has an IDR-frame every 1s.
If used in a channel with GoP duration 2s, the asset length is considered to be 32s
if padLastGop
is false, and 34s if padLastGop
is true. In the latter case, the last
1.5s will be padded with silent audio and black video frames to achieve the full duration
of an 2s GoP. The GoP duration of 1s of the actual asset, does not matter here, since
all segments are built from GoPs of the duration specified in the channel’s configuration.
If the channel entry for the asset specifies a length that wraps the asset to start from
the beginning, the padding is included in the video so that a padded entry wraps later than
a non-padded entry.
The padding content
The silent audio is built by repeating silent audio frames from the corresponding audio codec and setting the timing parameters appropriately.
The black video is built by taking frames from a 500frames long I-P-P-P- sequence
of AVC or HEVC video. Since the content is just a black frame, the resolution does not
influence the image quality, so a fixed resolution of 640x360 pixels is currently used.
Since this content generally doesn’t match with the content of the variant being played,
all video is sent using inband signaling parameter sets, that is avc3
for H.264/AVC
hev1
for H.265/HEVC.
1.1.4.4.3.1 - Asset Track Matching
Matching rules
For a schedule to be valid, all assets must be compatible with the content template of the channel.
The compatibility check is done by a set of matching rules when a channel is created or when its schedule is updated. If one of the assets is not matching the content template, the schedule is discarded and an error is reported.
The matching is done by comparing the asset tracks with the tracks of the content template.
The first condition is equal media type. A video track will, for example, never be matched to an audio track.
The second condition depends on the media type of the track. Some media type-specific properties of a track, must always be identical to a track found in the content template for them to match. The table below lists the properties that must be identical for the respective media types between a track in an asset and a track in the content template.
Media type | Media properties that must match |
---|---|
Video | Media type subtype |
Audio | Media type subtype Codec Sample rate |
Subtitles | Media type Language Role |
The third condition regards the bitrate range.
By default, the bitrate of an asset track must be identical to the bitrate of
the corresponding content template track. However, the max_bitrate
and
min_bitrate
parameters in the content template allow for a range
of matching bitrates on track level.
More generally, there are also percentage values that can be specified for bitrates in either a channel configuration, or as global parameters at the top level of the config file or as command line parameters.
The channel parameters are called maxBitratePercentAbove
and maxBitratePercentBelow
,
while the global parameters are called defaultMaxBitratePercentAbove
and defaultMaxBitratePercentBelow
These are all optional with default value 0.
The rules for bitrate matching are applied in the following priority order:
- Use the track specific bitrate range if it exists
- Use the channel specific bitrate percentage range if it exists
- Use the command-line bitrate percentage range if it exists
- Use the top-level JSON bitrate percentage range if it exists
Only one of the rules will be applied (the one with the highest priority that is valid for the scope of the track we are trying to match to).
Cases of non-direct match
There does not need to be a one-to-one match between tracks. An asset which deviate from the content template in the following way should be accepted:
- Extra tracks are allowed and will be silently discarded
- Subtitle tracks may be missing. This results in corresponding empty subtitle segments
- Audio languages may be missing. Such a track will be replaced by tracks of another language. An example would be a channel where some programs are in English and some in Spanish.
Matching algorithm
The matching occurs when a schedule is being updated for a channel. If no match is found for any variant in any asset in the new schedule, the schedule is considered invalid, and an error is returned. The matching algorithm begins by sorting the variants in the content template by their bitrate in descending order. The same is done for every asset. Finally, each variant in the sorted list of template variants, will be matched with a compatible asset variant considering media type and the compatibility values listed in the table above.
The search for a compatible variant in the asset is started from the top of the sorted variant list in the content template. This ensures that the most appropriate variant in each asset will be coupled with a corresponding variant in the content template.
1.1.4.4.4 - Repackager configuration
The ESB3002 repackager needs to be configured with a new
“ingestServer” corresponding to the ew-vod2cbm
node.
First define a new ingestServer
under ingestServers
services.repackaging.locations.ingestServers
"ingestServers": [
{
"name": "vod2cbm",
"url": "http://127.0.0.1:8090"
}
]
Then define a new group channelGroup
for vod2live content:
services.repackaging.content.channelGroups
{
"channelGroups": [{
"locations": [
"vod2cbm"
],
"name": "vod2live"
}
]
}
1.1.4.4.5 - Channels
As described in the Startup Configuration section, one can start up the service with both assets and channels defined in the config file.
However, one can change this configuration by using the REST API. In this way one can
- Add asset paths
- Add channels
- Replace schedules of non-looping channels
- Delete channels
- Delete asset paths for assets which are not in any schedule
Schedule updates are further described in the Dynamic Channels section.
If a path to a cached configuration is set, any change of the configuration via the REST API results in that the complete configuration of asset paths, channels and their schedules are written to a file at that path. On restart, an existing file at this path is used to restore the last dynamic configuration, while any static configuration of these settings is skipped.
1.1.4.4.6 - Licensing
ew-vod2cbm
requires a valid license file to operate. The license file must be
obtained from Agile Content, and copied to /etc/edgeware/ew-vod2cbm/license.json
.
See further details here.
1.1.4.5 - Monitoring and Logging
Health check
You can check the health of the server by making a request to /healthz
, which
should return a 200 OK response.
Monitoring
For monitoring, ew-vod2cbm generates Prometheus
data available at /metrics
.
There are different metrics for the response times for segments for different media types.
All bucket and counter names start with ew_
, or more precisely:
ew_audio_segment_request_duration_milliseconds_bucket
ew_audio_segment_requests_total
ew_subs_segment_request_duration_milliseconds_bucket
ew_subs_segment_requests_total
ew_video_segment_request_duration_milliseconds_bucket
ew_video_segment_requests_total
Logging
To provide context to each log message, structured logging
is used. Thus
instead of free text log messages without any specific format, the log data is
to some extent divided into fields of name-value pairs, making the logs more
coherent and more suitable for processing by external tools.
Log messages related to a specific HTTP request include the log field named
request_id
which can be used to filter out specific requests.
The log field named topic
is always present and is used to separate different
areas of logging. The current topics are access
, messages
and error
, and
are used to log HTTP access, debug messages and panic stack traces,
respectively.
As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.
Log formats
When run from the command line ew-vod2cbm
can log in one of the formats
consolepretty
, consolejson
or journald
depending on the value of the
-logformat
parameter. Logging can be disabled by using the value discard
.
$ ew-vod2cbm -upstream http://127.0.0.1 -logformat consolejson
consolepretty
logs to standard output (stdout
) in a human-readable format.
Each log line starts with the date and the log message followed by the context-
dependent log fields:
2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...
consolejson
logs to stdout
using a JSON object for each message:
{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}
When run as a systemd
service, ew-vod2cbm
logs directly to journald
using
the logjournald
configuration parameter. When stored in journald
, field
names are upper case whereas the values keep their format. Some examples:
To see entries with the topic access
:
$ journalctl -u ew-vod2cbm TOPIC=access -o verbose
To see entries with a specific request ID:
$ journalctl -u ew-vod2cbm REQUEST_ID="host/B1Po0eYz1d-000006" -o verbose
To see the call stack in the event of a crash:
$ journalctl -u ew-vod2cbm TOPIC=error -o verbose
Using the verbose
output includes all available name-value fields. Without
this only the log message is printed. The field named JSON
contains the
original structured log message as sent by the service. To filter out only
this field --output-fields=JSON
can be used, however this requires a systemd
version of at least 236.
$ journalctl -u ew-vod2cbm --output-fields=JSON TOPIC=access
To continuously monitor the service:
$ journalctl -fu ew-vod2cbm
Log levels
At startup the log level is set to info
.
The log level can be changed by posting a form-field named level
to the
loglevel
endpoint on the ew-vod2cbm
server:
$ curl -F level=debug ew-vod2cbm-server:8090/loglevel
The available log levels and how they relate to systemd priority values is listed below:
Log level Systemd priority
trace 7
debug 7
info 6
warn 4
error 3
fatal 2
panic 0
To e.g. see all error and warning messages using journalctl:
$ journalctl -u ew-vod2cbm PRIORITY=3 PRIORITY=4
Use a GET request to see the current log level:
$ curl ew-vod2cbm-server:8090/loglevel
Messages with higher level than the configured one will not be logged.
1.1.4.6 - how-to
1.1.4.6.1 - Looping channels
The simplest channel to set up is a looping channel.
Such a channel has a fixed schedule and the programs of that channel are presented over and over again and will never stop.
A looping channel can be setup via the
REST API, but it can
also be setup using a configuration file as examplified in the
Startup configuration.
Such channels have the doLoop
attribute set, and will run until
they are stopped. One can set the startTimeS
parameter to tell when
the first media should be “generated”, but there is no end time.
The default value startTime == 0
means that the channel will have
segments with a time relative to the start of the UNIX epoch
1970-01-01T00:00:00Z.
1.1.4.6.2 - Dynamic Channels
A flexible FAST channel has a schedule that is not fixed and looped, but has a limited window in the past and future. This can for example, be two hours back in time and 10 hours into the future.
To achieve such a “sliding window” of programs, the schedule needs to be updated by adding new entries and removing old ones. At the same time, the timeline needs to be continuous, and the generated DASH and HLS manifests must be consistent over time when it comes to discontinuities and period times.
A schedule update is done by posting a complete new schedule via the REST API to “/api/v1/schedule/{channel}”.
Removing old assets from the schedule
When removing old assets, it is important to keep a long enough window of old assets so that the sliding window for players is still available. This may be the last two hours or something similar.
To keep a consistent state when removing assets from the schedule, use the following two parameters:
- GopNrAtScheduleStart - the GoP number at which the schedule starts
- GopNrAfterLastAd - the GoP number right after the last ad before the schedule start
These should be updated like follows when one or more entries are dropped from the start of a schedule:
- GopNrAtSchedulStart should increase by the number of GoPs dropped
- GoPNrAfterLastAd should increase if an ad has been dropped
The source code in the Github repo edgeware/v2l-example-scheduler provides a simple example service that updates the schedule by adding and removing random entries and ads.
1.1.4.6.3 - Test Output
The ew-vod2cbm
service is targeted to provide a live stream
to the ESB3002 repackager, but for testing purposes it is also
possible to get media output that can be played directly with media players.
The supported output formats are HLS and DASH.
The media segments are in CMAF/fMP4 format with subtitles in
stpp/imsc1
format.
Direct HLS streams
A channel ch
can be reached as an HLS live asset using the URL
/ch/index.m3u8
The HLS playlist have SCTE-35 markers at the start and end of ad periods.
Direct DASH playback (new in v0.8)
A channel ch
can be reached as a DASH live asset using the URL
/ch/manifest.mpd
The DASH format is the simple SegmentTemplate with $Number$ format and does currently (v0.8) not include any SCTE-35 markers.
View as combined VoD
It is also possible to view a channel as an VoD asset by adding an extra
vod=1
query string to the URLs. This provides an HLS VoD playlist or
DASH static MPD. In both cases each subtitle track is provided as
a single big WebVTT file including all the subtitle cues.
Subtitle time track
To investigate timing and stitching of segments, it is possible to
enable an extra generated subtitle track for all channels. This is
done using the command line option -timesubs
.
1.1.4.7 - API Reference
1.1.4.7.1 - Channel REST API v1
The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.
However, an interactive Swagger API page is available
directly at the ew-vod2cbm server at <server>/swagger/
.
All API calls are relative to the base URL /api/v1/
.
A new addition in release 1.2.0 is padding of assets.
This is controlled via the boolean padLastGop
parameters on
channel and entry level, where the latter takes precedence
over the former.
For more information about how to use this API, see the howto section.
1.1.4.7.2 - Old API references
1.1.4.7.2.1 - REST API v1 - release 1.0
The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.
However, an interactive Swagger API page is available
directly at the ew-vod2cbm server at <server>/swagger/
.
All API calls are relative to the base URL /api/v1/
.
For more information about how to use this API, see the howto section.
1.1.4.7.2.2 - REST API v1 - release 1.2.0
The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.
However, an interactive Swagger API page is available
directly at the ew-vod2cbm server at <server>/swagger/
.
All API calls are relative to the base URL /api/v1/
.
For more information about how to use this API, see the howto section.
1.1.4.7.2.3 - REST API v1 - release 0.10
The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.
However, an interactive Swagger API page is available
directly at the ew-vod2cbm server at <server>/swagger/
.
All API calls are relative to the base URL /api/v1/
.
For more information about how to use this API, see the howto section.
1.1.4.7.2.4 - REST API v1 - release 0.8
The following is a rendering of the OpenAPI for the channels and schedules of ESB3019 using swagger. This page does not have a backend server, so it cannot be run interactively.
However, an interactive Swagger API page is available
directly at the ew-vod2cbm server at <server>/swagger/
.
All API calls are relative to the base URL /api/v1/
.
For more information about how to use this API, see the howto section.
1.1.4.8 - Credits
License List
The table below lists the third party libraries used by this software and their respective license types.
License Details
This section includes all the licenses/notices for each dependency verbatim
github.com/prometheus/common
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/swaggo/swag
license
MIT License
Copyright (c) 2017 Eason Lin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Comcast/gots
LICENSE
/* MIT License
Copyright 2016 Comcast Cable Communications Management, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
NOTICE
Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).
github.com/KyleBanks/depth
LICENSE
MIT License
Copyright (c) 2017 Kyle Banks
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/PuerkitoBio/urlesc
LICENSE
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/asticode/go-astikit
LICENSE
MIT License
Copyright (c) 2020 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/beorn7/perks/quantile
LICENSE
Copyright (C) 2013 Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/matttproud/golang_protobuf_extensions/pbutil
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
github.com/go-chi/chi/v5
LICENSE
Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-chi/docgen
LICENSE
Copyright (c) 2016-Present https://github.com/go-chi authors
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/josharian/intern
license
MIT License
Copyright (c) 2019 Josh Bleecher Snyder
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/client_model/go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/procfs
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.
Copyright 2014-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
gopkg.in/yaml.v2
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2011-2016 Canonical Ltd.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/asticode/go-astits
LICENSE
MIT License
Copyright (c) 2017 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/jsonreference
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-openapi/swag
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-playground/validator
LICENSE
The MIT License (MIT)
Copyright (c) 2015 Dean Karn
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/golang/protobuf
LICENSE
Copyright 2010 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/text
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/asticode/go-astisub
LICENSE
MIT License
Copyright (c) 2016 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/cespare/xxhash/v2
LICENSE
Copyright (c) 2016 Caleb Spare
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/zencoder/go-dash/v3
LICENSE
Copyright Brightcove, Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
golang.org/x/tools
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/aws/aws-sdk-go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.
github.com/coreos/go-systemd/v22/journal
LICENSE
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
- Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
- Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
- Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
- Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
- Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
- Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
- Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
- Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
CoreOS Project Copyright 2018 CoreOS, Inc
This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).
github.com/mailru/easyjson
LICENSE
Copyright (c) 2016 Mail.Ru Group
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/rs/zerolog
LICENSE
MIT License
Copyright (c) 2017 Olivier Poitrey
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
google.golang.org/protobuf
LICENSE
Copyright (c) 2018 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/sys
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/PuerkitoBio/purell
LICENSE
Copyright (c) 2012, Martin Angers All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/edgeware/mp4ff/bits
LICENSE
Copyright
Copyright (c) 2019-2020 Edgeware AB
.
Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits
Copyright (c) 2017 Taichi Nakashima
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-playground/universal-translator
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/leodido/go-urn
LICENSE
MIT License
Copyright (c) 2018 Leonardo Di Donato
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/client_golang/prometheus
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
The following components are included in this product:
perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.
Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.
Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0
github.com/swaggo/files
LICENSE
MIT License
Copyright (c) 2019 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/aws/aws-sdk-go/internal/sync/singleflight
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/edgeware/mp4ff
LICENSE
MIT License
Copyright (c) 2019-2020 Edgeware
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/jsonpointer
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/jmespath/go-jmespath
LICENSE
Copyright 2015 James Saryerwinnie
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/swaggo/http-swagger
LICENSE
MIT License
Copyright (c) 2018 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/edgeware/mp4ff/mp4
LICENSE
Copyright
Most code is Copyright (c) 2019-2020 Edgeware AB
.
Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has
Copyright (c) 2015 Jean-François Bustarret
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/spec
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-playground/locales
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
README
PACKAGE
package goautoneg import “bitbucket.org/ww/goautoneg”
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FUNCTIONS
func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.
func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses
TYPES
type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header
SUBDIRECTORIES
.hg
golang.org/x/net
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1.4.9 - Releases
ESB3019 - ew-vod2cbm releases
1.1.4.9.1 - Release 1.6.0
Change log
- NEW: API for refreshing updated assets [ESB3019-205]
- NEW: Timestamp format is accepted in Double and Open Ended requests. dateformat YYYYmmddTHHMMSSZ now accepted as start and stoptime (similar to ESB3002) [ESB3019-214]
- FIXED: Errors in ew-vod2cbm service when adding lots of assets. Fix of asset cache handling for case with many removed assets [ESB3019-170]
- FIXED: HLS master playlist is empty for video only content [ESB3019-171]
- FIXED: AVC subtype is not accepted. If content template has H264 as subtype for the same track, and vice versa [ESB3019-174]
- FIXED: Open-Ended and Double-Ended requests don’t work as expected [ESB3019-175]
- FIXED: ew-verify-asset is missing from ew-vod2cbm installer [ESB3019-179]
- FIXED: –gop-dur-ms argument in ew-content-template-tool is mandatory while it shouldn’t be [ESB3019-184]
- FIXED: Cannot access swagger for API specification [ESB3019-186]
- FIXED: Starting point of channel is incorrect after removing assets [ESB3019-190]
- FIXED: Incorrect SCTE35 signaling. Field out_of_network_indicator in CUE-IN is 1 while it should be 0 [ESB3019-193]
- FIXED: Conflict error is always returned when updating schedule via PUT method [ESB3019-194]
- FIXED: Invalid data is accepted to create channels [ESB3019-208]
- FIXED: Some fields in DASH manifest are not compliant with ESB3002 [ESB3019-209]
Release information
- Date: 2024-05-29
- Type: Product improvements
1.1.4.9.2 - Release 1.4.0
- Optional persistent cache of dynamic schedule and asset path configurations
- Content verification tool, for checking asset compatibility against content templates
- Improved handling of non-constant GoP duration
Release information
- Date: 2023-04-06
- Type: Product improvements
1.1.4.9.3 - Release 1.2.0
- The last GoP of an asset can now be padded to same length as the others
- Now supporting offline, as well as, online licensing
- Improved error messages for online licensing
- Support autofill of scteEventID [using Gop number] when configured to -1
- Fixed timestamp wrap-around
Release information
- Date: 2022-10-18
- Type: Product improvements
1.1.4.9.4 - Release 1.0.0
New: Support for shorter compatible GoP durations
New: Added utility for creating content templates:
ew-content-template-tool
New: The binary does not expire, it now requires a valid license to run
New: Support for AC-3/EC-3
New: Metrics for requested content
New: Improved GoP duration detection
New: Graceful service shutdown (handle outstanding requests)
Fix: EPG-offset for non-looping channels
Fix: Various scheduling bugs
Release information
- Date: 2022-05-17
- Type: First product release
1.1.4.9.5 - Release 0.10.0
- Track matching to allow for more flexibility when adding assets to a channel schedule.
- New
contentTemplatePath
parameter in channel configuration for specifying compatible assets. This is intended to replace and improve onmasterAssetID
. - New parameters to fine tune track matching via bitrate:
max_bitrate
andmin_bitrate
specified on a track levelmaxBitratePercentAbove
andmaxBitratePercentBelow
specified on channel levelmax_bitrate
andmin_bitrate
parameters in content template level and/or global level- global parameters for setting bitrate interval
- Global parameters can be set either as command line parameters or as environment variables
- New parameters to set maximal live window
- Remove
defaultGopDurMS
parameter and auto-detect GoP duration instead - Automatic extraction of
GoP duration
from assets to allow for matching - Support for HEVC video
- Support for
DASH OnDemand
assets without conversion to ESF format - New structured logging and better integration with
journald
- Assets with a missing subtitle track are allowed. An empty track will be generated automatically
- Assets with mismatch in audio language are allowed. Another language audio track is used instead
- Audio only support both via CBM interface and for direct HLS/DASH output
See Upgrade for information about how to upgrade
Release information
- Date: 2022-03-17
- Type: Beta for evaluation and testing
1.1.4.9.6 - Release 0.8.1
- Fix: handle assets where subtitle tracks have no cues (ESB3019-80)
- Fix: report configuration errors with proper JSON names (SUPPORT-10099, ESB3019-81)
See Upgrade for information about how to upgrade.
Release information
- Date: 2022-01-07
- Type: Beta bug fix for testing
1.1.4.9.7 - Release 0.8.0
- Segmentation based on GoPs instead of full segments
- REST API for dynamic change of channels and schedules
- Prometheus and health monitoring
- DASH output for testing
- Special live-time subtitle output for demo
See Upgrade for information about how to upgrade
Release information
- Date: 2021-12-22
- Type: Beta for testing
1.1.4.9.8 - Release 0.6.1
Bug fix: too small duration in SCTE-35 marker
Release information
- Date: 2021-06-01
- Type: Alpha bugfix for testing
1.1.4.9.9 - Release 0.6.0
Early release for generating live test content with SCTE-35 markers from recordings or other sources with fixed segment durations.
Output segments are generated by combining N segments, with variations of +/-N at an ad boundary.
Release information
- Date: 2021-05-30
- Type: Alpha for testing
1.1.5 - Manifest Manipulation (esb3020)
1.1.5.1 - Introduction
ew-manip
The service ew-manip
is a stateless manifest/playlist manipulator
for DASH and HLS. In the following, we use the term manifest to denote either a DASH
manifest or an HLS playlist.
ew-manip
is meant to be integrated with the nginx front of ew-repackager
(ESB3002) and can change DASH and HLS manifests depending on query parameters
in the URL.
The manipulations are triggered by a special query ewm=1
which must be at the start of the query string, and will
then do different manipulations depending on
options in the rest of the query.
The two modifications implemented this far are insertion of pre-roll assets in VoD manifests and change of HLS target duration for “live-like” HLS manifests coming from a live channel.
1.1.5.2 - Installation
The ew-manip service is distributed as a CentOS / Red Hat RPM and is available
as ew-manip.service
when installed. It works both on RH 7 and 8 and compatible
distributions.
To install version x.y.z, the yum
command can be used as follows:
yum install ./ew-manip-x.y.z-1.el8.x86_64.rpm
The service can be controlled with the standard systemctl
commands:
systemctl start ew-manip.service
systemctl stop ew-manip.service
systemctl status ew-manip.service
To uninstall version x.y.z using the yum
command, do:
yum remove ew-manip-x.y.z-1.el8.x86_64
When uninstalling or upgrading it is recommended to first stop the service.
1.1.5.2.1 - Upgrades
Upgrade to v0.10.x from v.0.8.x
The nginx configuration file ew-repackager-custom.conf
should no longer
contain the ew-manip specific location
. In regards to ew-manip, it should
rather only contain an include
to a newly installed file
/etc/edgeware/ew-manip/ew-manip-nginx.conf
. A more detailed description
regarding what should be in the /etc/ew-repackager/ew-repackager-custom.conf
file can be found here. The
reason for this change is so we can make ew-manip specific nginx changes in the
future without having users modifying an nginx file.
1.1.5.3 - Configuration
ew-manip
and the RepackagerConfiguring ew-manip
The ew-manip
global service parameters can be specified in the following ways:
- On the command line
- As environment variables
- Default values This also shows the order of precedence, where values on the command line, will override all other values.
The repackager is normally running as an HTTP server on port 80.
The ew-manip
service would typically run on the same host with the
default port 8094. The port can be changed in the service file at:
/usr/lib/systemd/system/ew-manip.service
key: ExecStart
If the repackager is not running on port 80, or on a different host from ew-manip
,
then this should be specified on the same line in the service file by adding:
-u <repackager-hostname:port>
In the resulting combined manifest, the pre-roll content URL will point to another asset, and its URL needs to be an absolute URL. This does not have to be configured since the full absolute URL must be sent in the query string.
Repackager configuration (nginx routing)
The nginx routing must be manually configured in the repackager. To do that, add
the following include
entry to the nginx config file at:
/etc/ew-repackager/ew-repackager-custom.conf
include /etc/edgeware/ew-manip/ew-manip-nginx.conf;
This will make requests with URLs ending with .m3u8
or .mpd
containing the string ewm=
at the start of the query string to
be forwarded to the ew-manip
server at http://localhost:8094
.
1.1.5.3.1 - Licensing
ew-manip
requires a valid license to operate. Some endpoints are accessible
without a valid license, but endpoints retrieving a manipulated
playlist/manifest are protected.
Requirements
- An internet connection on the machine running
ew-manip
- A valid license reference provided by Agile Content
Using the license reference
The license reference along with the product name must be stored in: /etc/edgeware/ew-manip/license.json. For example:
{
"license_ref": "this_is_an_example_license_ref",
"product_name": "ew-manip"
}
License validation
There will be an initial and then a periodic license check every 24 hours towards a license server once the service has started. The service will initiate a grace period if, and only if, the license server cannot be reached or the license server reports an internal error. The grace period will last for 2 hours if this is the license validation made during startup, and 7 days if this was a license validation that was made after a successful validation during startup (for internal license server errors, the grace period will always be 2 hours).
If an unsuccessful validation occurs, ew-manip
will do the verification more
often. This starts with one minute after the first fail, two minutes after the
second, doubling every time it fails. It will do so until it reaches 1024
minutes (~17 hours), and then do the verification every 1024 minutes. If the
license reference is successfully verified again, it will return to verifying
the reference every 24 hours.
In case license.json is changed, the ew-manip service must be restarted in order to update server data.
License information
There are mainly two ways of finding information regarding the license status in
the ew-manip
service, the logging, and an HTTP endpoint.
Logging
All license related logging has the topic logging
. Filtered logs with regard
to topic is described in Monitoring & Logging.
HTTP
The /licensing
endpoint of the ew-manip
service provides some information
regarding the licensing status. Currently, the information provided includes:
- A timestamp for when the last license validity verification occurred
- Timestamp for when the next license validity verification will occur
- Whether the current license reference is considered valid or not. If this is false, and there is no active grace period, requests to the protected endpoints will fail
- If the license is valid, this endpoint will also show the expiry date of the license
- If currently in a grace period, or the grace period has ended, a timestamp of when the grace period end is provided
1.1.5.4 - Monitoring and Logging
Health check
You can check the health of the server by making a request to /healthz
, which
should return a 200 OK response.
Monitoring
For monitoring, ew-manip generates Prometheus
data available at /metrics
.
There are different metrics for the response times for segments for different
media types. All bucket and counter names start with ew_
, or more precisely:
ew_hls_requests_total
ew_hls_request_duration_milliseconds
ew_dash_requests_total
ew_dash_request_duration_milliseconds
Logging
To provide context to each log message, structured logging
is used. Thus
instead of free text log messages without any specific format, the log data is
to some extent divided into fields of name-value pairs, making the logs more
coherent and more suitable for processing by external tools.
Log messages related to a specific HTTP request include the log field named
request_id
which can be used to filter out specific requests.
The log field named topic
is always present and is used to separate different
areas of logging. The current topics are access
, messages
and error
, and
are used to log HTTP access, debug messages and panic stack traces,
respectively.
As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.
Log formats
When run from the command line ew-manip
can log in one of the formats
consolepretty
, consolejson
or journald
depending on the value of the
-logformat
parameter. Logging can be disabled by using the value discard
.
$ ew-manip -logformat consolejson
consolepretty
logs to standard output (stdout
) in a human-readable format.
Each log line starts with the date and the log message followed by the context-
dependent log fields:
2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...
consolejson
logs to stdout
using a JSON object for each message:
{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}
When run as a systemd
service, ew-manip
logs directly to journald
using
the logjournald
configuration parameter. When stored in journald
, field
names are upper case whereas the values keep their format. Some examples:
To see entries with the topic access
:
$ journalctl -u ew-manip TOPIC=access -o verbose
To see entries with a specific request ID:
$ journalctl -u ew-manip REQUEST_ID="host/B1Po0eYz1d-000006" -o verbose
To see the call stack in the event of a crash:
$ journalctl -u ew-manip TOPIC=error -o verbose
Using the verbose
output includes all available name-value fields. Without
this only the log message is printed. The field named JSON
contains the
original structured log message as sent by the service. To filter out only
this field --output-fields=JSON
can be used, however this requires a systemd
version of at least 236.
$ journalctl -u ew-manip --output-fields=JSON TOPIC=access
To continuously monitor the service:
$ journalctl -fu ew-manip
Log levels
At startup the log level is set to info
. The log level can be changed at run
time by posting a form-field named level
to the loglevel
endpoint on the
ew-manip
server:
$ curl -F level=debug ew-manip-server:8094/loglevel
The available log levels and how they relate to systemd priority values is listed below:
Log level Systemd priority
trace 7
debug 7
info 6
warn 4
error 3
fatal 2
panic 0
To e.g. see all error and warning messages using journalctl:
$ journalctl -u ew-manip PRIORITY=3 PRIORITY=4
Use a GET request to see the current log level:
$ curl ew-manip-server:8094/loglevel
Messages with higher level than the configured one will not be logged.
1.1.5.5 - How-to guides
1.1.5.5.1 - Pre-rolls
The specific query-string trigger is a general escape query part ewm=1
which
will make nginx forward the request to the ew-manip
server. Pre-rolls assets
are then added in VoD with the query parameter pre=<URL>
. The <URL>
must be
the absolute public URL that the client uses to fetch the preroll video, since
this URL will be inserted in the combined manifest delivered to the client.
A complete request, to combine preroll-bumper
with program
could look like
this:
http://repack-host/__cl/s:vod/__c/program/__op/default/__f/index.m3u8?ewm=1&pre=https://public-repack-host/__cl/s:vod/__c/preroll-bumper/__op/default/__f/index.m3u8
Multiple pre=
query parts can be added to combine more than two manifests. The
service will then fetch all the manifests from the repackager and combine them
into the appropriate manifest with multiple periods for DASH or multiple parts
separated by discontinuities for HLS.
DASH manifest URLs look similar but must have the file extension .mpd
. HLS
playlist must have the file extension .m3u8
.
Limitations
DASH and HLS URLs cannot be combined with each other. For DASH, any assets can be combined, but for the best user experience it is reasonable to apply similar critera as for HLS. For HLS the following criteria must be met:
HLS Playlist Matching Criteria
In brief, the main and all the pre-roll master playlist(s) must match each other.
In detail, this means that:
For Renditions identified by
#EXT-X-MEDIA:
For each rendition in the main playlist, there must be exactly one corresponding rendition in each pre-roll playlist, and the following attributes (when present) must match exactly:TYPE
, andLANGUAGE
. Unmatched renditions in the pre-rolls will be discarded.- When matching renditions, in addition to the criteria mentioned above,
ew-manip
will match a rendition in the main playlist with the closest bitrate (without duplicate matching)
- When matching renditions, in addition to the criteria mentioned above,
For Variant streams identified by
#EXT-X-STREAM-INF:
For each variant stream in the main playlist, there must be exactly one corresponding variant stream in each pre-roll playlist, and the following attributes (when present) must match exactly:RESOLUTION
,FRAME-RATE
,CODECS
,AUDIO
,VIDEO
andSUBTITLES
. Unmatched variant streams in the pre-rolls will be discarded.For I-frame playlists identified by
#EXT-X-I-FRAME-STREAM-INF:
For each I-frame playlist in the main master playlist, there must be exactly one corresponding I-frame playlist in each pre-roll master playlist, and the following attributes (when present) must match exactly:RESOLUTION
andCODECS
. Unmatched I-frame playlists in the pre-rolls will be discarded.
Playlist requests where the main and pre-roll master playlists do not meet all
of the above criteria, will fail with an HTTP 400
error.
HLS Stream and Playlist Matching by Bandwidth
Typically there will be several variant streams that meet these criteria and
only differ in BANDWIDTH
. Within such matching groups (for example streams
with the same resolution) the main and pre-roll streams are paired together by
being sorted by bandwidth in decreasing order. The same pairing method is used
for I-frame playlists.
1.1.5.5.2 - HLS Target Duration
A common issue when playing live HLS is the value of target duration
(EXT-X-TARGETDURATION
).
The target duration is an integral number of seconds that correspond
to the longest segment in the stream. Depending on HLS version, this
value must either be higher than the longest duration, or can be rounded
to the closest integer, but many players desire a lower value
in order to work best. This is due to that the target-duration value influences
how often the client can ask for a playlist update.
Because live ingest node (ESB3003) generates segments with a precise average segment duration, adjusted segmentation boundaries due to SCTE-35 ad markers number may result in a single segment duration being 1.5 times the average duration. These singular values then effect the target-duration to become high.
To be able to fine-tune the target duration, the ew-manip
service has
an option to change the #EXT-X-TARGET-DURATON
value by using
the special query-string trigger target-duration=
once ew-manip
has
been triggered with the general ewm=1
trigger.
An example of a request that includes the target-duration=5
query parameter
to set #EXT-X-TARGET-DURATON
to 5seconds could look like this:
http://repack-host/__cl/cg:live/__c/program/__op/default/__f/index.m3u8?ewm=1&target-duration=5
This will only apply to “live-like” playlists from the repackager.
With “live-like” playlists, we mean playlists which come from a live channel
including an interval in the past. Such playlists can be
detected by searching for the part __cl/cg:
in the URL that indicates
that the URL is part of a live channel group. Media playlists with the stopTime
in the past are technically VoD playlists, but since there is a transition
from EVENT
to VOD
type of playlist as the stopTime
is passed, they
should be treated as live playlists.
For pure VoD assets, the target-duration can simply be calculated from the longest segment in the playlist, and there is in general no limit on how fast the segments can be requested, so there is no need for target duration modifications.
1.1.5.6 - Releases
ESB3020 - ew-manip releases
1.1.5.6.1 - Release 1.0.1
New:
- Licensing now incorporates a grace period in case of certain error cases described in Licensing
- The ew-manip service now gracefully exits when the service is stopped
Release information
- Date: 2022-05-19
- Type: Product release
1.1.5.6.2 - Release 1.0.0
Fixes:
- Solved a problem where the output DASH manifest was invalid if any pre-roll had DRM while the main asset had no DRM
New:
- Manipulating manifests/playlists requires a valid license
- Product binary has no expiry date
Release information
- Date: 2022-05-05
- Type: Product release
1.1.5.6.3 - Release 0.10.0
Fixes:
- Setting the target duration via the master playlists was not working properly
- HLS playlist matching has been fixed for certain subtitle use cases
- The transition from an encrypted preroll to an unencrypted asset is now signaled correctly in the HLS output
New:
- HLS alternative rendition’s GROUP-ID does not have to be identical for matching anymore
- Changed the way the nginx configuration is handled. See Upgrades
Release information
- Date: 2022-04-19
- Type: Beta for testing
1.1.5.6.4 - Release 0.8.1
Fixes:
- Failing HLS media playlist matching with different leaf pathnames has been fixed
Release information
- Date: 2022-02-16
- Type: Alpha for testing
1.1.5.6.5 - Release 0.8.0
Features:
- Improved DASH manifest handling
- Logging backend has been changed. The logging is now structured and is logged to journald
- Improved HLS variant stream and alternative rendition matching. The names of the variants and the alternatives do not have to be identical anymore.
- Prometheus counters for keeping track of number of requests received for HLS and DASH respectively
Fixes:
- File descriptor leak has been resolved
- For the EXT-X-MEDIA tag, the CHANNELS attribute is now preserved
Release information
- Date: 2022-02-14
- Type: Alpha for testing
1.1.5.6.6 - Release 0.6.0
Features:
- Add pre-roll videos to DASH and HLS assets
- Change HLS target-duration for live manifests
Release information
- Date: 2022-01-12
- Type: Alpha for testing
1.1.5.7 - Credits
License List
The table below lists the third party libraries used by this software and their respective license types.
Library | License | Checked At |
---|---|---|
github.com/prometheus/procfs | Apache-2.0 | 2022-03-10 |
github.com/cespare/xxhash/v2 | MIT | 2022-03-10 |
github.com/matttproud/golang_protobuf_extensions/pbutil | Apache-2.0 | 2022-03-10 |
github.com/sirupsen/logrus | MIT | 2022-03-10 |
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg | BSD-3-Clause | 2022-03-10 |
github.com/prometheus/common | Apache-2.0 | 2022-03-10 |
github.com/prometheus/client_model/go | Apache-2.0 | 2022-03-10 |
github.com/edgeware/m3u8 | BSD-3-Clause | 2022-03-10 |
github.com/rs/zerolog | MIT | 2022-03-10 |
google.golang.org/protobuf | BSD-3-Clause | 2022-03-10 |
github.com/zencoder/go-dash/v3 | Apache-2.0 | 2022-03-10 |
github.com/coreos/go-systemd/v22/journal | Apache-2.0 | 2022-03-10 |
github.com/go-chi/chi/v5 | MIT | 2022-03-10 |
github.com/prometheus/client_golang/prometheus | Apache-2.0 | 2022-03-10 |
github.com/beorn7/perks/quantile | MIT | 2022-03-10 |
github.com/golang/protobuf | BSD-3-Clause | 2022-03-10 |
golang.org/x/sys | BSD-3-Clause | 2022-03-10 |
License Details
This section includes all the licenses/notices for each dependency verbatim
github.com/prometheus/client_golang/prometheus
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
The following components are included in this product:
perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.
Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.
Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0
github.com/zencoder/go-dash/v3
LICENSE
Copyright Brightcove, Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/beorn7/perks/quantile
LICENSE
Copyright (C) 2013 Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/common
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
README
PACKAGE
package goautoneg import “bitbucket.org/ww/goautoneg”
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FUNCTIONS
func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.
func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses
TYPES
type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header
SUBDIRECTORIES
.hg
google.golang.org/protobuf
LICENSE
Copyright (c) 2018 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/matttproud/golang_protobuf_extensions/pbutil
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
github.com/golang/protobuf
LICENSE
Copyright 2010 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/rs/zerolog
LICENSE
MIT License
Copyright (c) 2017 Olivier Poitrey
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
golang.org/x/sys
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/edgeware/m3u8
LICENSE
Copyright (c) 2013-2016 Alexander I.Grafov grafov@gmail.com Copyright (c) 2013-2016 The Project Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/coreos/go-systemd/v22/journal
LICENSE
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
- Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
- Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
- Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
- Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
- Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
- Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
- Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
- Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
CoreOS Project Copyright 2018 CoreOS, Inc
This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).
github.com/go-chi/chi/v5
LICENSE
Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/client_model/go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/procfs
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.
Copyright 2014-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/sirupsen/logrus
LICENSE
The MIT License (MIT)
Copyright (c) 2014 Simon Eskildsen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/cespare/xxhash/v2
LICENSE
Copyright (c) 2016 Caleb Spare
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1.1.6 - VoD Ingest (esb3021)
1.1.6.1 - Introduction
ew-vodingest
The ew-vodingest
command may be used to perform either VoD ingest or to perform live recordings from an
ew-live-ingest
(esb3003) circular buffer.
VoD ingest
ew-vodingest
(ESB3021) reads and ingests an MP4/ts audio and video + subtitles asset
defined by a SMIL file into
an ESF (Edgeware Storage Format) asset in a way that is compatible with the
DASH OnDemand profile. A corresponding DASH MPD file is generated.
The SMIL-file syntax and usage is explained in the SMIL section.
It is also possible to specify a .ts
-file, an .mp4
-file or a directory-path as input.
For example:
ew-vodingest --input hitchcock/vertigo/index.smil --output esf/vertigo
Note: A main focus of this tool is to ingest VoD content that can be used to
generate live content by combining VoD assets using ESB3019 ew-vod2cbm
.
There is therefore a restriction on the ingested content that it must be possible
to discover a common constant GoP duration (sync-frame distance)
for all video tracks, and that all sample durations are exactly the same
in their respective timescales. The timescales may differ, but only
by integer factors, for example 50 for 50Hz video and 25 for 25Hz
video.
Codec and input format
Please refer to Supported codecs to get more information.
Input locations
This tables shows the possible combinations of input types and locations:
filesystem | http/https | S3 | FTP | |
---|---|---|---|---|
directory | yes | no | yes | yes |
SMIL | yes | yes | yes | yes |
MP4 | yes | no | no | no |
ts | yes | no | no | no |
DASH On-Demand | yes | yes | yes | yes |
HLS | yes | yes | yes | yes |
Unencrypted ISM/MSS | yes | yes | yes | yes |
For ingesting large assets (or for slow locations) the --maxtime
command-line
parameter can be used to increase the timeout threshold.
Output locations
Output locations can always be local filesystem, or network locations, as above. By default the content_id
in
content_info.json
of the output asset will equal the output directory. This can be overridden by specifying
any other ID with the --content-id
command-line parameter.
Live recordings
The input for live recordings is an ew-live-ingest
(esb3003) with a circular buffer available on
the instance specified by --host
and --port
(default localhost:8090
).
The output locations are the same as for VoD ingest above.
The --cbm
flag triggers a live recording (and cannot be combined with --i
).
The start/stop times are specified in epoch seconds, and must be in the past. The recording will consist
of integral segments, matching the specified time range as closely as possible. The time-stamps in the
resulting VoD will be shifted to start from zero. Any “holes” in the specified intervals will be removed,
thus resulting in a recording shorter than the specified interval.
SCTE-35 markers are transferred from the CBM interval and stored in a separate file.
For example:
ew-vodingest --cbm --start-epoch 1678190071 --stop-epoch 1678190099 --channel tv1 -o tv1-mar-7-2023
Note: VCP Origin
is end of support. No longer supported by ew-vodingest
.
Usage
ew-vodingest
is a command-line tool that is run as:
ew-vodingest [options]
Run as ew-vodingest [options]
-i, --input string SMIL file, dir or file pattern defining the asset (mandatory). Can't be used with --cbm.
-o, --output string output directory (mandatory)
-w, --minseg int minimum output segment duration (milliseconds) (default 4000)
-y, --maxseg int maximum output segment duration (milliseconds) (default 12000)
--cbm set to use esf export from cbm. Can't be used with --input.
--start-epoch uint recording start time given in epoch seconds. Only works with --cbm
--stop-epoch uint recording stop time given in epoch seconds. Only works with --cbm
--channel string channel name to record from. Only works with --cbm
--drop-non-aligned-track drop track with abnormal segment duration. Only works with --cbm
-c, --content-id string explicit content-id (instead of ingest path)
-m, --maxtime int maximal execution time to ingest asset (seconds) (default 1800)
--hls output HLS playlists (experimental)
--slim only output content_info and dat files
--leavepartial leave partial ingested content on failure
--s3file string path to S3 credentials file
-t, --template string path to content template file, for asset comapatibility verification
--licensefile string license file path (default "/etc/edgeware/ew-vodingest/license.json")
-l, --logfile string log file [default stdout]
--log-file string see above
--logformat string format and type of log: [consolejson consolepretty discard] (default "consolepretty")
--loglevel string initial log level (default "info")
-v, --version print version and date
--host string cbm host to connect to. Only works with --cbm (default "localhost")
--port uint16 cbm port to connect to. Only works with --cbm (default 8090)
--source-rate-limit uint32 maximum read rate in Mbps from source. Only works with --cbm. Setting 0 will disable source rate limiting
--thumbnails enable thumbnail generating, requires command 'ffmpeg' to work
--thumbnails-sizes string comma separated list of thumbnail sizes width[xheight],...If only widths are provided, the height will be calculated to keep aspect ratio, nothing provided, auto generate a thumbnails with 240 as width
--help extended tool help
The following options -i, -o, -w, -y, --cbm, --start-epoch, --stop-epoch, --channel, -l, --source-rate-limit
are the same as for the ESB3005 ew-recorder
.
To enable DASH thumbnails generation, add flag --thumbnails
. About
--thumbnails-sizes
, it acts like --sizes
in ew-thumbnails-generator
tool,
please refer to Tools for more information.
These options are available from version 1.12.0.
1.1.6.2 - Installation
The command line tool ew-vodingest
and the other tools can be installed on a Linux
distribution compatible with RedHat Enterprise Linux 8 with:
$ sudo dnf install ew-vodingest-x.y.z-1.x86_64.rpm
To uninstall:
$ sudo dnf remove ew-vodingest.x86_64
1.1.6.3 - Tools
The ew-vodingest
rpm also contains number of tools that can be
used to investigate and manipulate ESF format (CMAF + metadata)
made by the VoD Ingest.
All utilities will print a usage help message if you specify the -h
flag.
ew-check-variant-alignment
The tools lists the start and stop times of every variants of the output
recording or managed VOD. In the strict check mode
, it fails with non-zero exit code
if there is unalignment found.
usage: ew-check-variant-alignment [-h] [-v] [-s] content_path
Check ESF variant alignment
positional arguments:
content_path
optional arguments:
-h Show help message
-s Run in 'strict check mode'
-v Enable verbose output
ew-vod-modify-subtitles
This tool can modify subtitle and caption tracks of ingested assets.
It only works on ESF assets that are available as a mounted file directory.
If the asset was ingested with ew-vodingest
and has a DASH MPD file, it will also be updated.
Other features from ew-vodingest
like storing original subtitle files with a BaseURL link
in content_info.json
are also implemented.
The tool has commands like add
, delete
, modify
, etc to allow changes to the asset.
Each command has its own flags. To get help for a command, use the –help flag with the command,
like $ ew-vod-modify-subtitles add --help
or simply type ew-vod-modify-subtitles add
.
Usage:
ew-vod-modify-subtitles [command]
Available Commands:
add Add a new subtitle track to an asset
completion Generate the autocompletion script for the specified shell
delete Delete an existing subtitle track
help Help about any command
list Lists available subtitle tracks
modify Modify attributes of an existing subtitle track
rename Rename an existing subtitle track
replace Replace an existing subtitle track
Flags:
-h, --help help for ew-vod-modify-subtitles
--log-file string log to specified file instead of standard output
--log-format string format and type of log: [consolejson consolepretty discard] (default "consolepretty")
--log-level string log level (trace|debug|info|warn|error|fatal|panic) (default "info")
-v, --version version for ew-vod-modify-subtitles
ew-thumbnails-generator
This tools is only available from version 1.12.0 and used to generate DASH thumbnails tracks for existing ESF asset:
Basic usage of ew-thumbnails-generator:
ew-thumbnails-generator -i /path/to/esf --sizes "width[xheight[,width[xheight]]]"
Generate thumbnails for video in the source directory. Requires command 'ffmpeg' to be available"
Run ew-thumbnails-generator with options:
-i, --input string source directory
-l, --logfile string log file [default stdout]
--logformat string format and type of log: [consolejson consolepretty discard] (default "consolepretty")
--loglevel string Initial logging level: debug, info, warn, error, fatal, panic (default "info")
-r, --remove remove existing thumbnails instead of generating (base on the sizes)
-s, --sizes string comma separated list of thumbnail sizes 'width[xheight],...'If only widths are provided, the heights will be calculated to keep aspect ratio. In case nothing provided, auto generate a thumbnails with 240 as width (default "240")
-t, --tmpdir string temporary working directory (default "/tmp")
How does it work?
The tool will execute ffmpeg
for generating images by extracting first IDR frame
of segments. The maximum number of thumbnails will be 500, that means, if there
are more than 500 segment in the video, this tool will just only generate 500
thumbnails. This is for better performance and the fact that 500 images is a
reasonable ammount of images to display on scrub bar. The tool will automatically
pick the reasonable segments from which IDR frames will be extracted.
The thumbnails will be resized base on the --sizes
argument. You can enter
only width for size, or widthxheight or mixed, the sizes must be seperated by
comma. Below are acceptable inputs:
--size "240,320"
--size "240x120,320x150"
--size "240x120,320"
In case only width known, the height will be calculated base on video resolution.
height = videoHeight * (width / videoWidth)
The number of generated thumbnails track will equal with the number of sizes.
The thumbnails will be combined into a single image and will be served as a tile
in a SegmentNumber
AdaptationSet by repackager to reduce the number of requests
toward repackager.
Notes:
- Because this tool base on
ffmpeg
,ffmpeg
and its license should be installed and managed by user, therpm
package will not install it by default. And please make sure all necessary codec libraries are installed. For example, if the system is only using H264, only H264 codec libraries must be installed, H265 codec libraries can be skipped. Refer to Supported codecs for more information about current supported codecs ofew-vodingest
. - Only
jpeg
is supported by now. - This tool only compatible with the output of
ew-vodingest
andew-recorder
. The output of oldconvoy-live-ingest
is not supported.
1.1.6.4 - Convoy integrating
Currently Convoy
, a product that managed the streamers and origins, is using
the tool named ew-recorder
for recording and uploading VoD. That tool was
written in python and not so good in performance and resource usage. ew-vodingest
tends to resolve these problems.
This document’s purpose is to make to integrating process between ew-vodingest
and Convoy
becomes clear.
How to install ew-vodingest
in Convoy
?
From Convoy
version 2.30, it has already been installed along when installing
Convoy
.
Installing or upgrading ew-vodingest
on Convoy
by:
yum install -y <path to ew-vodingest RPM>
Integrating for recording
For using ew-vodingest
for recording on Convoy
, ingest script for recorder
must be changed to ew-vodingest
...
ccmi.webtv_recorders {
liveingest1 {
host = 1.2.3.4
port = 8090
live_buffer = 600
storage = storage1
ingest_script = /usr/bin/ew-vodingest
channel_groups = { swlive }
}
}
...
Then, recording will be handled by ew-vodingest
.
DASH thumbnails for recordings
To generate DASH thumbnails
, an option must be added when executing ew-vodingest
.
Unfortunately, this option cannot be added directly into ingest_script
configuration
above, so we should use this script:
#!/bin/bash
set -e
export PATH="$PATH:/usr/bin"
/usr/bin/ew-vodingest --thumbnails "$@"
The change in PATH
variable above means to allow ew-vodingest
to search for
ffmpeg
command. /usr/bin
can be changed to wherever ffmpeg
is placed.
Put this script into any bash script file, for example /usr/bin/ew-custom-recorder
,
and the configuration will look like this
...
ccmi.webtv_recorders {
liveingest1 {
host = 1.2.3.4
port = 8090
live_buffer = 600
storage = storage1
ingest_script = /usr/bin/ew-custom-recorder
channel_groups = { swlive }
}
}
...
Notes:: The above script is just a simple example and can be modified for more purposes.
Integrating for uploading
From Convoy
2.30, you can change the configuration of Convoy
to change the
uploading script:
upload.repackager_bin = /usr/bin/ew-vodingest
For older Convoy
, you should change the symlink /usr/bin/recorder
, and make
it point to ew-vodingest
.
ln -sf /usr/bin/ew-vodingest /usr/bin/recorder
DASH thumbnails for uploadings
Because ew-check-variant-aligment
, a legacy tool of ew-recorder
,
are still being used for checking the asset before uploading it, a similar
solution with recording above cannot be used since thumbnails
tracks
are not accepted by that tool.
Thus, thumbnails generating has to be executed after the checking step, and that can be achieved by using this script:
#!/bin/bash
set -e
/usr/lib64/ew-repackaging-recorder/bin/ew-check-variant-alignment "$@"
/usr/bin/ew-thumbnails-generator -i "$2"
Put above script into a file, for example /usr/bin/ew-custom-checker
, and change
the symlink:
ln -sf /usr/bin/ew-custom-checker /usr/bin/ew-check-variant-alignment
Notes::
The above script is just a simple example and can be modified for more purposes.
ew-check-variant-aligment
are going to be replaced in the future.
1.1.6.5 - Performance
This is the performance report for the vodingest tool. The results are affected by i/o capacity of the system and the system load. The results are not absolute and should be used as a reference only since the input from customer can be vary in codec, combination of tracks and so on. All of this results are measured with the input data is on local file system, not mounted or from external backend like nfs, s3 or http since the throughput of the backend can affect the results.
The scenarios are now run with the following formats: MP4 progressive, TS and Fragmented MP4 (fMP4) as DASH On-Demand. All other formats like SMIL or HLS are just the manifest in text, the base containers are still MP4, TS or fMP4.
Manifest text and subtitles tracks are not included in the results since their cost to be processed is too small compare to the video and audio tracks.
The results are based on the average of the runs.
CPU information: Intel(R) Xeon(R) CPU E31220 @ 3.10GHz
MP4 progressive
CPU(%) | Time(s) | Max RAM usage(KB) | Input operations | Output operations | |
---|---|---|---|---|---|
Size: 4GB Dur: 2h 15m Tracks: Video: . codec: h264 . resolution: 1920x1080 . bitrate: 3.74Mbps Audio 1: . codec: aac . bitrate: 128Kbps Audio 2: . codec: aac . bitrate: 128Kbps | 14 | 98.7 | 61405 | 7899776 | 7630237 |
Size: 2.3GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 2.28Mbps . resolution: 1280x720 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 15 | 47.8 | 62181 | 4140101 | 4701477 |
Size: 1GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 0.85Mbps . resolution: 1024x576 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 45.3 | 6 | 62060 | 1233706 | 1882600 |
Size: 4GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 3.78Mbps . resolution: 1920x1080 Audio 1: . codec: aac . bitrate: 128Kbps Audio 2: . codec: aac . bitrate: 128Kbps | 16 | 90.9 | 63276 | 7987461 | 7710013 |
Size: 1.5GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 1.38Mbps . resolution: 1024x576 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 16 | 35.6 | 63138 | 3047370 | 2917592 |
TS
CPU(%) | Time(s) | Max RAM usage(KB) | Input operations | Output operations | |
---|---|---|---|---|---|
Size: 4GB Dur: 2h 15m Tracks: Video: . codec: h264 . resolution: 1920x1080 . bitrate: 3.74Mbps Audio 1: . codec: aac . bitrate: 128Kbps Audio 2: . codec: aac . bitrate: 128Kbps | 28.3 | 68.3 | 34430 | 8851370 | 7365648 |
Size: 2.3GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 2.28Mbps . resolution: 1280x720 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 38.7 | 29.9 | 33584 | 5762170 | 4499920 |
Size: 1GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 0.85Mbps . resolution: 1024x576 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 42 | 11.3 | 32361 | 2372581 | 1681048 |
Size: 5.2GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 5.55Mbps . resolution: 1920x1080 Audio 1: . codec: aac . bitrate: 128Kbps Audio 2: . codec: aac . bitrate: 128Kbps | 28 | 93 | 53718 | 9856626 | 9831136 |
Size: 2.03GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 2.16Mbps . resolution: 1024x576 Audio 1: . codec: aac . bitrate: 96Kbps Audio 2: . codec: aac . bitrate: 96Kbps | 42 | 22.6 | 53973 | 4092181 | 3866560 |
DASH On-Demand (fMP4)
CPU(%) | Time(s) | Max RAM usage(KB) | Input operations | Output operations | |
---|---|---|---|---|---|
Size: 3.73GB Dur: 2h 15m Tracks: Video: . codec: h264 . resolution: 1920x1080 . bitrate: 3.74Mbps Audio: . codec: aac . bitrate: 128Kbps | 13.7 | 105 | 93684 | 6713314 | 7630245 |
Size: 2.24GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 2.28Mbps . resolution: 1280x720 Audio: . codec: aac . bitrate: 96Kbps | 13.7 | 57.1 | 89533 | 4006325 | 4701474 |
Size: 0.92GB Dur: 2h 15m Tracks: Video: . codec: h264 . bitrate: 0.85Mbps . resolution: 1024x576 Audio: . codec: aac . bitrate: 96Kbps | 26.7 | 17.2 | 89385 | 1356285 | 1882600 |
Size: 3.68GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 3.78Mbps . resolution: 1920x1080 Audio: . codec: aac . bitrate: 128Kbps | 15.3 | 112.5 | 89657 | 7243101 | 7710024 |
Size: 1.4GB Dur: 2h 15m Tracks: Video: . codec: hevc . bitrate: 1.38Mbps . resolution: 1024x576 Audio: . codec: aac . bitrate: 96Kbps | 15.3 | 41.2 | 85257 | 2045042 | 2917592 |
1.1.6.6 - SMIL manifest
Input SMIL syntax
SMIL is an XML format for multimedia presentation. It can be used
instead of an HLS master playlist or DASH Media Presentation File to
tell what media files should be combined into an asset and some associated
metadata parameters. The level of detail, however, is much lower than in the
other formats. ew-vodingest
supports the import of MP4 files for video
and audio, in connection to subtitle files.
Our usage of SMIL follows legacy format of Wowza, but we have added some parameters,
such as displayName
for HLS and role
for subtitles.
Basic structure
SMIL files should specify all relevant media files in a switch block in the body:
<?xml version="1.0" encoding="UTF-8"?>
<smil>
<body>
<switch>
<video src="movie1.mp4" ... />
<video src="audio.mp4" ... />
<textstream ... />
<srt ... />
</switch>
</body>
</smil>
Stream types
The supported stream types are <video>
which either means video, audio or both,
<texstream>
that is a subtitle file or <srt>
which is a subtitle
file in SRT format.
Video/Audio streams
Audio and video streams are identified by the video
tag.
Minimal configuration
The simplest variant is to just give a src
attribute:
<video src="videoAndAudio.mp4"/>
If this is the only information give, all video and audio tracks will be extracted and given names following the patterns
media type | pattern | example |
---|---|---|
video | video_<codec>_<bitrate> | video_hevc_9000kbps |
audio | audio_<codec>_<lang>_<bitrate> | audio_aac_en_256kbps |
depending on what tracks and codecs are available. The bitrate is calculated from
the file size and duration and the language is extracted from the mp4 file
if available in an elng
, of in the mdhd
box as a fallback.
If multiple files are specified in the SMIL file, tracks will be extracted from all of them, but if the resulting names (mediatype_codec_bitrate_language) coincide, only one copy will be kept. This makes it possible to import files which all include the same audio bitrate and language, but different video bitrates.
Specifying the bitrate
The system-bitrate
attribute is used to specify the bitrate for the stream.
<video src="video.mp4" system-bitrate="2500000" />
Optionally it is possible to specify bitrates as <param>
values as
<video src="videoAndAudio.mp4">
<param name="videoBitrate" value="2500000"/>
<param name="audioBitrate" value="128000"/>
</video>
Track selection and track-specific parameters - mp4
To achieve higher control over the extraction of tracks, and their parameters, it is possible to add extra parameters.
In particular, one can use the audioOnly
and videoOnly
keys to specify
that only one type of media track should be extracted.
To extract audio and video in this way, one could use the following snippet:
<video src="videoAndAudio.mp4" system-bitrate="2500000">
<param name="videoOnly" value="TRUE"/>
</video>
<video src="videoAndAudio.mp4" system-bitrate="128000">
<param name="audioOnly" value="TRUE"/>
</video>
In addition, one can add an audioindex
query index to extract a specific audio track.
The audioindex
value relates to the track ID inside an mp4 file, but
is zero-based. The mapping is that ?audioindex=0
refers to the audio
track with the lowest track ID, ?audioindex=1
to the second, and so on.
Here is an example that extracts the first two audio tracks, and gives them different parameters for language, bitrate, and displayName:
<video src="hev1_aac_mc.mp4?audioindex=0" system-language="dk" audio-bitrate="256000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="Danish 6ch"/>
</video>
<video src="hev1_aac_mc.mp4?audioindex=1" system-language="dk" audio-bitrate="192000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="Danish 2ch"/>
</video>
Track selection and track-specific parameters - ts
For multiplexed .ts
-files the audio tracks are selected by specifying the trackID
parameter
corresponding to the PID, as follows:
<video src="0.ts" audio-bitrate="94000" systemLanguage="spa">
<param name="audioOnly" value="TRUE" />
<param name="trackID" value="482"/>
<param name="displayName" value="español"/>
</video>
Audio Language
The language for an audio stream can be set using the system-language
attribute:
<video src="mp4:video3.mp4?audioindex=0" system-language="eng">
For legacy reasons, one can alternatively use the attribute systemLanguage
or language
.
If the language is not specified, 3-letter language code in the mdhd
box will be used.
It will in turn be overridden by the optional elng
box that can contain any language code.
Subtitle input
The supported input subtitle formats are TTML, WebVTT, STL, SRT. In all cases, a complete side-loaded file is expected. As part of the ESF format, the subtitles will be transformed into segmented wvtt. A complete WebVTT file will also be generated and referred to in the generated DASH manifest. The name of the output subtitle tracks are of the form
media type | pattern | example |
---|---|---|
subtitles | subtitles_wvtt_<lang>_<role> | subtitles_wvtt_se_caption |
The role can be either caption
or subtitle
. If not specified, the role will
be not be in the track name.
Subtitle streams in TTML, WebVTT, STL, or STT files are specified
with the <textstream>
or <srt>
tags.
The language can be specified with language
attribute, or,
for textstream, with the system-language
attribute like:
<textstream src="subtitles.ttml" system-language="en" />
<srt src="swedish.srt" language="se"/>
The format is auto-detected from the file extension, which must be one of:
.ttml, .webvtt, .vtt, .stl, .srt
The case of multiple languages in the same TTML file is not supported.
There is no bitrate specified for text streams. It will always be set to 1kbps.
Extracting language from subtitle file name
For the case where the SMIL-file is missing or there is no language attribute for
the subtitle files, ew-vodingest
will try to extract a language from the file name.
The language extraction algorithm works like this:
- the file extension is removed
- split the name on “-” characters
- if the last part is at most three characters, use it as a language code
If a language is not found, the subtitle languages will be denoted “und”, “und1”, “und2” etc.
Example SMIL files
In the following, we give examples to show some possible variations of supported SMIL files.
Example 1 - video and audio from all files
This example has width and height for the video. That information will be discarded.
There are only two distinct combinations of language and bitrate for audio, so
only two variants audio_aac_eng_128kbps
and audio_aac_eng_192kbps
will be generated.
<?xml version="1.0" encoding="UTF-8"?>
<smil>
<body>
<switch>
<video height="360" src="profile1.mp4" systemLanguage="eng" width="480">
<param name="videoBitrate" value="500000"/>
<param name="audioBitrate" value="128000"/>
</video>
<video height="480" src="profile2.mp4" systemLanguage="eng" width="720">
<param name="videoBitrate" value="800000"/>
<param name="audioBitrate" value="128000"/>
</video>
<video height="540" src="profile3.mp4" systemLanguage="eng" width="960">
<param name="videoBitrate" value="1300000"/>
<param name="audioBitrate" value="128000"/>
</video>
<video height="720" src="profile4.mp4" systemLanguage="eng" width="1280">
<param name="videoBitrate" value="2300000"/>
<param name="audioBitrate" value="192000"/>
</video>
<video height="1080" src="profile5.mp4" systemLanguage="eng" width="1920">
<param name="videoBitrate" value="5000000"/>
<param name="audioBitrate" value="192000"/>
</video>
</switch>
</body>
</smil>
Example 2 - audioindex queries
This example shows extraction of audio tracks using the audioindex
query parameter.
The mp4:
“scheme” is not needed, but supported for legacy reasons.
The mp4:///
scheme is also supported for the same reason.
<?xml version="1.0"?>
<smil>
<body>
<switch>
<video src="mp4:video1.mp4?audioindex=0" system-language="eng" audio-bitrate="96000">
<param name="audioOnly" value="TRUE"/>
</video>
<video src="mp4:video1.mp4?audioindex=1" system-language="ger" audio-bitrate="96000">
<param name="audioOnly" value="TRUE"/>
</video>
<video src="video2.mp4" system-bitrate="2000000">
<param name="videoOnly" value="TRUE"/>
</video>
<video src="video1.mp4" system-bitrate="5000000">
<param name="videoOnly" value="TRUE"/>
</video>
<textstream src="subtitles.ttml" system-language="eng">
</textstream>
</switch>
</body>
</smil>
Notes: audioindex
cannot be used when ingesting VOD over HTTP/FTP server.
Example 3 - displayName and role parameters
This example uses parameters for displayName
for audio and subtitles, and
role
for subtitles.
<?xml version="1.0" encoding="utf-8"?>
<smil>
<body>
<switch>
<video src="video800.mp4" system-bitrate="800000">
<param name="videoOnly" value="TRUE"/>
</video>
<video src="video400.mp4" system-bitrate="400000">
<param name="videoOnly" value="TRUE"/>
</video>
<video src="audio.mp4?audioindex=0" system-language="eng" audio-bitrate="256000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="English 6ch"/>
</video>
<video src="audio.mp4?audioindex=1" system-language="eng" audio-bitrate="192000">
<param name="audioOnly" value="TRUE"/>
<param name="displayName" value="English 2ch"/>
</video>
<srt src="swe.srt" language="swe">
<param name="displayName" value="svenska"/>
<param name="role" value="subtitle"/>
</srt>
<srt src="swe_cc.srt" language="swe">
<param name="displayName" value="svenska (CC)"/>
<param name="role" value="caption"/>
</srt>
<textstream src="eng.stl" system-language="eng">
<param name="displayName" value="English"/>
<param name="role" value="caption"/>
</textstream>
</switch>
</body>
</smil>
Example 4 - The simplest possible - same as no SMIL
This example shows a SMIL file where all parameters are extracted automatically.
In this case all video sources contain audio with language set to eng
in the mdhd
box in the mp4 files, and the subtitle languages can be extracted from the file names.
<?xml version="1.0" encoding="UTF-8"?>
<smil>
<body>
<switch>
<video src="0.mp4"/>
<video src="1.mp4"/>
<video src="2.mp4"/>
<video src="3.mp4"/>
<srt src="xyz-eng.srt"/>
<srt src="xyz-spa.srt"/>
</switch>
</body>
</smil>
The generated tracks are:
- 4 video tracks with different bitrates
- 2 audio track with different bitrates, but the same language “eng”
- 2 subtitle tracks with language codes “eng” and “spa”
In this particular case, the SMIL file just provides a list of files and no extra parameter.
Therefore, it is also possible to specify the directory of this file as input to ew-vodingest
and get exactly the same result.
1.1.6.7 - Supported codecs
Progressive MP4
An MP4 file contains all video and audio tracks. All the tracks in that MP4 will be extracted except subtitle.
Video
H.264/AVC and H.265/HEVC with multiple bitrates.
For H.264/AVC, both avc1
and avc3
are accepted, but the result always be
stored with avc1
type of video sample entry box.
For H.265/HEVC, both hev1
and hvc1
are accepted, but the result will always
be stored with hev1
type of video sample entry box.
In case a common GoP duration of all video tracks can be found, one or more
common GoP will be combined to form a segment that has duration --minseg
to --maxseg
, if we have more than one segment durations that satisfy the
range, the lowest one will be chosen. Then, all output video tracks will be
segmented with the same segment duration.
On the other hand, if a common GoP duration among video tracks cannot be found,
the segments will be formed base on the sync-frames distances of each video
track. Segment will begin with a sync-frame, it can contain one or more
sync-frames in it and will end right before a sync-frame (end sync-frame).
The DTS diff between begin sync-frame and end sync-frame is segment duration
and will be from --minseg
to --maxseg
. In this case, the segment duration
can be vary, but the duration of corresponding segments within tracks will be
the same.
Video track timescales, as defined in mdhd
box, need to be the same among
videos, or differ by an integer factor like 50 and 25 with factor is 2, or
60000 and 20000 with factor is 3.
Audio
AAC, HE-AACv1, HE-AACv2, AC3, Enhanced AC3, and MP4 with multiple
bitrates and languages. Language will be gotten from mdhd
box.
Subtitle
Embedded subtitle are not supported.
Note: you can add subtitle track later by this tools. Or you can use Directory input method by putting MP4 files and subtitle files into the same directory.
SMIL + progressive MP4
In this case, the assets have a SMIL file describing the Progressive MP4 video, audio and text stream.
Video
The same with Progressive MP4
Audio
The same with Progressive MP4
Subtitle
The SMIL-file syntax and usage is explained in the SMIL section. In that section, you can also find the subtitle specification at Subtitle input.
MPEG2-TS
A TS file contains all video and audio tracks, and them all will be extracted except subtitle track.
Video
H.264/AVC and H.265/HEVC with multiple bitrates.
In case a common GoP duration of all video tracks can be found, one or more
common GoP will be combined to form a segment that has duration --minseg
to --maxseg
, if we have more than one segment durations that satisfy the
range, the lowest one will be chosen. Then, all output video tracks will be
segmented with the same segment duration.
On the other hand, if a common GoP duration among video tracks cannot be found,
the segments will be formed base on the sync-frames distances of each video
track. Segment will begin with a sync-frame, it can contain one or more
sync-frames in it and will end right before a sync-frame (end sync-frame).
The DTS diff between begin sync-frame and end sync-frame is segment duration
and will be from --minseg
to --maxseg
. In this case, the segment duration
can be vary, but the duration of corresponding segments within tracks will be
the same.
The timescale in TS file must be standard, 90000.
Audio
AAC, HE-AACv1, HE-AACv2, AC3, and Enhanced AC3 with multiple bitrates and languages. Language will be gotten from stream descriptors in PMT.
Subtitle
Embedded subtitle are not supported.
Note: you can add subtitle track later by this tools. Or you can use Directory input method by putting TS files and subtitle files into the same directory.
Directory
A directory contains all the input TS, MP4 and subtitle files. ew-vodingest
will scan and extract all the media tracks from the media files in that
directory.
Video
The same with Progressive MP4 and MPEG2-TS sections, duplicated tracks are going to be dropped.
Audio
The same with Progressive MP4 and MPEG2-TS sections, duplicated tracks are going to be dropped.
Subtitle
Side-loaded subtitle text files are supported.
Supported formats: ttml
, webvtt
, srt
, stl
. Subtitle format will be
detected by the file extension:
.ttml
for ttml
format.
.vtt
and .webvtt
for webvtt
format.
.srt
for srt
format.
.stl
for stl
format.
MPEG DASH On-Demand Profile
A DASH On-Demand MPD file describes the asset.
Video
H.264/AVC and H.265/HEVC with multiple bitrates.
For H.264/AVC, both avc1
and avc3
are accepted, but the result always be
stored with avc1
type of video sample entry box.
For H.265/HEVC, both hev1
and hvc1
are supported, but the result always be
stored with hev1
type of video sample entry box.
All video tracks need to have the same timescale as defined in mdhd
box.
Audio
AAC, HE-AACv1, HE-AACv2, AC3 and Enchaned AC3 with multiple bitrates and languagues.
Subtitle
Side-loaded subtitle text files are supported under formats:
ttml
, webvtt
, srt
.
Side loaded subtitle fragmented mp4 files is supported under
formats: stpp
and fragmented webvtt
.
CEA608 Closed Captions is preserved from MPD manifest file.
Apple HLS
A Master Playlist file describes the asset. Multiplexed and isolate video and audio tracks are both supported in individual segment files or a concatenated files.
Video
H.264/AVC in TS encapsulation.
H.264/AVC and H.265/HEVC are supported in fMP4 encapsulation.
Audio
AAC, HE-AACv1, HE-AACv2, AC3 and Enhanced AC3 in fMP4 and TS encapsulation.
Subtitle
HLS WebVTT as side loaded, complete or segmented text files.
HLS stpp as fragmented files.
CEA608 Closed Captions are preserved from master playlist (.m3u8 file).
Microsoft SmoothStreaming
The MSS/ISM manifest file is used to define the asset.
Video
H.264/AVC with multiple bitrates.
Although it is not standard, H.265/hevc with muiltiple bitrates is supported.
Audio
AAC and HE-AAC with multiple bitrates and languages.
Subtitle
TTML as side-loaded complete files.
1.1.6.8 - HDR10 support
When ingesting TS streams, HDR10 is detected by parsing SPS. If the HDR10 info is included in the TS streams, the VUI part of SPS will contain colour_primaries
with value 9, matrix_coeffs
with value 9 and transfer_characteristics
with value 16. If ew-vodingest detects exactly HDR10 info with these values, it will do following things:
- Add new
hdr
field to video variant in content_info.json. This field currently supports only one valuehdr10
. The video variant info will look like this:
"variants": [
{
"media_type": "video",
"subtype": "hevc",
"name": "video_hevc_886kbps",
....
"hdr": "hdr10",
- Add compatible brand “chd1” to ftyp box of video file
.cfmv
[ftyp]
- majorBrand: mp42
- minorVersion: 512
- compatibleBrand: chd1
Beside the VUI part of SPS, the following SEI NAL units may be present in the TS streams: Mastering display colour volume
(SEI payload type 137) and Content light level information
(SEI payload type 144). But this signal is optional, ew-vodingest doesn’t rely on them to detect HDR10. If these SEI NAL units are present, ew-vodingest will just add them to the hvcc box of video file .cfmv
For MP4 input, ew-vodingest does exactly the same behaviours, but the behaviour which add above SEI NAL units to hvcc box has not been tested.
1.1.6.9 - AWS S3 Cloud Usage
To ingest to or from S3, the path is specified with s3://
. For example:
ew-vodingest --input s3://mybucket/dir1 --output /home/myhome/esf1 --s3file /home/myhome/.aws/credentials.json
S3 credentials file
You must create a JSON file for the credentials. (The credentials file used by the AWS CLI is not used.) For example:
{
"profile": "default",
"region": "eu-north-1",
"id": "AKIAQWERTYQWERTY",
"key": "qwerty123+QWERTY123&qwerty"
}
The actual values must be obtained from the AWS administration console.
Here id
and key
correspond to "Access key ID"
and "Secret access key"
.
1.1.6.10 - Releases
ESB3021 - ew-vodingest releases
1.1.6.10.1 - Release 1.12.0
Change log
- NEW: Generate DASH image-based thumbnails for recording and VoD [ESB3021-165]
- NEW: Detect recording GoP duration for better integration with ew-vod2cbm [ESB3021-159]
- NEW: Support recording for low-latency channels [ESB3021-161]
- NEW: Support
--local-storage
option for recording, input and temporary output [ESB3021-171] - IMPROVED: Better
--source-rate-limit
handling. Improve accuracy in checking used bandwidth [ESB3021-96] - FIXED: Fail to get inband codec information for DASH On-Demand [ESB3021-168]
- FIXED: All audios tracks extracted, even though
audioindex
is defined in SMIL [ESB3021-175]
Known limitations:
- Does not preserve TTML subtitle styling
- VoD ingest of SMIL over HTTP/FTP, does not work with query parameter
audioIndex
Compatibility has been verified with the following products:
- Sw Repackager: 1.50.3
- Sw Live Ingest: 1.40.1
- Convoy: 3.2.1
- Sw Streamer: 1.34.0
- Orbit TV Server: 3.4.1
Release information
- Date: 2024-10-23
- Type: Production release
1.1.6.10.2 - Release 1.10.0
Change log
- NEW: New subtitle format support. cmft for HLS/DASH and stpp for DASH [ESB3021-129]
- NEW: Preserve SCTE35 information for HLS input [ESB3021-130]
- NEW: Support FTP ingest [ESB3021-151]
- NEW: Allow repackager to output VOD DASH SegmentNumber [ESB3021-160]
- IMPROVED: Better command line help [ESB3021-131]
- FIXED: Missing original subtitle after ingestion. Problem in 1.8.0 with lost subtitles [ESB3021-136]
- FIXED: Broken AC3/E-AC3 sample data lead to broken audio data. Audio will be muted [ESB3021-137]
- FIXED: Newline tag in ttml is not preserved [ESB3021-147]
- FIXED: Missing space characters when preserving styling in webvtt [ESB3021-149]
- FIXED: Crash on empty line of m3u8 files [ESB3021-153]
- FIXED: Cannot download input from external servers. this happens when the manifest (includes MPD and M3U8) contains absolute URL for media segments/files [ESB3021-154]
- FIXED: Multiple languages TTML subtitle is not supported [ESB3021-158]
Known limitations:
- Does not preserve TTML subtitle styling
- VoD ingest of SMIL over HTTP/FTP, does not work with query parameter
audioIndex
Compatibility has been verified with the following products:
- Sw Repackager: 1.48.2
- Sw Live Ingest: 1.38.2
- Convoy: 3.0.1
- Sw Streamer: 1.34.0
- Orbit TV Server: 3.2.1
Release information
- Date: 2024-06-25
- Type: Production release
1.1.6.10.3 - Release 1.8.0
Features:
- New: Support for HLS VOD input
- New: Support for unencrypted ISM/MSS
- New: Support for irregular sample duration VODs (TS and MP4)
- New: Preserve WebVTT styling
- New: Support Audio Descriptions in VOD ingestion
- Fix: Missing CUE-IN for one segment ad break
- Fix: Average segment duration appears in content_info.json when common GoP cannot be detected
- Fix: Incorrect audio language
- Fix: Incorrect audio codec
- Fix: Duplicate track name for HEVC HDR and SDR tracks
- Fix: Ingest stops due to unrecognized tag in smil
- Fix: Missing role for subtitle track
- Fix: Cannot parse PES packet containing more than one AAC frame, causing silent audio output
- Fix: Incorrect maximum segment duration in content_info.json
- Fix: Redundant HLS target duration in content_info.json
Known limitations:
- Does not preserve TTML subtitle styling
- VoD ingest of SMIL over HTTP, does not work with query parameter
audioIndex
Compatibility has been verified with the following products:
- Sw Repackager: 1.46.2
- Sw Live Ingest: 1.38.0
- DRM Gateway: 2.30.1
- Convoy: 2.36.0
Release information
- Date: 2023-11-29
- Type: Production release
1.1.6.10.4 - Release 1.6.0
Features:
- New: Support for DASH On-Demand
- New: Option to throttle the reading rate from local storage
- Fix: Incorrect subtitles timing
- Fix: Ingestion failed when missing some samples at the end of tracks
- Fix: Cannot stream MSS throught ew-repackager
- Fix: Lingering
.dat
file after ingestion failed - Fix: Missing field
content_duration_ms
for recordings - Fix: Language code is not extracted from subtiles filename when ingesting from SMIL (if language is not defined in SMIL)
Known limitations:
- Does not preserve subtitle styling
- VoD ingest of SMIL over HTTP, does not work with query parameter
audioIndex
Release information
- Date: 2023-09-18
- Type: Production release
1.1.6.10.5 - Release 1.4.0
Features:
- New: Support for EC-3 audio in transport streams
- New:
ew-vodmod
tool to modify subtitle tracks of ingested VoD assets - New: Option to drop incompatible media tracks
- Fix:
ew-vodingest
did not escape special character for WVTT format - Fix: corrected VOD-asset duration in log
- Fix: corrected dropping of too early audio samples in TS ingest (causing “Bad box size” error)
Known limitations:
- Does not preserve subtitle styling
- HDR10 has not been tested fully on MP4 file
- VoD ingest of SMIL over HTTP, does not work with query parameter
audioIndex
- live-recording-asset duration is logged as zero
Release information
- Date: 2023-06-08
- Type: Production release
1.1.6.10.6 - Release 1.2.0
Features:
- New: Live recordings (with esb3003 CBM)
- New: Command-line
content-id
(esb3005 style) - New: Content template verification, for esb3019 integration
- New: Allow non-constant GoP-durations
- New: Improved S3 and NFS failure handling
- Fix: Superfluous audio-track generation
- Fix: Confused output audio bandwidths
- Fix: ADTS headers with 2-byte CRC
Known limitations:
- Does not preserve subtitle styling
- HDR10 has not been tested fully on MP4 file
- VoD ingest of SMIL over HTTP, does not work with query parameter
audioIndex
Release information
- Date: 2023-03-08
- Type: Production release
1.1.6.10.7 - Release 1.0.0
Features:
- Ingest single file TS
- Ingest single file MP4
- Support for HDR10
- S3 and HTTP support
- Timeout handling
- Improved logging
- Offline licensing
Known limitations:
- Require constant GoP duration and constant sample steps
- Does not preserve subtitle styling
- HDR10 has not been tested fully on MP4 file
Release information
- Date: 2022-12-02
- Type: First production release
1.1.6.10.8 - Release 0.6.2
Features:
- Ingest SMIL + mp4 + subtitle assets in combined ESF + DASH OnDemand format
- Support AVC, HEVC video
- Support AAC, AC-3 audio
- Support TTML, WebVTT, SRT, STL subtitles
- Support displayName parameter for audio and subtitles
- Support role (caption or subtitle) parameter for subtitles
Known limitations:
- Requires mounted file system for input and output
- Require constant GoP duration and constant sample steps
- Does not preserve subtitle styling
- Logging is not nice
Release information
- Date: 2022-03-28
- Type: Beta for testing
- Expiration Date: 2022-09-24
1.1.6.11 - Licensing
ew-vodingest
requires a valid license file to operate. The license file must be
obtained from Agile Content, and copied to /etc/edgeware/ew-vodingest/license.json
.
Note: ew-vodingest
only operates with offline licenses.
See further details here.
1.1.7 - VoD to JIT (esb3022)
1.1.7.1 - Introduction
Managed Content
The Repackager (ESB3002) and the VoD-to-Linear (ESB3019) require VoD assets to be available in ESF format. Assets are normally ingested into ESF with ew-vodingest
(ESB3021) or ew-recorder
(ESB3005). The ESF format is an internal format for efficient streaming. Such ingested assets will be referred to as managed content.
However, in some cases, for example having a big catalogue of rarely watched content, it may be unsuitable to ingest and convert all content to ESF format, and it may be preferred to keep the content as “external content”.
ew-vodjit
provides a solution by being able to read such “external content”, and convert it to ESF format on-the-fly. The ESF format is then not stored on disk, but only available via HTTP. For the repackager, the asset looks like a normal (managed) ESF asset, except that some operations like getting the first metadata may take longer time.
Supported Codecs
- video: AVC/H.264, HEVC/H.265
- audio: AAC-LC, HE-AACv1, HE-AACv2, AC-3, EC-3
- subtitles: WebVTT, TTML, SRT, STL
Input Locations
Assets must be directly mounted on server’s file-system. Remote storage, such as S3, is not supported.
1.1.7.2 - Configuration and Command Line Options
The ew-vodjit configuration parameters can be specified in the following ways:
- On the command-line
- In the configuration file (when specified by the command-line)
- Default values
They take precedence in the above order, i.e. a command-line value will override other values.
Command Line Options
The -h
option will give you all available command-line options.
$ ./ew-vodjit -h
Basic usage of ew-vodjit:
ew-vodjit -cfg <config file> -port <port>
Translates assets into ESF format on-the-fly and provides
the asset via an HTTP interface with byte ranges.
Command line options will override configuration file values.
Run ew-vodjit with options:
-basepath string
Base path to content
-cfg string
Full path to configuration file (default "/etc/edgeware/ew-vodjit/config.json")
-help
Print help
-licensefile string
License file path (default "/etc/edgeware/ew-vodjit/license.json")
-logformat string
Format and type of log: [consolejson consolepretty journald discard] (default "consolejson")
-loglevel string
Initial logging level: debug, info, warn, error, fatal, panic
-port int
Server TCP port (default 8092)
-version
Get version, date, and possible expiration date
Configuration File
Most of the above parameters can be specified in the configuration file:
{
"basePath": "/media",
"logFormat": "consolepretty",
"logLevel": "info"
}
Note: the server port and license file cannot be specified in this file
Downstream URLs and Configuration
Repackager Configuration
In the Repackager the ew-vodjit service needs to be configured as an HTTP server. Please refer to the section “HTTP server content locations” in the esb3002 User Guide.
Note: Request URLs to ew-vodjit for assets must be prepended with jit/
.
To request an asset at <basepath>/archive1/movie1
The request URL for the above asset should be something like:
http://<repackager>/__cl/s:jit/__c/jit/archive1/movie1/__op/default/__f/index.m3u8
To avoid the jit/
in the URL, an additional location
can be configured in the
Repackager’s ew-repackager-server.conf
.
VoD to Linear [ew-vod2cbm] Configuration
In the ew-vod2cbm service, each asset must be added using the
rest API /assetpaths
.
Where the "path"
field is the full HTTP URL to the asset in the ew-vodjit
service.
An entry for the above asset should be be:
"id": "...",
"path": "jit/archive1/movie1"
Assets can also be added in the startup configuration file. This is of course less flexible but can be suitable for testing.
1.1.7.3 - Credits
License List
The table below lists the third party libraries used by this software and their respective license types.
License Details
This section includes all the licenses/notices for each dependency verbatim
github.com/asticode/go-astikit
LICENSE
MIT License
Copyright (c) 2020 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/asticode/go-astisub
LICENSE
MIT License
Copyright (c) 2016 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/asticode/go-astits
LICENSE
MIT License
Copyright (c) 2017 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/aws/aws-sdk-go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.
github.com/aws/aws-sdk-go/internal/sync/singleflight
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/barkimedes/go-deepcopy
LICENSE
MIT License
Copyright (c) 2020 Sabrina Williams
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/beorn7/perks/quantile
LICENSE
Copyright (C) 2013 Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/cespare/xxhash/v2
LICENSE
Copyright (c) 2016 Caleb Spare
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Comcast/gots
LICENSE
/* MIT License
Copyright 2016 Comcast Cable Communications Management, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
NOTICE
Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).
github.com/coreos/go-systemd/v22/journal
LICENSE
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
- Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
- Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
- Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
- Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
- Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
- Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
- Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
- Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
CoreOS Project Copyright 2018 CoreOS, Inc
This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).
github.com/Eyevinn/dash-mpd/mpd
LICENSE
MIT License
Copyright (c) 2023 Eyevinn Technology AB.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Eyevinn/dash-mpd/xml
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/Eyevinn/mp4ff
LICENSE
MIT License
Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Eyevinn/mp4ff/bits
LICENSE
Copyright
Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB
.
Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits
Copyright (c) 2017 Taichi Nakashima
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Eyevinn/mp4ff/mp4
LICENSE
Copyright
Most code is Copyright (c) 2019-2022 Edgeware AB, 2023- Eyevinn Technology AB
.
Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has
Copyright (c) 2015 Jean-François Bustarret
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-chi/chi/v5
LICENSE
Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-chi/docgen
LICENSE
Copyright (c) 2016-Present https://github.com/go-chi authors
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/jsonpointer
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-openapi/jsonreference
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-openapi/spec
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-openapi/swag
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-playground/locales
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-playground/universal-translator
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-playground/validator
LICENSE
The MIT License (MIT)
Copyright (c) 2015 Dean Karn
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/golang/protobuf/proto
LICENSE
Copyright 2010 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/google/go-cmp/cmp
LICENSE
Copyright (c) 2017 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/hashicorp/errwrap
LICENSE
Mozilla Public License, version 2.0
- Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor’s Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses” means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
- License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party’s
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
- Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients’ rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients’
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
Termination
5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.
Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.
Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
Litigation
Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims.
Miscellaneous
This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.
Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.
README
errwrap
errwrap
is a package for Go that formalizes the pattern of wrapping errors
and checking if an error contains another error.
There is a common pattern in Go of taking a returned error
value and
then wrapping it (such as with fmt.Errorf
) before returning it. The problem
with this pattern is that you completely lose the original error
structure.
Arguably the correct approach is that you should make a custom structure
implementing the error
interface, and have the original error as a field
on that structure, such as this example.
This is a good approach, but you have to know the entire chain of possible
rewrapping that happens, when you might just care about one.
errwrap
formalizes this pattern (it doesn’t matter what approach you use
above) by giving a single interface for wrapping errors, checking if a specific
error is wrapped, and extracting that error.
Installation and Docs
Install using go get github.com/hashicorp/errwrap
.
Full documentation is available at http://godoc.org/github.com/hashicorp/errwrap
Usage
Basic Usage
Below is a very basic example of its usage:
// A function that always returns an error, but wraps it, like a real
// function might.
func tryOpen() error {
_, err := os.Open("/i/dont/exist")
if err != nil {
return errwrap.Wrapf("Doesn't exist: {{err}}", err)
}
return nil
}
func main() {
err := tryOpen()
// We can use the Contains helpers to check if an error contains
// another error. It is safe to do this with a nil error, or with
// an error that doesn't even use the errwrap package.
if errwrap.Contains(err, "does not exist") {
// Do something
}
if errwrap.ContainsType(err, new(os.PathError)) {
// Do something
}
// Or we can use the associated `Get` functions to just extract
// a specific error. This would return nil if that specific error doesn't
// exist.
perr := errwrap.GetType(err, new(os.PathError))
}
Custom Types
If you’re already making custom types that properly wrap errors, then
you can get all the functionality of errwraps.Contains
and such by
implementing the Wrapper
interface with just one function. Example:
type AppError {
Code ErrorCode
Err error
}
func (e *AppError) WrappedErrors() []error {
return []error{e.Err}
}
Now this works:
err := &AppError{Err: fmt.Errorf("an error")}
if errwrap.ContainsType(err, fmt.Errorf("")) {
// This will work!
}
errwrap
// Package errwrap implements methods to formalize error wrapping in Go.
//
// All of the top-level functions that take an error
are built to be able
// to take any error, not just wrapped errors. This allows you to use errwrap
// without having to type-check and type-cast everywhere.
package errwrap
import ( “errors” “reflect” “strings” )
// WalkFunc is the callback called for Walk. type WalkFunc func(error)
// Wrapper is an interface that can be implemented by custom types to // have all the Contains, Get, etc. functions in errwrap work. // // When Walk reaches a Wrapper, it will call the callback for every // wrapped error in addition to the wrapper itself. Since all the top-level // functions in errwrap use Walk, this means that all those functions work // with your custom type. type Wrapper interface { WrappedErrors() []error }
// Wrap defines that outer wraps inner, returning an error type that // can be cleanly used with the other methods in this package, such as // Contains, GetAll, etc. // // This function won’t modify the error message at all (the outer message // will be used). func Wrap(outer, inner error) error { return &wrappedError{ Outer: outer, Inner: inner, } }
// Wrapf wraps an error with a formatting message. This is similar to using
// fmt.Errorf
to wrap an error. If you’re using fmt.Errorf
to wrap
// errors, you should replace it with this.
//
// format is the format of the error message. The string ‘{{err}}’ will
// be replaced with the original error message.
//
// Deprecated: Use fmt.Errorf()
func Wrapf(format string, err error) error {
outerMsg := “
outer := errors.New(strings.Replace(
format, "{{err}}", outerMsg, -1))
return Wrap(outer, err)
}
// Contains checks if the given error contains an error with the // message msg. If err is not a wrapped error, this will always return // false unless the error itself happens to match this msg. func Contains(err error, msg string) bool { return len(GetAll(err, msg)) > 0 }
// ContainsType checks if the given error contains an error with // the same concrete type as v. If err is not a wrapped error, this will // check the err itself. func ContainsType(err error, v interface{}) bool { return len(GetAllType(err, v)) > 0 }
// Get is the same as GetAll but returns the deepest matching error. func Get(err error, msg string) error { es := GetAll(err, msg) if len(es) > 0 { return es[len(es)-1] }
return nil
}
// GetType is the same as GetAllType but returns the deepest matching error. func GetType(err error, v interface{}) error { es := GetAllType(err, v) if len(es) > 0 { return es[len(es)-1] }
return nil
}
// GetAll gets all the errors that might be wrapped in err with the // given message. The order of the errors is such that the outermost // matching error (the most recent wrap) is index zero, and so on. func GetAll(err error, msg string) []error { var result []error
Walk(err, func(err error) {
if err.Error() == msg {
result = append(result, err)
}
})
return result
}
// GetAllType gets all the errors that are the same type as v. // // The order of the return value is the same as described in GetAll. func GetAllType(err error, v interface{}) []error { var result []error
var search string
if v != nil {
search = reflect.TypeOf(v).String()
}
Walk(err, func(err error) {
var needle string
if err != nil {
needle = reflect.TypeOf(err).String()
}
if needle == search {
result = append(result, err)
}
})
return result
}
// Walk walks all the wrapped errors in err and calls the callback. If // err isn’t a wrapped error, this will be called once for err. If err // is a wrapped error, the callback will be called for both the wrapper // that implements error as well as the wrapped error itself. func Walk(err error, cb WalkFunc) { if err == nil { return }
switch e := err.(type) {
case *wrappedError:
cb(e.Outer)
Walk(e.Inner, cb)
case Wrapper:
cb(err)
for _, err := range e.WrappedErrors() {
Walk(err, cb)
}
case interface{ Unwrap() error }:
cb(err)
Walk(e.Unwrap(), cb)
default:
cb(err)
}
}
// wrappedError is an implementation of error that has both the // outer and inner errors. type wrappedError struct { Outer error Inner error }
func (w *wrappedError) Error() string { return w.Outer.Error() }
func (w *wrappedError) WrappedErrors() []error { return []error{w.Outer, w.Inner} }
func (w *wrappedError) Unwrap() error { return w.Inner }
github.com/hashicorp/go-multierror
LICENSE
Mozilla Public License, version 2.0
- Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor’s Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses” means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
- License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party’s
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
- Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients’ rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients’
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
Termination
5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.
Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.
Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
Litigation
Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims.
Miscellaneous
This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.
Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.
Makefile
TEST?=./…
default: test
test runs the test suite and vets the code.
test: generate
@echo “==> Running tests…”
@go list $(TEST)
| grep -v “/vendor/”
| xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS}
testrace runs the race checker
testrace: generate
@echo “==> Running tests (race)…”
@go list $(TEST)
| grep -v “/vendor/”
| xargs -n1 go test -timeout=60s -race ${TESTARGS}
updatedeps installs all the dependencies needed to run and build.
updatedeps: @sh -c “’${CURDIR}/scripts/deps.sh’ ‘${NAME}’”
generate runs go generate
to build the dynamically generated source files.
generate:
@echo “==> Generating…”
@find . -type f -name ‘.DS_Store’ -delete
@go list ./…
| grep -v “/vendor/”
| xargs -n1 go generate
.PHONY: default test testrace updatedeps generate
README
go-multierror
go-multierror
is a package for Go that provides a mechanism for
representing a list of error
values as a single error
.
This allows a function in Go to return an error
that might actually
be a list of errors. If the caller knows this, they can unwrap the
list and access the errors. If the caller doesn’t know, the error
formats to a nice human-readable format.
go-multierror
is fully compatible with the Go standard library
errors package, including the
functions As
, Is
, and Unwrap
. This provides a standardized approach
for introspecting on error values.
Installation and Docs
Install using go get github.com/hashicorp/go-multierror
.
Full documentation is available at https://pkg.go.dev/github.com/hashicorp/go-multierror
Requires go version 1.13 or newer
go-multierror
requires go version 1.13 or newer. Go 1.13 introduced
error wrapping, which
this library takes advantage of.
If you need to use an earlier version of go, you can use the v1.0.0 tag, which doesn’t rely on features in go 1.13.
If you see compile errors that look like the below, it’s likely that you’re on an older version of go:
/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is
Usage
go-multierror is easy to use and purposely built to be unobtrusive in existing Go applications/libraries that may not be aware of it.
Building a list of errors
The Append
function is used to create a list of errors. This function
behaves a lot like the Go built-in append
function: it doesn’t matter
if the first argument is nil, a multierror.Error
, or any other error
,
the function behaves as you would expect.
var result error
if err := step1(); err != nil {
result = multierror.Append(result, err)
}
if err := step2(); err != nil {
result = multierror.Append(result, err)
}
return result
Customizing the formatting of the errors
By specifying a custom ErrorFormat
, you can customize the format
of the Error() string
function:
var result *multierror.Error
// ... accumulate errors here, maybe using Append
if result != nil {
result.ErrorFormat = func([]error) string {
return "errors!"
}
}
Accessing the list of errors
multierror.Error
implements error
so if the caller doesn’t know about
multierror, it will work just fine. But if you’re aware a multierror might
be returned, you can use type switches to access the list of errors:
if err := something(); err != nil {
if merr, ok := err.(*multierror.Error); ok {
// Use merr.Errors
}
}
You can also use the standard errors.Unwrap
function. This will continue to unwrap into subsequent errors until none exist.
Extracting an error
The standard library errors.As
function can be used directly with a multierror to extract a specific error:
// Assume err is a multierror value
err := somefunc()
// We want to know if "err" has a "RichErrorType" in it and extract it.
var errRich RichErrorType
if errors.As(err, &errRich) {
// It has it, and now errRich is populated.
}
Checking for an exact error value
Some errors are returned as exact errors such as the ErrNotExist
error in the os
package. You can check if this error is present by using
the standard errors.Is
function.
// Assume err is a multierror value
err := somefunc()
if errors.Is(err, os.ErrNotExist) {
// err contains os.ErrNotExist
}
Returning a multierror only if there are errors
If you build a multierror.Error
, you can use the ErrorOrNil
function
to return an error
implementation only if there are errors to return:
var result *multierror.Error
// ... accumulate errors here
// Return the `error` only if errors were added to the multierror, otherwise
// return nil since there are no errors.
return result.ErrorOrNil()
append
package multierror
// Append is a helper function that will append more errors // onto an Error in order to create a larger multi-error. // // If err is not a multierror.Error, then it will be turned into // one. If any of the errs are multierr.Error, they will be flattened // one level into err. // Any nil errors within errs will be ignored. If err is nil, a new // *Error will be returned. func Append(err error, errs …error) *Error { switch err := err.(type) { case *Error: // Typed nils can reach here, so initialize if we are nil if err == nil { err = new(Error) }
// Go through each error and flatten
for _, e := range errs {
switch e := e.(type) {
case *Error:
if e != nil {
err.Errors = append(err.Errors, e.Errors...)
}
default:
if e != nil {
err.Errors = append(err.Errors, e)
}
}
}
return err
default:
newErrs := make([]error, 0, len(errs)+1)
if err != nil {
newErrs = append(newErrs, err)
}
newErrs = append(newErrs, errs...)
return Append(&Error{}, newErrs...)
}
}
flatten
package multierror
// Flatten flattens the given error, merging any *Errors together into // a single *Error. func Flatten(err error) error { // If it isn’t an *Error, just return the error as-is if _, ok := err.(*Error); !ok { return err }
// Otherwise, make the result and flatten away!
flatErr := new(Error)
flatten(err, flatErr)
return flatErr
}
func flatten(err error, flatErr *Error) { switch err := err.(type) { case *Error: for _, e := range err.Errors { flatten(e, flatErr) } default: flatErr.Errors = append(flatErr.Errors, err) } }
format
package multierror
import ( “fmt” “strings” )
// ErrorFormatFunc is a function callback that is called by Error to // turn the list of errors into a string. type ErrorFormatFunc func([]error) string
// ListFormatFunc is a basic formatter that outputs the number of errors // that occurred along with a bullet point list of the errors. func ListFormatFunc(es []error) string { if len(es) == 1 { return fmt.Sprintf(“1 error occurred:\n\t* %s\n\n”, es[0]) }
points := make([]string, len(es))
for i, err := range es {
points[i] = fmt.Sprintf("* %s", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(es), strings.Join(points, "\n\t"))
}
group
package multierror
import “sync”
// Group is a collection of goroutines which return errors that need to be // coalesced. type Group struct { mutex sync.Mutex err *Error wg sync.WaitGroup }
// Go calls the given function in a new goroutine. // // If the function returns an error it is added to the group multierror which // is returned by Wait. func (g *Group) Go(f func() error) { g.wg.Add(1)
go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.mutex.Lock()
g.err = Append(g.err, err)
g.mutex.Unlock()
}
}()
}
// Wait blocks until all function calls from the Go method have returned, then // returns the multierror. func (g *Group) Wait() *Error { g.wg.Wait() g.mutex.Lock() defer g.mutex.Unlock() return g.err }
multierror
package multierror
import ( “errors” “fmt” )
// Error is an error type to track multiple errors. This is used to // accumulate errors in cases and return them as a single “error”. type Error struct { Errors []error ErrorFormat ErrorFormatFunc }
func (e *Error) Error() string { fn := e.ErrorFormat if fn == nil { fn = ListFormatFunc }
return fn(e.Errors)
}
// ErrorOrNil returns an error interface if this Error represents // a list of errors, or returns nil if the list of errors is empty. This // function is useful at the end of accumulation to make sure that the value // returned represents the existence of errors. func (e *Error) ErrorOrNil() error { if e == nil { return nil } if len(e.Errors) == 0 { return nil }
return e
}
func (e Error) GoString() string { return fmt.Sprintf("%#v", *e) }
// WrappedErrors returns the list of errors that this Error is wrapping. It is // an implementation of the errwrap.Wrapper interface so that multierror.Error // can be used with that library. // // This method is not safe to be called concurrently. Unlike accessing the // Errors field directly, this function also checks if the multierror is nil to // prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface. func (e *Error) WrappedErrors() []error { if e == nil { return nil } return e.Errors }
// Unwrap returns an error from Error (or nil if there are no errors). // This error returned will further support Unwrap to get the next error, // etc. The order will match the order of Errors in the multierror.Error // at the time of calling. // // The resulting error supports errors.As/Is/Unwrap so you can continue // to use the stdlib errors package to introspect further. // // This will perform a shallow copy of the errors slice. Any errors appended // to this error after calling Unwrap will not be available until a new // Unwrap is called on the multierror.Error. func (e *Error) Unwrap() error { // If we have no errors then we do nothing if e == nil || len(e.Errors) == 0 { return nil }
// If we have exactly one error, we can just return that directly.
if len(e.Errors) == 1 {
return e.Errors[0]
}
// Shallow copy the slice
errs := make([]error, len(e.Errors))
copy(errs, e.Errors)
return chain(errs)
}
// chain implements the interfaces necessary for errors.Is/As/Unwrap to // work in a deterministic way with multierror. A chain tracks a list of // errors while accounting for the current represented error. This lets // Is/As be meaningful. // // Unwrap returns the next error. In the cleanest form, Unwrap would return // the wrapped error here but we can’t do that if we want to properly // get access to all the errors. Instead, users are recommended to use // Is/As to get the correct error type out. // // Precondition: []error is non-empty (len > 0) type chain []error
// Error implements the error interface func (e chain) Error() string { return e[0].Error() }
// Unwrap implements errors.Unwrap by returning the next error in the // chain or nil if there are no more errors. func (e chain) Unwrap() error { if len(e) == 1 { return nil }
return e[1:]
}
// As implements errors.As by attempting to map to the current value. func (e chain) As(target interface{}) bool { return errors.As(e[0], target) }
// Is implements errors.Is by comparing the current value directly. func (e chain) Is(target error) bool { return errors.Is(e[0], target) }
prefix
package multierror
import ( “fmt”
"github.com/hashicorp/errwrap"
)
// Prefix is a helper function that will prefix some text // to the given error. If the error is a multierror.Error, then // it will be prefixed to each wrapped error. // // This is useful to use when appending multiple multierrors // together in order to give better scoping. func Prefix(err error, prefix string) error { if err == nil { return nil }
format := fmt.Sprintf("%s {{err}}", prefix)
switch err := err.(type) {
case *Error:
// Typed nils can reach here, so initialize if we are nil
if err == nil {
err = new(Error)
}
// Wrap each of the errors
for i, e := range err.Errors {
err.Errors[i] = errwrap.Wrapf(format, e)
}
return err
default:
return errwrap.Wrapf(format, err)
}
}
sort
package multierror
// Len implements sort.Interface function for length func (err Error) Len() int { return len(err.Errors) }
// Swap implements sort.Interface function for swapping elements func (err Error) Swap(i, j int) { err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i] }
// Less implements sort.Interface function for determining order func (err Error) Less(i, j int) bool { return err.Errors[i].Error() < err.Errors[j].Error() }
github.com/jlaffaye/ftp
LICENSE
Copyright (c) 2011-2013, Julien Laffaye jlaffaye@FreeBSD.org
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
github.com/jmespath/go-jmespath
LICENSE
Copyright 2015 James Saryerwinnie
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/josharian/intern
license
MIT License
Copyright (c) 2019 Josh Bleecher Snyder
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/KyleBanks/depth
LICENSE
MIT License
Copyright (c) 2017 Kyle Banks
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/leodido/go-urn
LICENSE
MIT License
Copyright (c) 2018 Leonardo Di Donato
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/mailru/easyjson
LICENSE
Copyright (c) 2016 Mail.Ru Group
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/mattn/go-colorable
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Yasuhiro Matsumoto
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/mattn/go-isatty
LICENSE
Copyright (c) Yasuhiro MATSUMOTO mattn.jp@gmail.com
MIT License (Expat)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/matttproud/golang_protobuf_extensions/pbutil
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
github.com/prometheus/client_golang/prometheus
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
The following components are included in this product:
perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.
Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.
Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0
github.com/prometheus/client_model/go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/common
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
README
PACKAGE
package goautoneg import “bitbucket.org/ww/goautoneg”
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FUNCTIONS
func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.
func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses
TYPES
type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header
SUBDIRECTORIES
.hg
github.com/prometheus/procfs
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.
Copyright 2014-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/rs/zerolog
LICENSE
MIT License
Copyright (c) 2017 Olivier Poitrey
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/swaggo/files/v2
LICENSE
MIT License
Copyright (c) 2019 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/swaggo/http-swagger/v2
LICENSE
MIT License
Copyright (c) 2018 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/swaggo/swag
license
MIT License
Copyright (c) 2017 Eason Lin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
golang.org/x/exp
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/net/html
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/sys
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/text
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/tools
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
google.golang.org/protobuf
LICENSE
Copyright (c) 2018 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
gopkg.in/yaml.v3
LICENSE
This project is covered by two different licenses: MIT and Apache.
MIT License
The following files were ported to Go from C files of libyaml, and thus are still covered by their original MIT license, with the additional copyright staring in 2011 when the project was ported over:
apic.go emitterc.go parserc.go readerc.go scannerc.go
writerc.go yamlh.go yamlprivateh.go
Copyright (c) 2006-2010 Kirill Simonov Copyright (c) 2006-2011 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Apache License
All the remaining project files are covered by the Apache license:
Copyright (c) 2011-2019 Canonical Ltd
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2011-2016 Canonical Ltd.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
1.1.7.4 - Releases
ESB3022 - ew-vodjit releases
1.1.7.4.1 - Release 1.0.0
New
- Fundamental ESF/JITP Support
Fixes
None
Known Limitations
- Response to first metadata request for large TS input, can be very slow
- TTML subtitle styling is not supported
- Input needs to be on local or mounted file system. Remote storage such as HTTP or S3, is not supported
1.1.7.5 - Licensing
ew-vodjit
requires a valid license file to operate. The license file must be
obtained from Agile Content, and copied to /etc/edgeware/ew-vodjit/license.json
.
See further details here.
1.1.8 - HLS Ingest (esb3023)
1.1.8.1 - Introduction
The service consumes live HLS v3 sources. The sources must be multiplexed video and audio in each variant. Separate audio, video or subtitles are not supported. Higher HLS versions are not supported.
The output segments are typically written to a RAM disk, and are to be be consumed by the Edgeware CBM (esb3003) for further integration with the Edgeware repackager.
The output segments will be generated with a fixed average segment duration that is constant over time. To achieve this, it is required that the input segments have a fixed segment duration except at ad boundaries signalled by SCTE-35 markers. At such boundaries, the input segments should be split by an extra IDR-frame.
1.1.8.2 - Installation and Upgrades
Installation
The ew-hlsingest
service is distributed as a CentOS/Red Hat RPM and is available
as ew-hlsingest.service
when installed. It works both on RH 7 and 8 and
compatible versions.
To install version x.y.z, the rpm
command can be used as follows:
yum install ./ew-hlsingest-x.y.z-1.el8.x86_64.rpm
The service can be controlled with the standard systemctl
commands:
systemctl start ew-hlsingest
systemctl stop ew-hlsingest
systemctl status ew-hlsingest
Logs from the service can be seen using journalctl -u ew-hlsingest
.
The unit file is available in /usr/lib/systemd/system/ew-hlsingest.service
.
When run as a service, ew-hlsingest reads its initial configuration from
/etc/edgeware/ew-hlsingest/config.json
.
To uninstall the service, do:
yum remove ew-hlsingest
When uninstalling or upgrading it is recommended to first stop the service.
Upgrades
There is only one version of ew-hlsingest
so there are no configuration concerns during upgrade.
In the future, to upgrade simply run:
$ sudo yum upgrade <rpm-file>
1.1.8.3 - Configuration and command-line arguments
Typically ew-hlsingest
is run as a systemd
service with command-line arguments specified in
/usr/lib/systemd/system/ew-hlsingest.service
.
In can also be started from the command-line.
Command-line arguments
ew-hlsingest -h Usage of ew-hlsingest: -cfg string Config file (default "/etc/edgeware/ew-hlsingest/config.json") -defaultConfig Print default configuration -logFormat string Format and type of log: [consolejson consolepretty journald discard] (default "consolepretty") -logLevel string log level (default "trace") -version Get version, date, and possible expiration date
Configuration parameters
The configuration file, in the location specified as above, controls the service.
Review note: generate JSON-schema
This is an example configuration with two channels:
{
"outDir": "/tmp/ew-hlsingest",
"startCatchup": 20,
"logFormat": "journald",
"logLevel": "info",
"maxAdBreakDuration": 600,
"channels": [
{
"name": "ch1",
"url": "https://sometv.org/channel1",
"configID": 0,
"maxBandwidth": 100000000,
"liveWindowS": 180,
"logLevel": "info"
},
{
"name": "ch2",
"url": "https://othertv.org/channel1",
"configID": 0,
"maxBandwidth": 100000000,
"liveWindowS": 180,
"logLevel": "info"
}
]
}
Some fields may need clarification:
maxAdBreakDuration
Sometimes upstreams may fail to insert ad-break-end-markers (i.e. #EXT-X-CUE-IN
)
After the specified duration inside an ad-break ew-hlsingest
will insert an end-marker.
maxBandwidth
variants with bitrates above this threshold will be dropped from the output
configID
allows the “downstream” CBM to distinguish between channel configurations. For example if maxBandwidth
is modified the number output variants change, and configID
must be incremented.
Review note: part of defaultconfig and internal struct, never referenced, remove!
startCatchup
Review note: maxAdBreakDuration
[etc] should have S
in its name to clarify unit
Configuration updates
Channels can be modified/added/removed without restarting the service. Any modification to the configuration file are
automatically detected, and channels will be restarted/started/stopped accordingly. Changes not directly related to the
service itself, such as logLevel
, will not trigger a restart.
Integration with ew-cbm
ew-hlsingest
acts as the input source for ew-cbm
(Catchup Buffer Manager, a part of SW Live Ingest
), and ew-cbm
,
in its turn, will be the backend of sw-repackager
, from which the channels are streamed to CDN, and then, to
end user.
To make ew-hlsingest
channel visible with ew-cbm
, outDir
attribute in ew-hlsingest
configuration have to be
the same with the location that ew-cbm
gets the input from. The service file of ew-cbm
can be referred to get
that location (specified by argument --live-ingest-path
), it is usually /mnt/ramdisk
.
cat /usr/lib/systemd/system/ew-cbm.service ... ExecStart=/usr/bin/ew-cbm --live-ingest-path /mnt/ramdisk --socket-path /var/run/edgeware/ew-cbm/socket --with-accel-redirect --node-id=%m ...
The next step is configuring the channel for ew-cbm
to work with ew-hlsingest
buffer.
confcli services.liveIngest.channels. -w
Running wizard for resource 'Channels'
<A list of channels>
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
Channels <A list of channels>: [
Channel <Configuration for a single channel>: {
Channel Name (default: default): hlsingest-channel
Channel State (default: enabled): cbm-only
Catchup Location (default: ): cb1
Channel Name Alias (default: ):
Channel Template Name (default: default):
Config Id (default: 0):
Input Sources <A list of input sources>: [
Input Source <Input source configuration>: {
Backup IGMPv3 Source (default: ):
Error correction (default: off):
IGMPv3 Source (default: ):
Source (default: ):
Passphrase for SRT connection (default: ):
Tracks <A list of tracks from the channel template>: [
Track <Configuration for a single track>: {
Log Level (default: INHERIT):
Track Name (default: default):
Variant flags (default: -1):
}
Add another 'track' element to array 'tracks'? [y/N]:
]
Use As SCTE-35 Source (default: False):
}
Add another 'inputSource' element to array 'inputSources'? [y/N]:
]
Logging <Logging configuration>: {
General Log Level (default: INHERIT):
Track Log Level (default: INHERIT):
Source Log Level (default: INHERIT):
}
Nielsen Marker Tracking (default: off):
Segmentation Template Name (default: default):
}
Add another 'channel' element to array 'channels'? [y/N]:
]
Generated config:
{
"channels": [
{
"name": "hlsingest-channel",
"state": "cbm-only",
"catchupLocation": "cb1",
"alias": "",
"channelTemplate": "default",
"configId": 0,
"inputSources": [
{
"backupIgmpV3Source": "",
"errorCorrection": "off",
"igmpV3Source": "",
"source": "",
"srtPassphrase": "",
"tracks": [
{
"logLevel": "INHERIT",
"name": "default",
"variantFlags": -1
}
],
"useAsScte35Source": false
}
],
"logging": {
"general": "INHERIT",
"track": "INHERIT",
"source": "INHERIT"
},
"nielsenMarkerTracking": "off",
"segmentationTemplate": "default"
}
]
}
Merge and apply the config? [y/n]:
Only three configurations should be cared about: Channel Name (name)
, Channel State (state)
,
Catchup Location (catchupLocation)
, others are meaningful for ew-live-ingest
, another part of SW Live Ingest
,
so they should be left as default:
- Channel Name (name): have to be exactly the same with the channel
name
configured inew-hlsingest
, so thatew-cbm
will know where to look for the input. - Channel State (state):
cbm-only
is a must. - Catchup Location (catchupLocation) (optional): is the location that
ew-cbm
will write the catch up buffer to, please refer toew-cbm
documentation to know how to configure it.
After done configuring, this command, ew-cb-media
, can be used to check for the running channel. If the
channel name appears in the output of that command and the duration of catchup buffer starts growing
(repeat the command the see if the channel is growing, or just use watch ew-cb-media
), then the live content
can now be delivered through ew-cbm
to repackager and beyond.
1.1.8.4 - Logging
Logging
To provide context to each log message, structured logging
is used. Thus
instead of free text log messages without any specific format, the log data is
to some extent divided into fields of name-value pairs, making the logs more
coherent and more suitable for processing by external tools.
Log messages related to a specific HTTP request include the log field named
request_id
which can be used to filter out specific requests.
The log field named topic
is always present and is used to separate different
areas of logging. The current topics are access
, messages
and error
, and
are used to log HTTP access, debug messages and panic stack traces,
respectively.
As a comparison, the topics are similar to having separate files for access logging, debug messages and errors in a conventional file-based logging system.
Log formats
When run from the command line ew-hlsingest can log in one of the formats
consolepretty,
consolejsonor
journalddepending on the value of the
-logformatparameter. Logging can be disabled by using the value
discard`.
$ ew-hlsingest -upstream http://127.0.0.1 -logformat consolejson
consolepretty
logs to standard output (stdout
) in a human-readable format.
Each log line starts with the date and the log message followed by the context-
dependent log fields:
2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...
consolejson
logs to stdout
using a JSON object for each message:
{"level":"info","topic":"access","time":"2022-02-07T12:06:07Z","bytes_out":27592, ...}
When run as a systemd
service, ew-hlsingest logs directly to
journaldusing the
logjournaldconfiguration parameter. When stored in
journald`, field
names are upper case whereas the values keep their format. Some examples:
To see entries a specific channel:
$ journalctl -u ew-hlsingest CHANNEL=ch1 -o verbose
To continuously monitor the service:
$ journalctl -fu ew-hlsingest
Log levels
At startup the log level is set to info
.
The log level can be changed by posting a form-field named level
to the
loglevel
endpoint on the `ew-hlsingest server:
$ curl -F level=debug ew-hlsingest-server:8090/loglevel
The available log levels and how they relate to systemd priority values is listed below:
Log level Systemd priority
trace 7
debug 7
info 6
warn 4
error 3
fatal 2
panic 0
To e.g. see all error and warning messages using journalctl:
$ journalctl -u ew-hlsingest PRIORITY=3 PRIORITY=4
Messages with higher level than the configured one will not be logged.
1.1.8.5 - Credits
Review Note:: this list was copied from ew-vod2cbm. It is just a placeholder until we generate it here.
License List
The table below lists the third party libraries used by this software and their respective license types.
License Details
This section includes all the licenses/notices for each dependency verbatim
github.com/prometheus/common
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Common libraries shared by Prometheus Go components. Copyright 2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/swaggo/swag
license
MIT License
Copyright (c) 2017 Eason Lin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/Comcast/gots
LICENSE
/* MIT License
Copyright 2016 Comcast Cable Communications Management, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
NOTICE
Go Transport Stream Library Copyright 2016 Comcast Cable Communications Management, LLC This product includes software developed at Comcast (http://www.comcast.com/).
github.com/KyleBanks/depth
LICENSE
MIT License
Copyright (c) 2017 Kyle Banks
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/PuerkitoBio/urlesc
LICENSE
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/asticode/go-astikit
LICENSE
MIT License
Copyright (c) 2020 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/beorn7/perks/quantile
LICENSE
Copyright (C) 2013 Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/matttproud/golang_protobuf_extensions/pbutil
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
github.com/go-chi/chi/v5
LICENSE
Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-chi/docgen
LICENSE
Copyright (c) 2016-Present https://github.com/go-chi authors
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/josharian/intern
license
MIT License
Copyright (c) 2019 Josh Bleecher Snyder
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/client_model/go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Data model artifacts for Prometheus. Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
github.com/prometheus/procfs
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc.
Copyright 2014-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
gopkg.in/yaml.v2
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Copyright 2011-2016 Canonical Ltd.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/asticode/go-astits
LICENSE
MIT License
Copyright (c) 2017 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/jsonreference
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-openapi/swag
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-playground/validator
LICENSE
The MIT License (MIT)
Copyright (c) 2015 Dean Karn
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/golang/protobuf
LICENSE
Copyright 2010 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/text
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/asticode/go-astisub
LICENSE
MIT License
Copyright (c) 2016 Quentin Renard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/cespare/xxhash/v2
LICENSE
Copyright (c) 2016 Caleb Spare
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/zencoder/go-dash/v3
LICENSE
Copyright Brightcove, Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
golang.org/x/tools
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/aws/aws-sdk-go
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
AWS SDK for Go Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Copyright 2014-2015 Stripe, Inc.
github.com/coreos/go-systemd/v22/journal
LICENSE
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
- Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
- Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
- Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
- Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
- Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
- Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
- Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
- Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
CoreOS Project Copyright 2018 CoreOS, Inc
This product includes software developed at CoreOS, Inc. (http://www.coreos.com/).
github.com/mailru/easyjson
LICENSE
Copyright (c) 2016 Mail.Ru Group
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/rs/zerolog
LICENSE
MIT License
Copyright (c) 2017 Olivier Poitrey
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
google.golang.org/protobuf
LICENSE
Copyright (c) 2018 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
golang.org/x/sys
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/PuerkitoBio/purell
LICENSE
Copyright (c) 2012, Martin Angers All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/edgeware/mp4ff/bits
LICENSE
Copyright
Copyright (c) 2019-2020 Edgeware AB
.
Some code in this directory comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits
Copyright (c) 2017 Taichi Nakashima
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-playground/universal-translator
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/leodido/go-urn
LICENSE
MIT License
Copyright (c) 2018 Leonardo Di Donato
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/client_golang/prometheus
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
NOTICE
Prometheus instrumentation library for Go applications Copyright 2012-2015 The Prometheus Authors
This product includes software developed at SoundCloud Ltd. (http://soundcloud.com/).
The following components are included in this product:
perks - a fork of https://github.com/bmizerany/perks https://github.com/beorn7/perks Copyright 2013-2015 Blake Mizerany, Björn Rabenstein See https://github.com/beorn7/perks/blob/master/README.md for license details.
Go support for Protocol Buffers - Google’s data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details.
Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0
github.com/swaggo/files
LICENSE
MIT License
Copyright (c) 2019 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/aws/aws-sdk-go/internal/sync/singleflight
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
github.com/edgeware/mp4ff
LICENSE
MIT License
Copyright (c) 2019-2020 Edgeware
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/jsonpointer
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/jmespath/go-jmespath
LICENSE
Copyright 2015 James Saryerwinnie
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/swaggo/http-swagger
LICENSE
MIT License
Copyright (c) 2018 Swaggo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/edgeware/mp4ff/mp4
LICENSE
Copyright
Most code is Copyright (c) 2019-2020 Edgeware AB
.
Some code in this directory comes from or is based on https://github.com/jfbus/mp4 which has
Copyright (c) 2015 Jean-François Bustarret
.
All code has the same MIT License.
License
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/go-openapi/spec
LICENSE
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Definitions.
“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
github.com/go-playground/locales
LICENSE
The MIT License (MIT)
Copyright (c) 2016 Go Playground
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
README
PACKAGE
package goautoneg import “bitbucket.org/ww/goautoneg”
HTTP Content-Type Autonegotiation.
The functions in this package implement the behaviour specified in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of the Open Knowledge Foundation Ltd. nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FUNCTIONS
func Negotiate(header string, alternatives []string) (content_type string) Negotiate the most appropriate content_type given the accept header and a list of alternatives.
func ParseAccept(header string) (accept []Accept) Parse an Accept Header string returning a sorted list of clauses
TYPES
type Accept struct { Type, SubType string Q float32 Params map[string]string } Structure to represent a clause in an HTTP Accept Header
SUBDIRECTORIES
.hg
golang.org/x/net
LICENSE
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1.8.6 - Releases
ESB3023 - ew-hlsingest releases
1.1.8.6.1 - Release 0.6.0
Early release for ingesting HLS v3 streams.
Release information
- Date: 2022-12-31
- Type: Beta for testing
1.1.9 -
1.1.10 - Solutions
1.1.11 - General
1.1.11.1 - Monitoring and Logging
Health check
You can check the health of the server by making a request to /healthz
, which
should return a 200 OK response.
Structured Logging
To aid processing, structured logging is available. This makes the logs more
coherent, and more suitable for processing by external tools. The log formats
journald
or consolejson
will trigger structured logging.
Log messages related to a specific HTTP request include the log field named
request_id
which can be used to filter out specific requests.
The log field named topic
is always present and is used to separate different
areas of logging. The topics are access
, messages
, licensing
and error
.
It is useful when querying the log.
Log formats
When run from the command line the application can log in one of the formats
consolepretty
, consolejson
or journald
depending on the value of the
-logformat
parameter. Logging can be disabled by using the value discard
.
$ ew-vod2cbm -upstream http://127.0.0.1 -logformat consolejson
consolepretty
logs to standard output (stdout
) in a human-readable format.
Each log line starts with the date and the log message followed by the context-
dependent log fields:
2022-02-07T11:54:42Z INF Incoming request bytes_out=27592 latency_ms=6.18251 method=GET ...
consolejson
logs to stdout
using a JSON object for each message:
{level:info,topic:access,time:2022-02-07T12:06:07Z,bytes_out:27592, ...}
When running as a systemd
service, it logs directly to journald
. In this
case field names are upper case whereas the values keep their format.
Here are a few examples of querying the logs:
$ journalctl -u ew-vodjit TOPIC=access -o verbose
To see entries with a specific request ID:
$ journalctl -u ew-vod2cbm REQUEST_ID=host/B1Po0eYz1d-000006 -o verbose
To see the call stack in the event of a crash:
$ journalctl -u ew-manip TOPIC=error -o verbose
Using the verbose
output includes all available name-value fields. Without
this only the log message is printed. The field named JSON
contains the
original structured log message as sent by the service. To filter out only
this field --output-fields=JSON
can be used, however this requires a systemd
version of at least 236.
$ journalctl -u ew-vod2cbm --output-fields=JSON TOPIC=access
To continuously monitor the service:
$ journalctl -fu ew-vod2cbm
Log levels
The startup log level is set according to the service configuration.
The log level for a running service can be changed by posting
a form-field named level
to the loglevel
endpoint. For example:
$ curl -F level=debug ew-vod2cbm-server:8090/loglevel
The available log levels and how they relate to systemd priority values is listed below:
Log level Systemd priority
trace 7
debug 7
info 6
warn 4
error 3
fatal 2
panic 0
To e.g. see all error [3] and warning [4] messages using journalctl:
$ journalctl -u ew-vod2cbm PRIORITY=3 PRIORITY=4
Use a GET request to see the current log level:
$ curl ew-vod2cbm-server:8090/loglevel
Messages with higher level than the configured one will not be logged.
Monitoring
The services generate Prometheus data, available at the endpoint: /metrics
.
The respective metrics for the services are:
ew-vod2cbm
ew_audio_segment_requests_total
ew_audio_segment_request_duration_milliseconds
ew_video_segment_requests_total
ew_video_segment_request_duration_milliseconds
ew_subs_segment_requests_total
ew_subs_segment_request_duration_milliseconds
ew_segment_times_requests_total
ew_segment_times_request_duration_milliseconds
ew_content_info_requests_total
ew_content_info_request_duration_milliseconds
ew-manip
ew_hls_requests_total
ew_hls_request_duration_milliseconds
ew_dash_requests_total
ew_dash_request_duration_milliseconds
ew-vodjit
ew_cmaf_segment_requests_total
ew_cmaf_segment_request_duration_milliseconds
ew_dat_segment_requests_total
ew_dat_segment_request_duration_milliseconds
ew_content_info_requests_total
ew_content_info_request_duration_milliseconds
ew_manifest_requests_total
ew_manifest_request_duration_milliseconds
1.1.11.2 - CCMI URLs
CCMI URLs
Edgeware’s origin URL format is called CCMI URLs
and is the format
that StreamBuilder understands. A typical URL looks like:
http://<server>/__cl/<cl>/__c/<content>/__op/<op>/__f/<pres><ext>
where the different parts are indicated by prefixes starting with two underscores,
and where the file extension <ext>
starts with a period if present.
The most important StreamBuilder fields are:
__cl : content location with parts prefix:name
+ cg:<live> stands for channel group <live> and denote a group
of live channels configured with the name <live>
+ s:<vod> stands for a storage path for vod assets
__c : the actual content or asset path (can contain slashes)
__op : output profile `<op>`, defining the encryption/DRM system or segment addressing
Segments with different output profiles are not compatible
__f : the file path but also the way to choose a presentation.
A presentation is a manifest variation, for example exluding some variants.
The segments can be the same between presentation.
The extensions ".m3u8" maps to HLS, ".mpd" maps to DASH and "Manifest" or
".ism/Manifest" map to MSS
The <pres>
part is matched to a presentation configured in repackager.
The <live>
, <vod>
, <op>
are also defined in the repackager configuration.
For segments, the URLs are further enhanced with a config_id (for live/catchup), a variant, and a segment number (for HLS and DASH with $Number$)
__f/<cfg_id>/<variant>/<nr>.cmfv
__f/<cfg_id>/<variant>/<nr>.ts
or with a time (for DASH and MSS)
__f/<cfg_id>/<variant>/D<time>.cmfv
__f/<cfg_id>/QualityLevels({bitrate})/Fragments(video={start time})
In addition, there are other possible parts like
__dci : DRM Content ID - an id used to lookup the key from license server
__account : Account to distinguish different tenants
Finally, there are query parameters for time intervals
?startTime=
?stopTime=
and query parameters for variant flags mask
?p=<variant_flags_mask>
In addition, there may also be a part ?pre=1
that triggers
ESB3020 - ew-manip
.
1.1.11.3 - ESF Format
ESF is Edgeware’s CMAF-based storage format for both live and VoD content. It saves media data in CMAF tracks, and has additional metadata files. It supports H.264/AVC and HEVC/H.265 video, AAC and AC-3 audio, and wvtt subtitles.
Asset media data
The media data is stored as CMAF tracks in files with extensions “.cmfv”, “.cmfa”, and “.cmft”, for video, audio, and subtitles, respectively. The subtitle format is “wvtt” which is much more storage-efficient than “stpp”.
Asset metadata
The metadata for the assets are stored in two places:
- a single
content_info.json
file describing the tracks - segment info (
.dat
) files describing the segments, one per track
Content info
Content info is stored in a file named content_info.json
inside the asset directory.
It is a JSON file containing enough information about the tracks of the assets, to be
able to fill in all information about media tracks in HLS, DASH, or MSS manifests.
This includes codecs, languages, time scales, bitrates etc. However, it does
not contain information about individual segments. Such information is stored in segment info files.
Segment info
Metadata about the segments are stored in segment info files with extension .dat
.
There is exactly one such file for each media file.
These files describe the data of the individual segments of the CMAF tracks with a 32-byte entry for each segment:
Field | Type | Description |
---|---|---|
Nr | uint32 | Segment number |
Time | uint64 | Time (normally presentationTime=DecodeTime) |
Dur | uint32 | Duration of segment in timescale specified in content info |
Size | uint32 | Size in bytes |
Offset | uint64 | Byte offset inside track file |
Rest | uint32 | Flags for SCTE-markers and other information |
For VoD assets, an init segment is stored at the start of the file.
Its size is given by the Offset
of the first media segment in the
segment info file.
Commonalities with DASH OnDemand format
DASH OnDemand stores media data in the same type of CMAF tracks as ESF. However, the metadata is stored in other structures.
To describe the asset and its variants, there is a manifest called
Media Presentation Description
(MPD) which is an XML file with file extension .mpd
.
It is similar to the ESF content_info.json file. It has explicit switching groups called Adaptation Sets, but is lacking some other information compared to ESF like video parameter sets which are needed to generate MSS manifests.
Similar to ESF, there is a second structure that contains the information about the
segments. In the case of DASH OnDemand, this information is stored in a sidx
box
inside the CMAF track itself. Its position is at the beginning of the media file
right after the init segment, and before the actual media data.
By generating a DASH MPD file, and inserting a sidx
box in the media tracks,
it is possible to make VoD assets which are both compatible with DASH OnDemand and
the ESF format. The new ESB3031 ew-vodingest
tool generates such combined ingested
files. For DASH OnDemand, a complete WebVTT file is used instead of wvtt segments.
That complete WebVTT file is generated by extracting and concatenating all subtitle
cues from the wvtt
subtitle tracks used in the ESF format.
Live storage using ESF
The main reason to use ESF instead of DASH OnDemand, is that the latter does not support
live content, but requires a static structure. In fact, since the sidx
box must be placed
before the media, it is not even possible to concatenate media segments and write a
sidx
box at the end. With ESF we can have the same format for both VoD and live.
The SegmentInfo files are separated from the media files and use 32 bytes per segment. These are therefore easy to seek and also to grow, by just adding another 32 bytes for each segment. In the ESB3003 catchup buffer, we store live content in one-minute files.
1.1.11.4 - Licensing
All Agile Content Processing products require a valid license file to operate. For the
server products a few endpoints such as /metrics
and /licensing
are accessible
without a valid license, but the core functionality requires a license.
The license file
The license file must be obtained from Agile Content along with your software. Depending on your agreement the file will contain either an online or offline license. For online licenses, the machine running the service, must have an internet connection, in order to access the license server.
The command-line products, such as ew-vodingest
only support offline licenses.
Using the license file
The license must be placed in: /etc/edgeware/<product-name>/license.json
e.g:
/etc/edgeware/ew-vod2cbm/license.json
You must never attempt to edit the license file. When you receive a new
license.json
, and your product is a service, the service must be restarted.
License expiry
Your product will not work beyond the expiry date.
For online as well as offline licenses the server product logs will warn
you that the service is about to expire, when the expiry date is closer than
7 days. For automatic expiry monitoring, the /licensing
HTTP endpoint is recommended.
Please note that there will be no warning before expiry for command-line products.
When the service, under a valid service contract, is about to expire, your license must be renewed:
- For online licenses, Agile Content should renew your service license on a
central license server. The licensing status can be checked by
calling the
/licensing
endpoint (see below). - For offline licenses, you should obtain a new license file.
Online licenses
Less than three minutes after a service is started it starts to query the license server periodically. In case of temporary network or license server outages (up to 2 hours), your service will continue to function.
Checking the license: /licensing
endpoint
You may query status of your license by querying your service with the /licensing
endpoint. The response, in JSON-format, looks like:
$ curl localhost:8090/licensing
{
"status": "valid",
"pending_until": "",
"expiry": "2022-12-31T23:59:29Z",
"invalid_reason": "",
"license_type": "online"
}
The call will return "status": "pending"
during temporary network outage and
for less than three minutes after the service has been restarted. The response for
an expired license looks like:
{
"status": "invalid",
"pending_until": "",
"expiry": "2021-12-31T23:59:29Z",
"invalid_reason": "expired",
"license_type": "online"
}
Checking the license: server log
If the service has, or is about to expire, the server log will show the status
under "topic":"licensing"
. For example:
{"level":"warn","request_id":"adam/HLYRsgfrwz-000005","topic":"licensing",
"LicenseExpiryDate":"2022-08-30T23:59:09Z","time":"2022-08-24T11:42:28Z",
"message":"License will expire in less than 7 days, please remember to get a renewed license"}
These log messages only appear when a licensed endpoint e.g. /segment_times.json
is called.
1.2 - Automatic Speech Recognition (as a service)
1.2.1 - Getting Started
Introduction
This guide will get you started with Agile Contents Automatic Speech Recognition service. It will show you how WebVTT subtitles are generated live from an audio clip ingested with FFmpeg.
Prerequisites
Before following those steps make sure to prepare the following
- FFmpeg (or another mean to ingest WAV audio over SRT to the ASR service)
- An audio clip in a format decodable by ffmpeg
- Curl or another HTTP tool to use the API
- An account for the Automatic Speech Recognition Service (contact sales@agilecontent.com for info)
You will need the following account information
- URL in the form
<your-id>.asr.agilecontent.com
- username
- password
- Audio ingest IP
- SRT secret
Replace <your-id>
, <username>
, <password>
, <ingest-ip>
and <srt-secret>
with those values in the examples below
Validate API Access
Validate you can access the service API.
$ curl -i -u "<username>:<password>" https://<your-id>.asr.agilecontent.com/api/v1/channels
You should get a response similar to this
HTTP/2 200
date: Thu, 08 Aug 2024 09:05:13 GMT
content-type: text/plain; charset=utf-8
content-length: 3
access-control-allow-origin: *
x-request-id: ip-10-0-0-138.eu-north-1.compute.internal/nxlyokd96h-000003
[]
Create a channel
To setup a channel first prepare a file mychannel.json
with the following,
but replace the language with the language code of your audio clip
{
"id": "mychannel",
"name": "My Channel",
"input":{
"type":"srt",
"port":10000
},
"language":"en-US",
"outputs":[
"webvtt"
]
}
Then apply the channel configuration to the API
$ curl -i -u "<username>:<password>" -XPOST -H "Content-Type: application/json" https://<your-id>.asr.agilecontent.com/api/v1/channels -d @mychannel.json
You will receive a 200 OK
response with a JSON payload similar to this
{
"id": "mychannel",
"name": "My Channel",
"enabled": true,
"engine": "google",
"input": {
"type": "srt",
"port": 10000
},
"language": "en-US",
"outputs": [
"webvtt"
],
"segmentation": {
"rows": 2,
"chars_per_row": 40,
"progressive": false
}
}
Ingest the Audio
Start ingesting audio from your audiofile (named audio.ts
here).
ffmpeg -re -i audio.ts -vn -ac 1 -acodec pcm_s16le -f wav -bitexact "srt://<ingest-ip>:10000?mode=caller&passphrase=<srt-secret>"
Check the Subtitles
First request a HLS subtitle variant manifest to see available WebVTT files
$ curl https://<your-id>.asr.agilecontent.com/subtitles/mychannel/subtitles.m3u8
Replace with a specific WebVTT file to see the generated subtitles
$ curl https://<your-id>.asr.agilecontent.com/subtitles/mychannel/<replace with vtt file in manifest>.vtt
You will receive a WebVTT file, like
WEBVTT
00:00:47.717 --> 00:00:49.317
Nice subtitles you generated for me.
00:00:50.557 --> 00:00:51.117
No problem, it's been my pleasure.
You could also run the following python code to progressively see all WebVTT files as they are generated
import sys
import time
import m3u8
import requests
def watch(uri):
seen_segments = set()
while True:
manifest = m3u8.load(uri)
for s in manifest.segments:
if s.absolute_uri not in seen_segments:
print("#", s.absolute_uri)
res = requests.get(s.absolute_uri)
print(res.text)
seen_segments.add(s.absolute_uri)
if manifest.target_duration >= 1:
time.sleep(manifest.target_duration / 2)
else:
time.sleep(1)
if __name__ == "__main__":
watch(sys.argv[1])
Add it to a file show_subs.py
and run
$ pip3 install m3u8 requests
$ python3 show_subs.py https://<your-id>.asr.agilecontent.com/subtitles/mychannel/subtitles.m3u8
Adjust Subtitles
To get the current settings for mychannel
use
curl -u "<username>:<password>" https://<your-id>.asr.agilecontent.com/api/v1/channels/mychannel
Put the JSON data in a file channel-change.json
, then adjust for example chars_per_row
and apply the change with
curl -u "<username>:<password>" https://<your-id>.asr.agilecontent.com/api/v1/channels/mychannel -XPUT -H "Content-Type: application/json" -d @channel-change.json
Cleanup channel
To delete the channel mychannel
after you’re done use
$ curl -i -u "<username>:<password>" -XDELETE https://<your-id>.asr.agilecontent.com/api/v1/channels/mychannel
1.2.2 - ASR Engine Configuration
Introduction
This section will show you how to configure the Automatic Speech Recognition (ASR) engine and language settings for a channel.
There are two ASR engines available for the ASR service:
google
(Google Cloud Speech-to-Text)speechmatics
(Speechmatics)
Configure ASR Engine and Language
Add the selected engine to the channel configuration
{
"id": "mychannel",
"name": "My Channel",
"input":{
"type":"srt",
"port":10000
},
"language":"en-US",
"outputs":[
"webvtt"
],
"engine": "google"
}
If the engine is not specified, the default engine is google
.
Google Cloud Speech-to-Text
The language code for the Google ASR engine is in the form ll-CC
where ll
is the language code and CC
is the country code. For example, en-US
is English (United States) and es-ES
is Spanish (Spain).
Speechmatics
Speechmatics uses the short language code ll
, for example, ja
is Japanese and es
is Spanish.
The only exception is for English and Chinese Mandarin, where the expected output should be specified as one of the following:
en-GB
, en-US
, en-AU
, cmn-Hans (Simplified)
, cmn-Hant (Traditional)
.
Once the desired engine and language has been selected, apply the channel configuration to the API
$ curl -i -u "<username>:<password>" -XPOST -H "Content-Type: application/json" https://<your-id>.asr.agilecontent.com/api/v1/channels -d @mychannel.json
You will receive a 200 OK
response with a JSON payload similar to this
{
"id": "mychannel",
"name": "My Channel",
"enabled": true,
"engine": "google",
"input": {
"type": "srt",
"port": 10000
},
"language": "en-US",
"outputs": [
"webvtt"
],
"segmentation": {
"rows": 2,
"chars_per_row": 40,
"progressive": false
}
}
1.2.3 - Integrate ASR output with Cavena STU
Introduction
This section will show you how to use Cavena STU as an output in the Automatic Speech Recognition (ASR) service.
There are 2 modes of integration with Cavena STU.
Mode 1: If the STU Subtitle Input Protocol of your STU is available on a public IP the ASR service can connect directly to the STU.
Mode 2: If not you need to install a STU agent together with the STU that connects to the ASR service and proxies the subtitle traffic.
Setup ASR service to connect to a STU on a public IP
You need to configure the public IP and port where the ASR
service can connect to the STU Subtitle Input Protocol.
Those settings are available in our settings
API which contains system-wide
settings that are not unique for each channel used.
Access the current settings with
$ curl -i -u "<username>:<password>" https://<your-id>.asr.agilecontent.com/api/v1/settings
The output have a JSON data structure similar to this
{
"srt_passphrase": "<SRT Passphrase>",
"subtitle_filename": "subtitle.vtt",
"subtitle_rotation_interval": 4,
"stu_settings": {
"hostname": "<Public IP of the STU>",
"port": 4621,
"subtitle_type": 0,
"user_id": "test-0",
"username": "test",
"offset": 0,
"remove_accents": false,
"server_mode": false
}
}
Put the JSON data in a file settings.json
and update the following
- Set
stu_settings.hostname
to the public IP of your STU - Update
stu_settings.port
if you use a non-default port - Update
stu_settings.server_mode
tofalse
Now apply the new settings with the following command
$ curl -i -u "<username>:<password>" https://<your-id>.asr.agilecontent.com/api/v1/settings -XPUT -H "Content-Type: application/json" -d @settings.json
Continue to Create a channel further down to create a channel with a STU output.
Setup ASR service to listen for connections from a STU
Please contact your Agile Content representative for access and instructions on how to setup this mode.
Create a channel
To setup a channel first prepare a file mychannel.json
with the following,
but replace the language with the language code of your audio clip
{
"id": "mychannel",
"name": "My Channel",
"input":{
"type":"srt",
"port":10000
},
"language":"en-US",
"outputs":[
"stu_ip"
]
}
Then apply the channel configuration to the API
$ curl -i -u "<username>:<password>" -XPOST -H "Content-Type: application/json" https://<your-id>.asr.agilecontent.com/api/v1/channels -d @mychannel.json
You will receive a 200 OK
response with a JSON payload similar to this
{
"id": "mychannel",
"name": "My Channel",
"enabled": true,
"engine": "google",
"input": {
"type": "srt",
"port": 10000
},
"language": "en-US",
"outputs": [
"stu_ip"
],
"segmentation": {
"rows": 2,
"chars_per_row": 40,
"progressive": false
}
}
See the Getting Started guide for guidance on how to ingest audio and validate generated subtitles.
1.2.4 - API Reference
The Swagger API reference for your account is available at https://<your-id>.asr.agilecontent.com/swagger/index.html
. Replace <your-id>
in the URL so it matches the URL
given with your account. To interact directly with the API through the Swagger interface
you also need to provide your account username and password when asked for.
2 - Agile Content Delivery
2.1 - Components
2.1.1 - ESB3024 Router
2.1.1.1 - Getting Started
The Director serves as a versatile network service designed to redirect incoming HTTP(s) requests to the optimal host or Content Delivery Network (CDN) by evaluating various request properties through a set of rules. Although requests can be generic, the primary focus centers around audio-video content delivery. The rule engine allows users to construct routing configurations using predefined blocks, providing for the creation of intricate routing logic. This modular approach allows the users to tailor and streamline the content delivery process to meet their specific needs. The Director’s flexible rule engine takes into account factors such as geographical location, server load, content type, and other metadata from external sources to intelligently route incoming requests. It supports dynamic adjustments to seamlessly adapt to changing network conditions, ensuring efficient and reliable content delivery. The Director improves the overall user experience by delivering content from the most suitable and responsive sources, thereby reducing latency and enhancing performance.
Requirements
Hardware
The Director is designed to be installed and operated on commodity hardware, ensuring accessibility for a broad range of users. The minimum hardware specifications are as follows:
- CPU: x86-64 AMD or Intel with at least 2 cores.
- Memory: At least 2 GB free at runtime.
Operating System Compatibility
The Director is officially supported on Red Hat Enterprise Linux 8 or 9 or any
compatible operating system. In order to run the service, a minimum CPU
architecture of x86-64-v2
is required. This can be determined by running the
following command. If supported, it will be listed as “(supported)” in the
output.
/usr/lib64/ld-linux-x86-64.so.2 --help | grep x86-64-v2
External Internet access is necessary during the installation process for the installer to download and install additional dependencies. This ensures a seamless setup and optimal functionality of the Director on Red Hat Enterprise Linux 8 or 9. It’s worth noting that, due to the unique workings of the DNF package manager in Red Hat Enterprise Linux with rolling package streams, an air-gapped installation process is not available.
Firewall Recommendations
See Firewall.
Installation
See Installation.
Operations
See Operations.
Configuration Process
Once the router is operational, it requires a valid configuration before it can route incoming requests.
There are currently three methods available for configuring the router, each catering to different levels of complexity. The first is a Web UI, suitable for the most common use-cases, providing an intuitive interface for configuration. The second involves utilizing a confd REST service, complemented by an optional command line tool, confcli, suitable for all but the most advanced scenarios. The third method involves leveraging an internal REST API, ideal for the most intricate cases where using confd proves to be less flexible. It’s essential to note that as the configuration method advances through these levels, both flexibility and complexity increase, providing users with tailored options based on their specific needs and expertise.
API Key Management
Regardless of the method used to configure the system, a unique API key is
crucial for safeguarding the router’s configuration and preventing unauthorized
access to the API. This key must be supplied when interacting with the API.
During the router software installation, an automatically generated API key is
created and can be located on the installed system at
/opt/edgeware/acd/router/cache/rest-api-key.json
. The structure of this file
is as follows:
{"api_key": "abc123"}
When accessing the internal configuration API, the key must be included in the
X-API-key
header of the request, as shown below:
curl -v -k -H "X-API-Key: abc123" https://<router-host.example>:5001/v2/configuration
Modification to the authentication key and behavior can be done through the
/v2/rest_api_key
endpoint. To change the key, a PUT
request with a JSON body
of the same structure can be sent to the endpoint:
curl -v -k -X PUT -T new-key.json -H "X-API-Key: abc123" \
-H "Content-Type: application/json" https://<router-host.example>:5001/v2/rest_api_key
Additionally, key authentication can be disabled completely by sending a DELETE
request to the endpoint:
curl -v -k -X DELETE -H "X-API-Key: abc123" \
https://<router-host.example>:5001/v2/rest_api_key
In the event of a lost or forgotten authentication key, it can always be
retrieved at /opt/edgeware/acd/router/cache/rest-api-key.json
on the
machine running the router. It is critical to emphasize that the API key should
remain private to prevent unauthorized access to the internal API, as it grants
full access to the router’s configuration.
Configuration Basics
Upon completing the installation process and configuring the API keys, the subsequent section will provide guidance on configuring the router to route all incoming requests to a single host. For straightforward CDN Offload use cases, there is a web based user interface described here.
For further details on configuring the router using confd and confcli, please consult the Confd documentation.
The initial step involves defining the target host group. In this illustration,
a singular group named all
will be established, comprising two hosts.
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: host
Adding a 'host' element
hostGroup : {
name (default: ): all
type (default: host):
httpPort (default: 80):
httpsPort (default: 443):
hosts : [
host : {
name (default: ): host1.example.com
hostname (default: ): host1.example.com
ipv6_address (default: ):
}
Add another 'host' element to array 'hosts'? [y/N]: y
host : {
name (default: ): host2.example.com
hostname (default: ): host2.example.com
ipv6_address (default: ):
}
Add another 'host' element to array 'hosts'? [y/N]: n
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: n
]
Generated config:
{
"hostGroups": [
{
"name": "all",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "host1.example.com",
"hostname": "host1.example.com",
"ipv6_address": ""
},
{
"name": "host2.example.com",
"hostname": "host2.example.com",
"ipv6_address": ""
}
]
}
]
}
Merge and apply the config? [y/n]:
After defining the host group, the next step is to establish a rule that directs
incoming requests to the designated host. In this example, a sole rule named
random
will be generated, ensuring that all incoming requests are consistently
routed to the previously defined host.
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: random
Adding a 'random' element
rule : {
name (default: ): random
type (default: random):
targets : [
target (default: ): host1.example.com
Add another 'target' element to array 'targets'? [y/N]: y
target (default: ): host2.example.com
Add another 'target' element to array 'targets'? [y/N]: n
]
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "random",
"type": "random",
"targets": [
"host1.example.com",
"host2.example.com"
]
}
]
}
Merge and apply the config? [y/n]:
The last essential step involves instructing the router on which rule should
serve as the entry point into the routing tree. In this example, we designate
the rule random
as the entrypoint for the routing process.
$ confcli services.routing.entrypoint random
services.routing.entrypoint = 'random'
Once this configuration is defined, all incoming requests will initiate their
traversal through the routing rules, starting with the rule named random
. This
rule is designed to consistently match for every incoming request, effectively load
balancing evenly between host1.example.com
and host2.example.com
on port 80
or 443, depending on whether the initial request was made using HTTP or HTTPS.
Integration with Convoy
The router is equipped with the capability to synchronize specific configuration metadata with a separate Convoy installation through the integrated convoy-bridge service. However, this service necessitates additional setup and configuration, and you can find comprehensive details on the process here..
Additional Resources
Additional documentation resources are included with the Director and can be
accessed at the following directory: /opt/edgeware/acd/documentation/
. This
directory contains supplementary materials to provide users with comprehensive
information and guidance for optimizing their experience with the Director.
Ready for Production
Once the Director software is completely installed and configured, there are a few additional considerations before moving to a full production environment. See the section Ready for Production for additional information.
2.1.1.2 - Installation
2.1.1.2.1 - Installing a 1.14 release
To install ESB3024 Router, one first needs to copy the installation ISO image
to the target node where the router will be run. Due to the way the
installer operates, it is necessary that the host is reachable by
password-less SSH from itself for the user account that will perform the
installation, and that this user has sudo
access.
Prerequisites:
Ensure that the current user has
sudo
access.sudo -l
If the above command fails, you may need to add the user to the
/etc/sudoers
file.Ensure that the installer has password-less SSH access to
localhost
.If using the
root
user, thePermitRootLogin
property of the/etc/ssh/sshd_config
file must be set to ‘yes’.The local host key must also be included in the
.ssh/authorized_keys
file of the user running the installer. That can be done by issuing the following as the intended user:mkdir -m 0700 -p ~/.ssh ssh-keyscan localhost >> ~/.ssh/authorized_keys
Note! The
ssh-keyscan
utility will result in the key fingerprint being output on the console. As a security best-practice it is recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to thisssh-keyscan
approach, establishing an SSH connection to localhost and accepting the host key will have the same result.Disable SELinux.
The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.
To check if SELinux is enabled:
getenforce
This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.
setenforce 0
This disables SELinux, but does not make the change persistent across reboots. To do that, edit the
/etc/selinux/config
file and set theSELINUX
property todisabled
.It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.
Assuming the installation ISO image is in the current working directory,
the following steps need to be executed either by root
user or with sudo
.
Mount the installation ISO image under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-1.14.0.iso /mnt/acd
Run the installer script.
/mnt/acd/installer
Upgrade from and earlier ESB3024 Router release
The following steps can be used to upgrade the router from a 1.10 or 1.12 release to 1.14.0. If upgrading from an earlier release it is recommended to first upgrade to 1.10.1 in multiple steps; for instance when upgrading from release 1.8.0 to 1.14.0, it is recommended to first upgrade to 1.10.1 and then to 1.14.0.
The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new release of the router, and applying the saved configuration.
With the router running, save a backup of the configuration.
The exact procedure to accomplish this depends on the current method of configuration, e.g. if
confd
is used, then the configuration should be extracted fromconfd
, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.Extracting the configuration using
confd
is the recommend approach where available.confcli | tee config_backup.json
To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.
curl --insecure https://localhost:5001/v2/configuration \ | tee config_backup.json
If the API Key is required, it can be found in the file
/opt/edgeware/acd/router/cache/rest-api-key.json
and can be passed to the API by setting the value of theX-API-Key
header.curl --insecure -H "X-API-Key: 1234abcd" \ https://localhost:5001/v2/configuration \ | tee config_backup.json
Mount the new installation ISO under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-1.14.0.iso /mnt/acd
Stop the router and all associated services.
Before upgrading the router it needs to be stopped, which can be done by typing this:
systemctl stop 'acd-*'
Run the installer script.
/mnt/acd/installer
Migrate the configuration.
Note that this step only applies if the router is configured using
confd
. If it is configured using the REST API, this step is not necessary.The confd configuration used in the previous versions is not directly compatible with 1.14, and may need to be converted. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.
The
acd-confd-migration
tool will automatically apply any necessary schema migrations. Further details about this tool can be found at Confd Auto Upgrade Tool.The tool takes as input the old configuration file, either by reading the file directly, or by reading from standard input, applies any necessary migrations between the two specified versions, and outputs a new configuration to standard output which is suitable for being applied to the upgraded system. While the tool has the ability to migrate between multiple versions at a time, the earliest supported version is 1.10.1.
The example below shows how to upgrade from 1.10.2. If upgrading from 1.12.0,
--from 1.10.2
should be replaced with--from 1.12.0
.The command line required to run the tool is different depending on which esb3024 release it is run on. On 1.14.0 it is run like this:
cat config_backup.json | \ podman run -i --rm \ images.edgeware.tv/acd-confd-migration:1.14.0 \ --in - --from 1.10.2 --to 1.14.0 \ | tee config_upgraded.json
After running the above command, apply the new configuration to
confd
by runningcat config_upgraded.json | confcli -i
.
Troubleshooting
If there is a problem running the installer, additional debug information can
be output by adding -v
or -vv
or -vvv
to the installer command, the
more “v” characters, the more detailed output.
2.1.1.2.1.1 - Configuration changes between 1.12.1 and 1.14
Confd configuration changes
Below are the changes to the confd configuration between versions 1.12.1 and 1.14.x listed.
Renamed services.routing.settings.allowedProxies
The configuration setting services.routing.settings.allowedProxies
has been
renamed to services.routing.settings.trustedProxies
.
Added services.routing.tuning.general.restApiMaxBodySize
This parameter configures the maximum body size for the REST API. It mainly applies to the configuration, which sometimes has a large payload size.
2.1.1.2.2 - Installing a 1.12 release
To install ESB3024 Router, one first needs to copy the installation ISO image
to the target node where the router will be run. Due to the way the
installer operates, it is necessary that the host is reachable by
password-less SSH from itself for the user account that will perform the
installation, and that this user has sudo
access.
Prerequisites:
Ensure that the current user has
sudo
access.sudo -l
If the above command fails, you may need to add the user to the
/etc/sudoers
file.Ensure that the installer has password-less SSH access to
localhost
.If using the
root
user, thePermitRootLogin
property of the/etc/ssh/sshd_config
file must be set to ‘yes’.The local host key must also be included in the
.ssh/authorized_keys
file of the user running the installer. That can be done by issuing the following as the intended user:mkdir -m 0700 -p ~/.ssh ssh-keyscan localhost >> ~/.ssh/authorized_keys
Note! The
ssh-keyscan
utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to thisssh-keyscan
approach, establishing an SSH connection to localhost and accepting the host key will have the same result.Disable SELinux.
The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.
To check if SELinux is enabled:
getenforce
This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.
setenforce 0
This disables SELinux, but does not make the change persistent across reboots. To do that, edit the
/etc/selinux/config
file and set theSELINUX
property todisabled
.It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.
Assuming the installation ISO image is in the current working directory,
the following steps need to be executed either by root
user or with sudo
.
Mount the installation ISO image under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.12.1.iso /mnt/acd
Run the installer script.
/mnt/acd/installer
Upgrade from ESB3024 Router release 1.10
The following steps can be used to upgrade the router from a 1.10 release to 1.12.0 or 1.12.1. If upgrading from an earlier release it is recommended to perform the upgrade in multiple steps; for instance when upgrading from release 1.8.0 to 1.12.1, it is recommended to first upgrade to 1.10.1 or 1.10.2 and then to 1.12.1.
The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new release of the router, and applying the saved configuration.
With the router running, save a backup of the configuration.
The exact procedure to accomplish this depends on the current method of configuration, e.g. if
confd
is used, then the configuration should be extracted fromconfd
, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.Extracting the configuration using
confd
is the recommend approach where available.confcli | tee config_backup.json
To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.
curl --insecure https://localhost:5001/v2/configuration \ | tee config_backup.json
If the API Key is required, it can be found in the file
/opt/edgeware/acd/router/cache/rest-api-key.json
and can be passed to the API by setting the value of theX-API-Key
header.curl --insecure -H "X-API-Key: 1234abcd" \ https://localhost:5001/v2/configuration \ | tee config_backup.json
Mount the new installation ISO under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.12.1.iso /mnt/acd
Stop the router and all associated services.
Before upgrading the router it needs to be stopped, which can be done by typing this:
systemctl stop 'acd-*'
Run the installer script.
/mnt/acd/installer
Migrate the configuration.
Note that this step only applies if the router is configured using
confd
. If it is configured using the REST API, this step is not necessary.The confd configuration used in the 1.10 versions is not directly compatible with 1.12, and may need to be converted. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.
To help with migrating the configuration, a new tool has been included in the 1.12.0 release, which will automatically apply any necessary schema migrations. Further details about this tool can be found here. Confd Auto Upgrade.
The
confd-auto-upgrade
tool takes as input the old configuration file, either by reading the file directly, or by reading from standard input, applies any necessary migrations between the two specified versions, and outputs a new configuration to standard output which is suitable for being applied to the upgraded system. While the tool has the ability to migrate between multiple versions at a time, the earliest supported version is 1.10.1.The example below shows how to upgrade from 1.10.2. If upgrading from 1.10.1,
--from 1.10.2
should be replaced with--from 1.10.1
.The command line required to run the tool is different if it is run on esb3024-1.12.0 or esb3024-1.12.1. On 1.12.1 it is run like this:
cat config_backup.json | \ podman run -i --rm \ images.edgeware.tv/auto-upgrade-esb3024-1.12.1-master:20240702T151205Z-f1b53a98f \ --in - --from 1.10.2 --to 1.12.1 \ | tee config_upgraded.json
On esb3024-1.12.0 it is run like this:
cat config_backup.json | \ podman run -i --rm \ images.edgeware.tv/auto-upgrade-esb3024-1.12.0:20240619T154952Z-2b72f7400 \ --in - --from 1.10.2 --to 1.12.0 \ | tee config_upgraded.json
After running the above command, apply the new configuration to
confd
by runningcat config_upgraded.json | confcli -i
.
Troubleshooting
If there is a problem running the installer, additional debug information can
be output by adding -v
or -vv
or -vvv
to the installer command, the
more “v” characters, the more detailed output.
2.1.1.2.2.1 - Configuration changes between 1.10.2 and 1.12
Confd configuration changes
Below are the major changes to the confd configuration between versions 1.10.2 and 1.12.0/1.12.1. Note that there are no configuration changes between versions 1.12.0 and 1.12.1, so the differences apply to both.
Added services.routing.translationFunctions.hostRequest
A new translation function has been added which will allow custom Lua code to modify requests to backend hosts before they are sent.
Added services.routing.translationFunctions.session
A new translation function has been added which will allow custom Lua code to be executed after the router has made the routing decision but before generating the redirect URL.
An example use case would be for enabling instream sessions, which can be done by
setting this value to return set_session_type('instream')
.
Removed services.routing.settins.managedSessions
configuration
This configuration is no longger used.
Added services.routing.tuning.general.maxActiveManagedSessions
tuning parameter.
This parameter configures the maximum number of active managed sessions.
2.1.1.2.3 - Installing release 1.10.x
To install ESB3024 Router, one first needs to copy the installation ISO image
to the target node where the router will be run. Due to the way the
installer operates, it is necessary that the host is reachable by
password-less SSH from itself for the user account that will perform the
installation, and that this user has sudo
access.
Prerequisites:
Ensure that the current user has
sudo
access.sudo -l
If the above command fails, you may need to add the user to the
/etc/sudoers
file.Ensure that the installer has password-less SSH access to
localhost
.If using the
root
user, thePermitRootLogin
property of the/etc/ssh/sshd_config
file must be set to ‘yes’.The local host key must also be included in the
.ssh/authorized_keys
file of the user running the installer. That can be done by issuing the following as the intended user:mkdir -m 0700 -p ~/.ssh ssh-keyscan localhost >> ~/.ssh/authorized_keys
Note! The
ssh-keyscan
utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to thisssh-keyscan
approach, establishing an SSH connection to localhost and accepting the host key will have the same result.Disable SELinux.
The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.
To check if SELinux is enabled:
getenforce
This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.
setenforce 0
This disables SELinux, but does not make the change persistent across reboots. To do that, edit the
/etc/selinux/config
file and set theSELINUX
property todisabled
.It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.
Assuming the installation ISO image is in the current working directory,
the following steps need to be executed either by root
user or with sudo
.
Mount the installation ISO image under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.10.1.iso /mnt/acd
Run the installer script.
/mnt/acd/installer
Upgrade from ESB3024 Router release 1.8.0
The following steps can be used to upgrade the router from release 1.8.0 to 1.10.x. If upgrading from an earlier release it is recommended to perform the upgrade in multiple steps; for instance when upgrading from release 1.6.0 to 1.10.x, it is recommended to first upgrade to 1.8.0 and then to 1.10.x.
The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new release of the router, and applying the saved configuration.
With the router running, save a backup of the configuration.
The exact procedure to accomplish this depends on the current method of configuration, e.g. if
confd
is used, then the configuration should be extracted fromconfd
, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.Extracting the configuration using
confd
is the recommend approach where available.confcli | tee config_backup.json
To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.
curl --insecure https://localhost:5001/v2/configuration \ | tee config_backup.json
If the API Key is required, it can be found in the file
/opt/edgeware/acd/router/cache/rest-api-key.json
and can be passed to the API by setting the value of theX-API-Key
header.curl --insecure -H "X-API-Key: 1234abcd" \ https://localhost:5001/v2/configuration \ | tee config_backup.json
Mount the new installation ISO under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.10.1.iso /mnt/acd
Stop the router and all associated services.
Before upgrading the router it needs to be stopped, which can be done by typing this:
systemctl stop 'acd-*'
Run the installer script.
/mnt/acd/installer
Migrate the configuration.
Note that this step only applies if the router is configured using
confd
. If it is configured using the REST API, this step is not necessary.The confd configuration used in version 1.8.0 is not directly compatible with 1.10.x, and may need to be converted. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.
To determine if the configuration needs to be converted,
confcli
can be run like below. If it prints error messages, the configuration needs to be converted. If no error messages are printed, the configuration is valid and no further updates are necessary.confcli | head -n5 [2024-04-02 14:48:37,155] [ERROR] Missing configuration key /integration [2024-04-02 14:48:37,162] [ERROR] Missing configuration key /services/routing/settings/qoeTracking [2024-04-02 14:48:37,222] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/hosts/convoy-rr-1/healthChecks [2024-04-02 14:48:37,222] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/hosts/convoy-rr-2/healthChecks [2024-04-02 14:48:37,242] [ERROR] Missing configuration key /services/routing/hostGroups/e-dns/hosts/linton-dns-1/healthChecks { "integration": { "convoy": { "bridge": { "accounts": {
If error messages are printed, the configuration needs to be converted. If the configuration was saved in the file
config_backup.json
, the conversion can be done by typing this at the command line:sed -E -e '/"hosts":/,/]/ s/([[:space:]]+)("hostname":.*)/\1\2\n\1"healthChecks": [],/' -e '/"apiKey":/ d' config_backup.json | \ curl -s -X PUT -T - -H 'Content-Type: application/json' http://localhost:5000/config/__active/
systemctl restart acd-confd
This adds empty
healthChecks
sections to all hosts and removes theapiKey
configuration. After that,acd-confd
is restarted. See Configuration changes between 1.8.0 and 1.10.x for more details about the configuration changes.Migrating configuration to esb3024-1.10.2
When upgrading to version 1.10.2, an extra step is required to migrate the consistent hashing configuration. This step is necessary both when upgrading from an earlier 1.10 release and when upgrading from older versions. It is only needed if consistent hashing was configured in the previous version.
To determine if consistent hashing was configured, execute the following command:
confcli | head -n2 [2024-05-31 09:43:55,932] [ERROR] Missing configuration key /services/routing/rules/constantine/hashAlgorithm { "integration": {
If an error message about a missing configuration key appears, the configuration must be migrated. If no such error message appears, this step should be skipped.
To migrate the configuration, execute the following command at the command line:
curl -s http://localhost:5000/config/__active/ | \ sed -E 's/(.*)("type":.*"consistentHashing")(,?)/\1\2,\n\1"hashAlgorithm": "MD5"\3/' | \ curl -s -X PUT -T - -H 'Content-Type: application/json' http://localhost:5000/config/__active/
This command will read the current configuration, add the
hashAlgorithm
configuration key, and write back the updated configuration.Remove the Account Monitor container
Older versions of the router installed the Account Monitor tool. This was removed in release 1.8.0, but if it is still present and unused, it can be removed by typing:
podman rm account-monitor
Remove the
confd-transformer.lua
fileAfter installing or upgrading to 1.10.x, ensure that the
confd-transformer.lua
script located in/opt/edgeware/acd/router/lib/standard_lua
directory is removed.This file contains deprecated Lua language definitions which will override newer versions of those functions already present in the ACD Router’s Lua Standard Library. When upgrading beyond 1.10.2, the installer will automatically remove this file, however for this particular release, it requires manual intervention.
rm -f /opt/edgeware/acd/router/lib/standard_lua/confd-transformer.lua
After removing this file, it will be necessary to restart the router to flush the definitions from the router’s memory:
systemctl restart acd-router
Troubleshooting
If there is a problem running the installer, additional debug information can
be output by adding -v
or -vv
or -vvv
to the installer command, the
more “v” characters, the more detailed output.
2.1.1.2.3.1 - Configuration changes between 1.8.0 and 1.10.x
Confd configuration changes
Below are the major changes to the confd configuration between version 1.8.0 and 1.10.x listed.
Added integration.convoy
section
An integration.convoy
section has been added to the configuration. It is
currently used for configuring the Convoy Bridge
service.
Removed services.routing.apiKey
configuration
The services.routing.apiKey
configuration key has been removed. This was an
obsolete way of giving the configuration access to the router. The key has to be
removed from the configuration when upgrading, otherwise the configuration will
not be accepted.
Added services.routing.settings.qoeTracking
A services.routing.settings.qoeTracking
section has been added to the
configuration.
Added healthChecks
sections to the hosts
The hosts in the hostGroup
entries have been extended with a healthChecks
key, which is a list of functions that determine if a host is in good health.
For example, a redirecting host might look like this after the configuration has been updated:
{
"services": {
"routing": {
"hostGroups": [
{
"name": "convoy-rr",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"forwardHostHeader": true,
"hosts": [
{
"name": "convoy-rr-1",
"hostname": "convoy-rr-1",
"ipv6_address": "",
"healthChecks": [
"health_check('convoy-rr-1')"
]
}
]
}
],
Added hashAlgorithm
to the consistentHashing
rule
In esb3024-1.10.2 the consistentHashing
routing rule has been extended with a
hashAlgorithm
key, which can have the values MD5
, SDBM
and Murmur
. The
default value is MD5
.
2.1.1.2.4 - Installing release 1.8.0
To install ESB3024 Router, one first needs to copy the installation ISO image
to the target node where the router will be run. Due to the way the
installer operates, it is necessary that the host is reachable by
password-less SSH from itself for the user account that will perform the
installation, and that this user has sudo
access.
Prerequisites:
Ensure that the current user has
sudo
access.sudo -l
If the above command fails, you may need to add the user to the
/etc/sudoers
file.Ensure that the installer has password-less SSH access to
localhost
.If using the
root
user, thePermitRootLogin
property of the/etc/ssh/sshd_config
file must be set to ‘yes’.The local host key must also be included in the
.ssh/authorized_keys
file of the user running the installer. That can be done by issuing the following as the intended user:mkdir -m 0700 -p ~/.ssh ssh-keyscan localhost >> ~/.ssh/authorized_keys
Note! The
ssh-keyscan
utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to thisssh-keyscan
approach, establishing an SSH connection to localhost and accepting the host key will have the same result.Disable SELinux.
The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.
To check if SELinux is enabled:
getenforce
This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.
setenforce 0
It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.
Assuming the installation ISO image is in the current working directory,
the following steps need to be executed either by root
user or with sudo
.
Mount the installation ISO image under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.8.0.iso /mnt/acd
Run the installer script.
/mnt/acd/installer
Upgrade
The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new version of the router, and applying the saved configuration.
With the router running, save a backup of the configuration.
The exact procedure to accomplish this depends on the current method of configuration, e.g. if
confd
is used, then the configuration should be extracted fromconfd
, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.Extracting the configuration using
confd
is the recommend approach where available.confcli | tee config_backup.json
To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.
curl --insecure https://localhost:5001/v2/configuration \ | tee config_backup.json
If the API Key is required, it can be found in the file
/opt/edgeware/acd/router/cache/rest-api-key.json
and can be passed to the API by setting the value of theX-API-Key
header.curl --insecure -H "X-API-Key: 1234abcd" \ https://localhost:5001/v2/configuration \ | tee config_backup.json
Mount the new installation ISO under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-1.2.0.iso /mnt/acd
Stop the router and all associated services.
Before upgrading the router it needs to be stopped, which can be done by typing this:
systemctl stop 'acd-*'
Run the installer script.
/mnt/acd/installer
Migrate the configuration.
Note that this step only applies if the router is configured using
confd
. If it is configured using the REST API, this step is not necessary.The confd configuration used in version 1.6.0 is not directly compatible with 1.8.0, and may need to have a few minor manual updates in order to be valid. If this is not done, the configuration will not be valid and it will not be possible to make configuration changes.
To determine if the configuration needs to be manually updated,
confcli
can be run like below. If it prints error messages, the configuration needs to be updated. If no error messages are printed, the configuration is valid and no further updates are necessary.confcli services.routing | head [2024-02-01 19:05:10,769] [ERROR] Missing configuration key /services/routing/hostGroups/convoy-rr/forwardHostHeader [2024-02-01 19:05:10,779] [ERROR] Missing configuration key /services/routing/hostGroups/e-dns/forwardHostHeader [2024-02-01 19:05:10,861] [ERROR] 'forwardHostHeader'
If error messages are printed, a
forwardHostHeader
configuration needs to be added to thehostGroups
configuration. This can be done by running this at the command line:curl -s http://localhost:5000/config/__active/ | \ sed -E 's/([[:space:]]+)"type": "(host|redirecting|dns)"(,?)/\1"type": "\2",\n\1"forwardHostHeader": false\3/' | \ curl -s -X PUT -T - -H 'Content-Type: application/json' http://localhost:5000/config/__active/
This reads the active configuration from the router, adds the “forwardHostHeader” configuration to all host groups, and then sends the updated configuration back to the router.
See Configuration changes between 1.6.0 and 1.8.0 for more details about the configuration changes.
Remove the Account Monitor container
Previous versions of the router installed the Account Monitor tool. This is no longer included, but since the previous version installed, there will be a stopped Account Monitor container. If it is not used, the container can be removed by typing:
podman rm account-monitor
Troubleshooting
If there is a problem running the installer, additional debug information can
be output by adding -v
or -vv
or -vvv
to the installer command, the
more “v” characters, the more detailed output.
2.1.1.2.4.1 - Configuration changes between 1.6.0 and 1.8.0
Confd configuration changes
Below are some of the configuration changes between version 1.4.0 and 1.6.0 listed. The list only contains the changes that might affect already existing configuration, enirely new items are not listed. Normally nothing needs to be done about this since they will be upgraded automatically, but they are listed here for reference.
Added enabled
to contentPopularity
An enabled
key has been added to
services.routing.settings.contentPopularity
. After the key has been added, the
configuration looks like this:
{
"services": {
"routing": {
"settings": {
"contentPopularity": {
"enabled": true,
"algorithm": "score_based",
"sessionGroupNames": []
},
...
Added selectionInputItemLimit
to tuning
A selectionInputItemLimit
key has been added to
services.routing.tuning.general
. After the key has been added, the
configuration looks like this:
{
"services": {
"routing": {
"tuning": {
"general": {
...
"selectionInputItemLimit": 10000,
...
Added forwardHostHeader
to hostGroups
All three hostGroup
types (host
, redirecting
and dns
) have been extended
with a forwardHostHeader
key. For example, a redirecting host might look like
this after the change:
{
"services": {
"routing": {
"hostGroups": [
{
"name": "convoy-rr",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"forwardHostHeader": true,
"hosts": [
{
"name": "convoy-rr-1",
"hostname": "convoy-rr-1",
"ipv6_address": ""
}
]
}
],
...
REST API configuration changes
The following items have been added to the REST API configuration. They will not need to be manually updated, the router will add the new keys with default values. Note that this is not a complete list of all changes, it only contains the changes that will be automatically added when upgrading the router.
If the router is configured via confd
and confcli
, these changes will be
applied by them. This section is only relevant if the router is configured via
the v2/configuration
API.
- Added the
session_translation_function
key. - Added the
tuning.selection_input_item_limit
key.
2.1.1.2.5 - Installing release 1.6.0
To install ESB3024 Router, one first needs to copy the installation ISO image
to the target node where the router will be run. Due to the way the
installer operates, it is necessary that the host is reachable by
password-less SSH from itself for the user account that will perform the
installation, and that this user has sudo
access.
Prerequisites:
Ensure that the current user has
sudo
access.sudo -l
If the above command fails, you may need to add the user to the
/etc/sudoers
file.Ensure that the installer has password-less SSH access to
localhost
.If using the
root
user, thePermitRootLogin
property of the/etc/ssh/sshd_config
file must be set to ‘yes’.The local host key must also be included in the
.ssh/authorized_keys
file of the user running the installer. That can be done by issuing the following as the intended user:mkdir -m 0700 -p ~/.ssh ssh-keyscan localhost >> ~/.ssh/authorized_keys
Note! The
ssh-keyscan
utility will result in the key fingerprint being output on the console. As a security best-practice its recommended to verify that this host-key matches the machine’s true SSH host key. As an alternative, to thisssh-keyscan
approach, establishing an SSH connection to localhost and accepting the host key will have the same result.Disable SELinux.
The Security-Enhanced Linux Project (SELinux) is designed to add an additional layer of security to the operating system by enforcing a set of rules on processes. Unfortunately out of the box the default configuration is not compatible with the way the installer operates. Before proceeding with the installation, it is recommended to disable SELinux. It can be re-enabled after the installation completes, if desired, but will require manual configuration. Refer to the Red Hat Customer Portal for details.
To check if SELinux is enabled:
getenforce
This will result in one of 3 states, “Enforcing”, “Permissive” or “Disabled”. If the state is “Enforcing” use the following to disable SELinux. Either “Permissive” or “Disabled” is required to continue.
setenforce 0
It is recommended to reboot the computer after changing SELinux modes, but the changes should take effect immediately.
Assuming the installation ISO image is in the current working directory,
the following steps need to be executed either by root
user or with sudo
.
Mount the installation ISO image under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-esb3024-1.8.0.iso /mnt/acd
Run the installer script.
/mnt/acd/installer
Upgrade
The upgrade procedure for the router is performed by taking a backup of the configuration, installing the new version of the router, and applying the saved configuration.
With the router running, save a backup of the configuration.
The exact procedure to accomplish this depends on the current method of configuration, e.g. if
confd
is used, then the configuration should be extracted fromconfd
, but if the REST API is used directly, then the configuration must be saved by fetching the current configuration snapshot using the REST API.Extracting the configuration using
confd
is the recommend approach where available.confcli | tee config_backup.json
To extract the configuration from the REST API, the following may be used instead. Depending on the version of the router used, an API-Key may be required to fetch from the REST API.
curl --insecure https://localhost:5001/v2/configuration \ | tee config_backup.json
If the API Key is required, it can be found in the file
/opt/edgeware/acd/router/cache/rest-api-key.json
and can be passed to the API by setting the value of theX-API-Key
header.curl --insecure -H "X-API-Key: 1234abcd" \ https://localhost:5001/v2/configuration \ | tee config_backup.json
Mount the new installation ISO under
/mnt/acd
.Note: The mount-point may be any accessible path, but
/mnt/acd
will be used throughout this document.mkdir -p /mnt/acd mount esb3024-acd-router-1.2.0.iso /mnt/acd
Stop the router and all associated services.
Before upgrading the router it needs to be stopped, which can be done by typing this:
systemctl stop 'acd-*'
Run the installer script.
/mnt/acd/installer
Migrate the configuration.
Note that this step only applies if the router is configured using
confd
. If it is configured using the REST API, this step is not necessary.See Configuration changes between 1.4.0 and 1.6.0 for instructions on how to migrate the configuration to release 1.6.0.
Troubleshooting
If there is a problem running the installer, additional debug information can
be output by adding -v
or -vv
or -vvv
to the installer command, the
more “v” characters, the more detailed output.
2.1.1.2.5.1 - Configuration changes between 1.4.0 and 1.6.0
confd configuration
The confd configuration used in version 1.4.0 is not directly compatible with
1.6.0, and will need to have a few minor updates in order to be valid. If this
is not done, the configuration will not be valid and it will not be possible to
make configuration changes. Running confcli
will cause error messages and an
empty default configuration to be printed.
$ confcli services.routing.
[2023-12-12 16:08:07,120] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-12 16:08:07,122] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-12 16:08:07,122] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-12 16:08:07,123] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-12 16:08:07,123] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds
{
"routing": {
"apiKey": "",
"settings": {
"allowedProxies": [],
"contentPopularity": {
"algorithm": "score_based",
"sessionGroupNames": []
},
"extendedContentIdentifier": {
...
The first thing that needs to be done is to rename the keys sessionGroupIds
to
sessionGroupNames
. If the configuration was backed up to the file
config_backup.json
before upgrading, the keys can be renamed and the
updated configuration can be applied by typing this:
sed 's/"sessionGroupIds"/"sessionGroupNames"/' config_backup.json | confcli -i
[2023-12-19 12:33:17,725] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-19 12:33:17,726] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-19 12:33:17,727] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds
The configuration has not yet been converted, so the error messages are still
printed. The configuration will be converted when the acd-confd
service is
restarted.
systemctl restart acd-confd
This concludes the conversion of the configuration and the router is ready to be used.
Configuration changes
Below are all configuration changes between version 1.4.0 and 1.6.0 listed. Normally nothing needs to be done about this since they will be upgraded automatically, but they are listed here for reference.
Added translationFunctions
block
services.routing.translationFunctions
has been added. It can be added as a
map with two empty strings as values, to make the top of the configuration look
like this:
{
"services": {
"routing": {
"translationFunctions": {
"request": "",
"response": ""
},
...
Renamed sessionGroupIds
to sessionGroupNames
The keys
services.routing.settings.instream.dashManifestRewrite.sessionGroupIds
and
services.routing.settings.instream.hlsManifestRewrite.sessionGroupIds
have
been renamed to
services.routing.settings.instream.dashManifestRewrite.sessionGroupNames
and
services.routing.settings.instream.hlsManifestRewrite.sessionGroupNames
respectively. Any session group IDs need to be manually converted to session
group names.
After the conversion, the head of the configuration file might look like this:
{
"services": {
"routing": {
"apiKey": "",
"settings": {
"allowedProxies": [],
"contentPopularity": {
"algorithm": "score_based",
"sessionGroupNames": []
},
"extendedContentIdentifier": {
"enabled": false,
"includedQueryParams": []
},
"instream": {
"dashManifestRewrite": {
"enabled": false,
"sessionGroupNames": []
},
"hlsManifestRewrite": {
"enabled": false,
"sessionGroupNames": []
},
"reversedFilenameComparison": false
},
...
Added managedSessions
block
A services.routing.settings.managedSessions
block has been added. After
adding the block, the configuration might look like this:
{
"services": {
"routing": {
"apiKey": "",
"settings": {
"allowedProxies": [],
"contentPopularity": {
"algorithm": "score_based",
"sessionGroupNames": []
},
...
"managedSessions": {
"fraction": 0.0,
"maxActive": 100000,
"sessionTypes": []
},
"usageLog": {
"enabled": false,
"logInterval": 3600000
}
},
...
Added recentDurationMilliseconds
A services.routing.tuning.target.recentDurationMilliseconds
key has been added
to the configuration file, with a default value of 500. After adding the key,
the configuration might look like this:
{
"services": {
"routing": {
"apiKey": "",
...
"tuning": {
"target": {
...
"recentDurationMilliseconds": 500,
...
Storing the updated configuration
After all these changes have been done to the configuration file, it can be
applied to the router using confcli
.
confcli
will still display error messages because the stored configuration is
not valid. They will not be displayed anymore after the valid configuration has
been applied.
$ confcli -i < updated_config.json
[2023-12-12 18:52:05,500] [ERROR] Missing configuration key /services/routing/translationFunctions
[2023-12-12 18:52:05,502] [ERROR] Missing configuration key /services/routing/settings/instream/dashManifestRewrite/sessionGroupNames
[2023-12-12 18:52:05,502] [ERROR] Missing configuration key /services/routing/settings/instream/hlsManifestRewrite/sessionGroupNames
[2023-12-12 18:52:05,503] [ERROR] Missing configuration key /services/routing/settings/managedSessions
[2023-12-12 18:52:05,511] [ERROR] Missing configuration key /services/routing/tuning/target/recentDurationMilliseconds
Raw configuration
The following changes have been made to the raw configuration. If the router is
configured via confd
and confcli
, these changes will be applied by them.
This section is only relevant if the router is configured via the
v2/configuration
API.
Simple changes
The following keys were added or removed. They will not need to be manually updated, the router will add the new keys with default values.
- Removed the
tuning.repeated_session_start_threshold_seconds
key. - Removed the
lua_paths
key. - Added the
tuning.target_recent_duration_milliseconds
key.
EDNS proxy changes
If the router has been configured to use an EDNS server, the following has to be changed for the configuration to work.
The hosts.proxy_address
key has been renamed to hosts.proxy_url
and now
accepts a port that is used when connecting to the proxy.
The cdns.http_port
and cdns.https_port
keys now configure the port that is
used for connecting to the EDNS server, before they configured the port that is
used for connecting to the proxy.
2.1.1.3 - Firewall
For security reasons, the ESB3024 Installer does not automatically configure the local firewall to allow incoming traffic. It is the responsibility of the operations person to ensure that the system is protected from external access by placing it behind a suitable firewall solution. The following table describes the set of ports required for operation of the router.
Application | Port | Protocol | Direction | Source | Description |
---|---|---|---|---|---|
Prometheus Alert Manager | 9093 | TCP | IN | internal | Monitoring Services |
Confd | 5000 | TCP | IN | internal | Configuration Services |
Router | 80 | TCP | IN | public | Incoming HTTP Requests |
Router | 443 | TCP | IN | public | Incoming HTTPS Requests |
Router | 5001 | TCP | IN | localhost | Access to router’s REST API |
Router | 8000 | TCP | IN | localhost | Internal monitoring port |
EDNS-Proxy | 8888 | TCP | IN | localhost | Proxy EDNS Requests |
Grafana | 3000 | TCP | IN | internal | Monitoring Services |
Grafana-Loki | 3100 | TCP | IN | internal | Log monitoring daemon |
Prometheus | 9090 | TCP | IN | internal | Monitoring Service |
The “Direction” column represents the direction in which the connection is established.
IN
- The connection is originated from an outside serverOUT
- The connection is established from the host to an external server.
Once a connection is established through the firewall, bidirectional traffic must be allowed using the established connection.
For the “Source” column, the following terms are used.
internal
- Any host or network which is allowed to monitor or operate the system.public
- Any host or subnet that can access the router. This includes any customer network that will be making routing requests.localhost
- Access can be limited to local connections only.any
- All traffic from any source or to any destination.
Additional Ports
Convoy bridge integration
The optional convoy-bridge service needs the ability to access the Convoy MariaDB service, which by default runs on port 3306 on all of the Convoy Management servers. To allow this integration to run, port 3306/tcp must be allowed from the router to the configured Convoy Management node.
2.1.1.4 - API Overview
ESB3024 Router provides two different types of API:s:
- A content request API that is used by video clients to ask for content, normally using port 80 for HTTP and port 443 for HTTPS.
- A few REST API:s used by administrators to configure and monitor the router installation, using port 5001 over HTTPS by default.
The content API won’t be described further in this document, since it’s a simple HTTP interface serving content as regular files or redirect responses.
Raw configuration – /v2/configuration
Used to check and update the raw configuration of ESB3024 Router. Note that this API is considered an implementation detail and is not documented further.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
PUT | application/json | Success | 204 No Content | <N/A> |
PUT | application/json | Failure | 400 Bad Request | application/json 1 |
Validate Configuration – /v2/validate_configuration
Used to determine if a JSON payload is correctly formatted without actually applying its configuration. A successful return status does not guarantee that the applied configuration will work, it only validates the JSON structure.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
PUT | application/json | Success | 204 No Content | <N/A> |
PUT | application/json | Failure | 400 Bad Request | application/json 1 |
Example request
When an expected field is missing from the payload, the validation will show which one and return an appropriate error message in its payload:
$ curl -i -X PUT \
-d '{"routing": {"log_level": 3}}' \
-H "Content-Type: application/json" \
https://router.example:5001/v2/validate_configuration
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Length: 132
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
"Configuration validation: Configuration parsing failed. \
Exception: [json.exception.out_of_range.403] (/routing) key 'id' not found"
Selection Input – /v1/selection_input
Selection input API can be used to inject external key:value data into the
routing engine, making the data available when making routing decisions. An
arbitrary JSON structure can be pushed to the endpoint. When performing GET
or
DELETE
requests, specific selection input values can be accessed or deleted by
including a path to the request. Note that not specifying a path will select all
selection input values.
One use case for selection input is to provide data on cache availability. E.g.
If you send {"edge-streamer-2-online": true}
to the selection input API,
you can create a routing condition eq('edge-streamer-online', true)
to
ensure that no traffic gets routed to the streamer if it’s offline. Note that
sending the same key:value data to the selection input API will overwrite the
previous value.
There is a configurable limit to how many key:value items that can be injected into the router, see the tuning parameter
$ confcli services.routing.tuning.general.selectionInputItemLimit
{
"selectionInputItemLimit": 10000
}
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
PUT | application/json | Success | 204 No Content | <N/A> |
PUT | application/json | Failure | 400 Bad Request | application/json |
GET | <N/A> | Success | 200 OK | application/json |
DELETE | <N/A> | Success | 204 No Content | <N/A> |
DELETE | <N/A> | Failure | 404 Not Found | <N/A> |
Example successful request (PUT
)
$ curl -i -X PUT \
-d '{"host1_bitrate": 13000, "host1_capacity": 50000}' \
-H "Content-Type: application/json" \
https://router.example:5001/v1/selection_input
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
Example unsuccessful request (PUT
)
$ curl -i -X PUT \
-d '{"cdn-status": {"session-count": 12345, "load-percent" 98}}' \
-H "Content-Type: application/json" \
https://router.example:5001/v1/selection_input
HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Content-Length: 169
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"error": "[json.exception.parse_error.101] parse error at line 1, column 57: \
syntax error while parsing object separator - \
unexpected number literal; expected ':'"
}
Example successful request (GET
)
curl -i https://router.example:5001/v1/selection_input
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 129
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"host1_bitrate": 13000,
"host1_capacity": 50000
}
Example successful specific value request (GET
)
curl -i https://router.example:5001/v1/selection_input/path/to/value
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 129
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
1
Example successful request (DELETE
)
curl -i -X DELETE https://router.example:5001/v1/selection_input
HTTP/1.1 204 OK
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d
Example successful specific value request (DELETE
)
curl -i -X DELETE https://router.example:5001/v1/selection_input/value/to/delete
HTTP/1.1 204 OK
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d
Example unsuccessful request (DELETE
)
curl -i -X DELETE https://router.example:5001/v1/selection_input/non/existent/value
HTTP/1.1 404 Not Found
Access-Control-Allow-Origin: *
Content-Length: 129
X-Service-Identity: router.example-5fc78d
Subnets – /v1/subnets
An API for managing named subnets that can be used for routing and block lists. See Subnets for more details.
PUT
requests inject key value pairs with the form {<subnet>: <value>}
, where
<subnet>
is a valid CIDR string, into ACD, e.g.:
$ curl -i -X PUT \
-d '{"255.255.255.255/24": "area1", "1.2.3.4/24": "area2"}' \
-H "Content-Type: application/json" \
https://router.example:5001/v1/subnets
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
GET
requests are used to fetch injected subnets, e.g.:
# Fetch all injected subnets
$ curl -i https://router.example:5001/v1/subnets
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 411
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"1.2.3.4/16": "area2",
"1.2.3.4/24": "area1",
"1.2.3.4/8": "area3",
"255.255.255.255/16": "area2",
"255.255.255.255/24": "area1",
"255.255.255.255/8": "area3",
"2a02:2e02:9bc0::/16": "area8",
"2a02:2e02:9bc0::/32": "area7",
"2a02:2e02:9bc0::/48": "area6",
"2a02:2e02:9de0::/44": "combined_area",
"2a02:2e02:ada0::/44": "combined_area",
"5.5.0.4/8": "area5",
"90.90.1.3/16": "area4"
}
DELETE
requests are used to delete injected subnets, e.g.:
# Delete all injected subnets
$ curl -i https://router.example:5001/v1/subnets -X DELETE
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
Both GET
and DELETE
requests can be specified with the paths /byKey/
and
/byValue/
to filter which subnets to GET
or DELETE
.
# Fetch subnet with the CIDR string 1.2.3.4/8 if it exists
$ curl -i https://router.example:5001/v1/subnets/byKey/1.2.3.4/8
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 26
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"1.2.3.4/8": "area3"
}
# Fetch all subnets whose CIDR string begins with the IP 1.2.3.4
$ curl -i https://router.example:5001/v1/subnets/byKey/1.2.3.4
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 76
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"1.2.3.4/16": "area2",
"1.2.3.4/24": "area1",
"1.2.3.4/8": "area3"
}
# Fetch all subnets whose value equals 'area1'
$ curl -i https://router.example:5001/v1/subnets/byValue/area1
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 60
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"1.2.3.4/24": "area1",
"255.255.255.255/24": "area1"
}
# Delete subnet with the CIDR string 1.2.3.4/8 if it exists
$ curl -i https://router.example:5001/v1/subnets/byKey/1.2.3.4/8
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
# Delete all subnets whose CIDR string begins with the IP 1.2.3.4
$ curl -i https://router.example:5001/v1/subnets/byKey/1.2.3.4
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
# Delete all subnets whose value equals 'area1'
$ curl -i https://router.example:5001/v1/subnets/byValue/area1
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
PUT | application/json | Success | 204 No Content | <N/A> |
PUT | application/json | Failure | 400 Bad Request | application/json |
GET | <N/A> | Success | 200 OK | application/json |
GET | <N/A> | Failure | 400 Bad Request | application/json |
DELETE | <N/A> | Success | 204 No Content | application/json |
DELETE | <N/A> | Failure | 400 Bad Request | application/json |
Subrunner Resource Usage – /v1/usage
Used to monitor the load on subrunners, the processes performing those tasks that are possible to run in parallel.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
Example request
$ curl -i https://router.example:5001/v1/usage
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 1234
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"total_usage": {
"content": {
"lru": 0,
"newest": "-",
"oldest": "-",
"total": 0
},
"sessions": 0,
"subrunner_usage": {
[...]
}
},
"usage_per_subrunner": [
{
"subrunner_usage": {
[...]
}
},
[...]
]
}
Metrics – /m1/v1/metrics
An interface intended to be scraped by Prometheus. It is possible to scrape it manually to see current values, but doing so will reset some counters and cause actual Prometheus data to become faulty.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | text/plain |
Example request
$ curl -i https://router.example:5001/m1/v1/metrics
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 1234
Content-Type: text/plain
X-Service-Identity: router.example-5fc78d
# TYPE num_configuration_changes counter
num_configuration_changes 12
# TYPE num_log_errors_total counter
num_log_errors_total 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category=""} 123
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="cdn"} 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="content"} 0
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="generic"} 10
# TYPE num_log_warnings_total counter
num_log_warnings_total{category="repeated_session"} 0
# TYPE num_ssl_errors_total counter
[...]
Node Visit Counters – /v1/node_visits
Used to gather statistics about the number of visits to each node in the routing tree. The returned value is a JSON object containing node ID names and their corresponding counter values.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
See Routing Rule Evaluation Metrics for more details.
Example request
$ curl -i https://router.example:5001/v1/node_visits
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 73
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"cache1.tv": "99900",
"offload": "100"
"routingtable": "100000"
}
Node Visit Graph – /v1/node_visits_graph
Creates a GraphML representation of the node visitation data that can be rendered into an image to make it easier to understand the data.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/xml |
See Routing Rule Evaluation Metrics for more details.
Example request
> curl -i -k https://router.example:5001/v1/node_visits_graph
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 731
Content-Type: application/xml
X-Service-Identity: router.example-5fc78d
<?xml version="1.0"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key id="visits" for="node" attr.name="visits" attr.type="string" />
<graph id="G" edgedefault="directed">
<node id="routingtable">
<data key="visits">100000</data>
</node>
<node id="cache1.tv">
<data key="visits">99900</data>
</node>
<node id="offload">
<data key="visits">100</data>
</node>
<edge id="e0" source="routingtable" target="cache1.tv" />
<edge id="e1" source="routingtable" target="offload" />
</graph>
</graphml>
Session list - /v1/sessions
Used to monitor the load on subrunners, the processes performing those tasks that are possible to run in parallel.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
Example request
$ curl -k -i https://router.example:5001/v1/sessions
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 12345
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"sessions": [
{
"age_seconds": 103,
"cdn": "edgeware",
"cdn_is_redirecting": false,
"client_ip": "1.2.3.4",
"host": "cdn.example:80",
"id": "router.example-5fc78d-00000001",
"idle_seconds": 103,
"last_request_time": "2022-12-02T14:05:05Z",
"latest_request_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
"no_of_requests": 1,
"requested_bytes": 0,
"requests_redirected": 0,
"requests_served": 0,
"session_groups": [
"all"
],
"session_groups_generation": 2,
"session_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
"start_time": "2022-12-02T14:05:05Z",
"type": "instream",
"user_agent": "libmpv"
},
[...]
]
}
Session details - /v1/sessions/<id: str>
Used to get details about a specific session from the above session list. The
id
part of the URL corresponds to the id
field in one of the
returned session entries in the above response.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
GET | <N/A> | Failure | 404 Not Found | application/json |
Example request
$ curl -k -i https://router.example:5001/v1/sessions/router.example-5fc78d-00000001
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 763
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"age_seconds": 183,
"cdn": "edgeware",
"cdn_is_redirecting": false,
"client_ip": "1.2.3.4",
"host": "cdn.example:80",
"id": "router.example-5fc78d-00000001",
"idle_seconds": 183,
"last_request_time": "2022-12-02T14:05:05Z",
"latest_request_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
"no_of_requests": 1,
"requested_bytes": 0,
"requests_redirected": 0,
"requests_served": 0,
"session_groups": [
"all"
],
"session_groups_generation": 2,
"session_path": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
"start_time": "2022-12-02T14:05:05Z",
"type": "instream",
"user_agent": "libmpv"
}
Content List - /v1/content
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
Example request
$ curl -k -i https://router.example:5001/v1/content
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 572
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"content": [
[
"/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
{
"cached_count": 0,
"content_requested": false,
"content_set": false,
"expiration_time": "2022-12-02T14:05:05Z",
"key": "/__cl/s:storage1/__c/v/f/0/5/v_sintel3v_f05a05f07d352e891d79863131ef4df7/__op/hls-default/__f/index.m3u8",
"listeners": 0,
"manifest": "",
"request_count": 4,
"state": "HLS:MANIFEST-PENDING",
"wait_count": 0
}
]
]
}
Lua scripts – /v1/lua/<path str>.lua
Used to upload, retrieve and delete custom named Lua scripts on the router.
Global functions in uploaded scripts automatically become available to Lua code
in the configuration (which effectively may be viewed as hooks). Upload a
script by PUTing
a application/x-lua
to the endpoint, and retrieve it by
GETing
the endpoint without payload.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
PUT | application/x-lua | Success | 204 No Content | <N/A> |
PUT | application/x-lua | Failure | 400 Bad Request | application/json |
GET | <N/A> | Success | 200 OK | application/x-lua |
GET | <N/A> | Failure | 404 Not Found | application/json |
DELETE | <N/A> | Success | 204 No Content | <N/A> |
DELETE | <N/A> | Failure | 400 Bad Request | application/json |
DELETE | <N/A> | Failure | 404 Not Found | application/json |
Example request (PUT
)
Save a Lua script under the name advanced_functions/f1.lua
:
$ curl -i -X PUT \
-d 'function fun1() return 1 end' \
-H "Content-Type: application/x-lua" \
https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully saved Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
Example request (PUT
, from file)
Upload an entire Lua file under the name advanced_functions/f1.lua
:
First put your code in a file.
$ cat f1.lua
function fun1()
return 1
end
Then upload it using the --data-binary
flag to preserve newlines
$ curl -i -X PUT \
--data-binary @f1.lua \
-H "Content-Type: application/x-lua" \
https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully saved Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
Example request (GET
)
Request the Lua script named advanced_functions/f1.lua
using a GET
request:
$ curl -i https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 28
Content-Type: application/x-lua
X-Service-Identity: router.example-5fc78d
function fun1() return 1 end
Example request (DELETE
)
Delete the Lua script named advanced_functions/f1.lua
using a DELETE
request:
$ curl -i -X DELETE \
https://router.example:5001/v1/lua/advanced_functions/f1.lua
HTTP/1.1 204 Successfully removed Lua file
Access-Control-Allow-Origin: *
Content-Length: 0
X-Service-Identity: router.example-5fc78d
List Lua scripts – /v1/lua
Used to list previously uploaded custom Lua scripts on the router, retrieving their respective paths and file checksums.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
GET | <N/A> | Success | 200 OK | application/json |
Example request
$ curl -k -i https://router.example:5001/v1/lua
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 108
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
[
{
"file_checksum": "d41d8cd98f00b204e9800998ecf8427e",
"path": "advanced_functions/f1.lua"
}
]
Debug a Lua expression – /v1/lua/debug
Used to debug an arbitrary Lua expression on the router in a “sandbox” (with no visible side effects to the state of the router), and inspect the result.
The Lua expression in the body is evaluated inside an isolated copy of the
internal Lua environment including selection input. The stdout
field of the
resulting JSON body is populated with a concatenation of every string provided
as argument to the Lua print()
function during the course of evaluation.
Upon a successful evaluation, as indicated by the success
flag,
return.value
and return.lua_type_name
capture the resulting Lua value.
Otherwise, if valuation was aborted (e.g. due to a Lua exception), error_msg
reflects any error description arising from the Lua environment.
REQUEST Method | Content-Type | RESPONSE Result | Status Code | Content-Type |
---|---|---|---|---|
POST | application/x-lua | Success | 200 OK | application/json |
Example successful request
$ curl -i -X POST \
-d 'fun1()' \
-H "Content-Type: application/x-lua" \
https://router.example:5001/v1/lua/debug
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 123
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"error_msg": "",
"return": {
"lua_type_name": "number",
"value": 1.0
},
"stdout": "",
"success": true
}
Example unsuccessful request
(attempt to invoke unknown function)
$ curl -i -X POST \
-d 'fun5()' \
-H "Content-Type: application/x-lua" \
https://router.example:5001/v1/lua/debug
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Length: 123
Content-Type: application/json
X-Service-Identity: router.example-5fc78d
{
"error_msg": "[string \"function f0() ...\"]:2: attempt to call global 'fun5' (a nil value)",
"return": {
"lua_type_name": "",
"value": null
},
"stdout": "",
"success": false
}
Access logging
When the configuration parameter tuning.access_log
is set to true
, HTTP
requests are logged in the common log format
(see https://en.wikipedia.org/wiki/Common_Log_Format) and tagged with the
matchable field "ACCESSLOG=1"
to be retrieved with journalctl
:
journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1
Example output
-- Logs begin at Tue 2023-05-23 07:57:16 UTC, end at Mon 2023-05-29 07:25:59 UTC. --
May 29 07:20:00 router[52236]: ::1 - - [29/May/2023:07:20:00 +0000] "GET /vod/batman.m3u8 HTTP/1.1" 302 0 "-" "curl/7.61.1"
Some useful optional arguments to journalctl
are:
journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1 [--follow] [-o json-pretty] [--since 2022-06-06] [--until 2022-06-10]
[--grep="HTTP/1.1\" 404"]
See the journalctl
documentation for further reading.
Footnotes
2.1.1.5 - Configuration
2.1.1.5.1 - WebUI Configuration
The web based user interface is installed as a separate component and can be used to configure many common use cases. After navigating to the UI, a login screen will be presented.
Enter your credentials and log in. In the top left corner is a menu to select what section of the configuration to change. The configuration that will be active on the router is added in the Routing Workflow view. However, basic elements such as classification rules and routing targets, etc must be added first. Hence the following main steps are required to produce a proper configuration:
- Create classifiers serving as basic elements to create session groups.
- Create session groups which, using the classifiers, tag requests/clients for later use in the routing logic. of the incoming traffic.
- Define offload rules.
- Define rules to control behavior of internal traffic.
- Define backup rules to be used if the routing targets in the above step are unavailable.
- Finally, create the desired routing workflow using the elements defined in the previous steps.
A simplified concrete example of the above steps could be:
- Create two classifiers “smartphone” and “off-net”.
- Create a session group “mobile off-net”.
- Offload off-net traffic from mobile phones to a public CDN.
- Route other traffic to a private CDN.
- If the private CDN has an outage, use the public CDN for all traffic.
Hence, to start with, define the classifiers you will need. Those are based on information in the incoming request, optionally in combination with GeoIP databases or subnet information configured via the Subnet API. Here we show how to set up a GeoIP classifier. Note that the Director ships with a compatible snapshot of the GeoIP database, but for a production system a licensed and updated database is required.
Click the plus sign indicated in the picture above to create a new GeoIP classifier. You will be presented with the following view:
Here you can enter the geographical data on which to match, or check the “Inverted” check box to match anything except the entered geographical data.
The other kinds of classifiers are configured in a similar way.
After having added all the classifiers you need, it is time to create the session groups. Those are named filters that group incoming requests, typically video playback sessions in a video streaming CDN, and are defined with the help of the classifiers. For example, a session group “off-net mobile devices” could be composed of the classifiers “off-net traffic” and “mobile devices”.
Open the Session Groups view from the menu and hit the plus sign to add a new session group.
Define the new sessions groups by combining the previously created classifiers. It is often convenient to define an “All” session group that matches any incoming request.
Next go the “CDN Offload” view:
Here you define conditions for CDN offload. Each row defines a rule for offloading a specified session group. The rule makes use of the Selection Input API. This is an integration API that provides a way to supply additional data for use in the routing decision. Common examples are current bitrates or availability status. The selection input variables to use must be defined in the “Selection Input Types” view in the “Administration” section of the menu:
Reach out to the solution engineers from Agile Content in order to perform this integration in the best way. If no external data is required, such that the offload rule can be based solely based on session groups, this is not necessary and the condition field can be set to “Always” or “Disabled”.
When clicking the plus sign to add a new CDN Offload rule, the following view is presented:
The selection input rule is phrased in terms of a variable being above or below a threshold, but also a state such as “available” taking values 0 or 1 can be supported by for instance checking if “available” is below 1.
Moving on, if an incoming request is not offloaded, it will be handled by the Primary CDN section of the routing configuration.
Add all hosts in your primary CDN, together with a weight. A row in this table will be selected by random weighted load balancing. If each weight is the same, each row will be selected with the same probability. Another example would be three rows with weights 100, 100 and 200 which would randomly balance 50% of the load on the last row and the remaining load on the first two rows, i.e. 25% on each of the first and second row. If a Primary CDN host is unavailable, that host will not take part in the random selection.
If all hosts are unavailable, as a final resort the routing evaluation will go to the final Backup CDN step:
Here you can define what to do when all else fail. If not all requests are covered, for example with an “All” session group, then the request will fail with 403 Forbidden.
Now you have defined the basic elements and it is time to define the routing workflow. Select “Routing Workflow” from the menu, as pictured below. Here you can combine the elements previously created to achieve the desired routing behavior.
When everything seems correct, open the “Publish Routing” view from the menu:
Hit “Publish All Changes” and verify that you get a successful result.
2.1.1.5.2 - Confd and Confcli
confcli
to set up routing rulesConfiguration of a complex routing tree can be difficult. The command line
interface tool called confcli
has been developed to make it simpler. It
combines building blocks, representing simple routing decisions, into complex
routing trees capable of satisfying almost any routing requirements.
These blocks are translated into an ESB3024 Router configuration which is automatically sent to the router, overwriting existing routing rules, CDN list and host list.
Installation and Usage
The confcli
tools are installed alongside ESB3024 Router, on the same host,
and the confcli
command line tool itself is made available on the host machine.
Simply type confcli
in a shell on the host to see the current routing
configuration:
$ confcli
{
"services": {
"routing": {
"settings": {
"trustedProxies": [],
"contentPopularity": {
"algorithm": "score_based",
"sessionGroupNames": []
},
"extendedContentIdentifier": {
"enabled": false,
"includedQueryParams": []
},
"instream": {
"dashManifestRewrite": {
"enabled": false,
"sessionGroupNames": []
},
"hlsManifestRewrite": {
"enabled": false,
"sessionGroupNames": []
},
"reversedFilenameComparison": false
},
"usageLog": {
"enabled": false,
"logInterval": 3600000
}
},
"tuning": {
"content": {
"cacheSizeFullManifests": 1000,
"cacheSizeLightManifests": 10000,
"lightCacheTimeMilliseconds": 86400000,
"liveCacheTimeMilliseconds": 100,
"vodCacheTimeMilliseconds": 10000
},
"general": {
"accessLog": false,
"coutFlushRateMilliseconds": 1000,
"cpuLoadWindowSize": 10,
"eagerCdnSwitching": false,
"httpPipeliningEnable": false,
"logLevel": 3,
"maxConnectionsPerHost": 5,
"overloadThreshold": 32,
"readyThreshold": 8,
"redirectingCdnManifestDownloadRetries": 2,
"repeatedSessionStartThresholdSeconds": 30,
"selectionInputMetricsTimeoutSeconds": 30
},
"session": {
"idleDeactivateTimeoutMilliseconds": 20000,
"idleDeleteTimeoutMilliseconds": 1800000
},
"target": {
"responseTimeoutSeconds": 5,
"retryConnectTimeoutSeconds": 2,
"retryResponseTimeoutSeconds": 2,
"connectTimeoutSeconds": 5,
"maxIdleTimeSeconds": 30,
"requestAttempts": 3
}
},
"sessionGroups": [],
"classifiers": [],
"hostGroups": [],
"rules": [],
"entrypoint": "",
"applyConfig": true
}
}
}
The CLI tool can be used to modify, add and delete values by providing it with
the “path” to the object to change. The path is constructed by joining the field
names leading up to the value with a period between each name, e.g. the path to
the entrypoint
is services.routing.entrypoint
since entrypoint
is nested
under the routing
object, which in turn is under the services
root object.
Lists use an index number in place of a field name, where 0 indicates the very
first element in the list, 1 the second element and so on.
If the list contains objects which have a field with the name name
, the
index number can be replaced by the unique name of the object of interest.
Tab completion is supported by confcli. Pressing tab once will complete as far as possible, and pressing tab twice will list all available alternatives at the path constructed so far.
Display the values at a specific path:
$ confcli services.routing.hostGroups
{
"hostGroups": [
{
"name": "internal",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "rr1",
"hostname": "rr1.example.com",
"ipv6_address": ""
}
]
},
{
"name": "external",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "offload-streamer1",
"hostname": "streamer1.example.com",
"ipv6_address": ""
},
{
"name": "offload-streamer2",
"hostname": "streamer2.example.com",
"ipv6_address": ""
}
]
}
]
}
Display the values in a specific list index:
$ confcli services.routing.hostGroups.1
{
"1": {
"name": "external",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "offload-streamer1",
"hostname": "streamer1.example.com",
"ipv6_address": ""
},
{
"name": "offload-streamer2",
"hostname": "streamer2.example.com",
"ipv6_address": ""
}
]
}
}
Display the values in a specific list index using the object’s name:
$ confcli services.routing.hostGroups.1.hosts.offload-streamer2
{
"offload-streamer2": {
"name": "offload-streamer2",
"hostname": "streamer2.example.com",
"ipv6_address": ""
}
}
Modify a single value:
confcli services.routing.hostGroups.1.hosts.offload-streamer2.hostname new-streamer.example.com
services.routing.hostGroups.1.hosts.offload-streamer2.hostname = 'new-streamer.example.com'
Delete an entry:
$ confcli services.routing.sessionGroups.Apple.classifiers.
{
"classifiers": [
"Apple",
""
]
}
$ confcli services.routing.sessionGroups.Apple.classifiers.1 -d
http://localhost:5000/config/__active/services/routing/sessionGroups/Apple/classifiers/1 reset to default/deleted
$ confcli services.routing.sessionGroups.Apple.classifiers.
{
"classifiers": [
"Apple"
]
}
Adding new values in objects and lists is done using a wizard by invoking
confcli with a path and the -w
argument. This will be shown extensively in
the examples further down in this document rather than here.
If you have a JSON file with a previously generated confcli
configuration
output it can be applied to a system by typing confcli -i <file path>
.
CDNs and Hosts
Configuration using confcli has no real concept of CDNs, instead it has groups of hosts that share some common settings such as HTTP(S) port and whether they return a redirection URL, serve content directly or perform a DNS lookup. Of these three variants, the two former share the same parameters, while the DNS variant is slightly different.
Each host belongs to a host group and may itself be an entire CDN using a single public hostname or a single streamer server, all depending on the needs of the user.
Host Health
When creating a host in the confd configuration, you have the option to define a list of health check functions. Each health check function must return true for a host to be selected. This means that the host will only be considered available if all the defined health check functions evaluate to true. If any of the health check functions return false, the host will be considered unavailable and will not be selected for routing. All health check functions are detailed in the section Built-in Lua functions.
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: redirecting
Adding a 'redirecting' element
hostGroup : {
name (default: ): edgeware
type (default: redirecting): ⏎
httpPort (default: 80): ⏎
httpsPort (default: 443): ⏎
hosts : [
host : {
name (default: ): rr1
hostname (default: ): convoy-rr1.example.com
ipv6_address (default: ): ⏎
healthChecks : [
healthCheck (default: always()): health_check()
Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
]
}
Add another 'host' element to array 'hosts'? [y/N]: y
host : {
name (default: ): rr2
hostname (default: ): convoy-rr2.example.com
ipv6_address (default: ): ⏎
healthChecks : [
healthCheck (default: always()): ⏎
Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
]
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "edgeware",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "rr1",
"hostname": "convoy-rr1.example.com",
"ipv6_address": "",
"healthChecks": [
"health_check()"
]
},
{
"name": "rr2",
"hostname": "convoy-rr2.example.com",
"ipv6_address": "",
"healthChecks": [
"always()"
]
}
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: dns
Adding a 'dns' element
hostGroup : {
name (default: ): external-dns
type (default: dns): ⏎
hosts : [
host : {
name (default: ): dns-host
hostname (default: ): dns.example.com
ipv6_address (default: ): ⏎
healthChecks : [
healthCheck (default: always()): ⏎
Add another 'healthCheck' element to array 'healthChecks'? [y/N]: n
]
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "external-dns",
"type": "dns",
"hosts": [
{
"name": "dns-host",
"hostname": "dns.example.com",
"ipv6_address": "",
"healthChecks": [
"always()"
]
}
]
}
]
}
Merge and apply the config? [y/n]: y
Rule Blocks
The routing configuration using confcli
is done using a combination of logical
building blocks, or rules. Each block evaluates the incoming request in some way
and sends it on to one or more sub-blocks. If the block is of the host
type
described above, the client is sent to that host and the evaluation is done.
Existing blocks
Currently supported blocks are:
allow
: Incoming requests, for which a given rule function matches, are immediately sent to the providedonMatch
target.consistentHashing
: Splits incoming requests randomly between preferred hosts, determined by the proprietary consistent hashing algorithm. The amount of hosts to split between is controlled by thespreadFactor
.contentPopularity
: Splits incoming requests into two sub-blocks depending on how popular the requested content is.deny
: Incoming requests, for which a given rule function matches, are immediately denied, and all non-matching requests are sent to theonMiss
target.firstMatch
: Incoming requests are matched by an ordered series of rules, where the request will be handled by the first rule for which the condition evaluates to true.random
: Splits incoming requests randomly and equally between a list of target sub-blocks. Useful for simple load balancing.split
: Splits incoming requests between two sub-blocks depending on how the request is evaluated by a provided function. Can be used for sending clients to different hosts depending on e.g. geographical location or client hardware type.weighted
: Randomly splits incoming requests between a list of target sub-blocks, weighted according to each target’s associated weight rule. A higher weight means a higher portion of requests will be routed to a sub-block. Rules can be used to decide whether or not to pick a target.rawGroup
: Contains a raw ESB3024 Router configuration routing tree node, to be inserted as is in the generated configuration. This is only meant to be used in the rare cases when it’s impossible to construct the required routing behavior in any other way.rawHost
: A host reference for use as endpoints in rawGroup trees.
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: allow
Adding a 'allow' element
rule : {
name (default: ): allow
type (default: allow): ⏎
condition (default: ): customFunction()
onMatch (default: ): rr1
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "content",
"type": "contentPopularity",
"condition": "customFunction()",
"onMatch": "rr1"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: consistentHashing
Adding a 'consistentHashing' element
rule : {
name (default: ): consistentHashingRule
type (default: consistentHashing):
spreadFactor (default: 1): 2
hashAlgorithm (default: MD5):
targets : [
target : {
target (default: ): rr1
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): rr2
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): rr3
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: n
]
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "consistentHashingRule",
"type": "consistentHashing",
"spreadFactor": 2,
"hashAlgorithm": "MD5",
"targets": [
{
"target": "rr1",
"enabled": true
},
{
"target": "rr2",
"enabled": true
},
{
"target": "rr3",
"enabled": true
}
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: contentPopularity
Adding a 'contentPopularity' element
rule : {
name (default: ): content
type (default: contentPopularity): ⏎
contentPopularityCutoff (default: 10): 20
onPopular (default: ): rr1
onUnpopular (default: ): rr2
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "content",
"type": "contentPopularity",
"contentPopularityCutoff": 20.0,
"onPopular": "rr1",
"onUnpopular": "rr2"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: deny
Adding a 'deny' element
rule : {
name (default: ): deny
type (default: deny): ⏎
condition (default: ): customFunction()
onMiss (default: ): rr1
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "content",
"type": "contentPopularity",
"condition": "customFunction()",
"onMiss": "rr1"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: firstMatch
Adding a 'firstMatch' element
rule : {
name (default: ): firstMatch
type (default: firstMatch): ⏎
targets : [
target : {
onMatch (default: ): rr1
rule (default: ): customFunction()
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): rr2
rule (default: ): otherCustomFunction()
}
Add another 'target' element to array 'targets'? [y/N]: n
]
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "firstMatch",
"type": "firstMatch",
"targets": [
{
"onMatch": "rr1",
"condition": "customFunction()"
},
{
"onMatch": "rr2",
"condition": "otherCustomFunction()"
}
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: random
Adding a 'random' element
rule : {
name (default: ): random
type (default: random): ⏎
targets : [
target (default: ): rr1
Add another 'target' element to array 'targets'? [y/N]: y
target (default: ): rr2
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "random",
"type": "random",
"targets": [
"rr1",
"rr2"
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): split
type (default: split): ⏎
condition (default: ): custom_function()
onMatch (default: ): rr2
onMiss (default: ): rr1
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "split",
"type": "split",
"condition": "custom_function()",
"onMatch": "rr2",
"onMiss": "rr1"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.rules. -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: weighted
Adding a 'weighted' element
rule : {
name (default: ): weight
type (default: weighted): ⏎
targets : [
target : {
target (default: ): rr1
weight (default: 100): ⏎
condition (default: always()): always()
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): rr2
weight (default: 100): si('rr2-input-weight')
condition (default: always()): gt('rr2-bandwidth', 1000000)
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): rr2
weight (default: 100): custom_func()
condition (default: always()): always()
}
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "weight",
"type": "weighted",
"targets": [
{
"target": "rr1",
"weight": "100",
"condition": "always()"
},
{
"target": "rr2",
"weight": "si('rr2-input-weight')",
"condition": "gt('rr2-bandwith', 1000000)"
},
{
"target": "rr2",
"weight": "custom_func()",
"condition": "always()"
}
]
}
]
}
Merge and apply the config? [y/n]: y
>> First add a raw host block that refers to a regular host
$ confcli services.routing.rules. -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: rawHost
Adding a 'rawHost' element
rule : {
name (default: ): raw-host
type (default: rawHost): ⏎
hostId (default: ): rr1
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "raw-host",
"type": "rawHost",
"hostId": "rr1"
}
]
}
Merge and apply the config? [y/n]: y
>> And then add a rule using the host node
$ confcli services.routing.rules. -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: rawGroup
Adding a 'rawGroup' element
rule : {
name (default: ): raw-node
type (default: rawGroup): ⏎
memberOrder (default: sequential): ⏎
members : [
member : {
target (default: ): raw-host
weightFunction (default: ): return 1
}
Add another 'member' element to array 'members'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "raw-node",
"type": "rawGroup",
"memberOrder": "sequential",
"members": [
{
"target": "raw-host",
"weightFunction": "return 1"
}
]
}
]
}
Merge and apply the config? [y/n]: y
Rule Language
Some blocks, such as the split
and firstMatch
types, have a rule field that
contains a small function in a very simple programming language. This field is
used to filter any incoming client requests in order to determine how to rule
block should react.
In the case of a split
block, the rule is evaluated and if it is true the
client is sent to the onMatch
part of the block, otherwise it is sent to the
onMiss
part for further evaluation.
In the case of a firstMatch
block, the rule for each target will be evaluated
top to bottom in order until either a rule evaluates to true or the list is
exhausted. If a rule evaluates to true, the client will be sent to the onMatch
part of the block, otherwise the next target in the list will be tried. If all
targets have been exhausted, then the entire rule evaluation will fail, and the
routing tree will be restarted with the firstMatch
block effectively removed.
Example of Boolean Functions
Let’s say we have an ESB3024 Router set up with a session group that matches Apple
devices (named “Apple”). To route all Apple devices to a specific streamer one
would simply create a split
block with the following rule:
in_session_group('Apple')
In order to make more complex rules it’s possible to combine several checks like
this in the same rule. Let’s extend the hypothetical ESB3024 Router above with a
configured subnet with all IP addresses in Europe (named “Europe”). To make a
rule that accepts any clients using an Apple device and living outside of
Europe, but only as long as the reported load on the streamer (as indicated by
the selection input variable
“europe_load_mbps”) is less than 1000 megabits per second one could make an
offload
block with the following rule (without linebreaks):
in_session_group('Apple')
and not in_subnet('Europe')
and lt('europe_load_mbps', 1000)
In this example in_session_group('Apple')
will be true if the client belongs
to the session group named ‘Apple’. The function call in_subnet('Europe')
is
true if the client’s IP belongs to the subnet named ‘Europe’, but the word not
in front of it reverses the value so the entire section ends up being false if
the client is in Europe. Finally lt('europe_load_mbps', 1000)
is true if
there is a selection input variable named “europe_load_mbps” and its value is
less than 1000.
Since the three parts are conjoined with the and
keyword they must all
be true for the entire rule to match. If the keyword or
had been used
instead it would have been enough for any of the parts to be true for the
rule to match.
Example of Numeric Functions
A hypothetical CDN has two streamers with different capacity; Host_1
has
roughly twice the capacity of Host_2
. A simple random load balancing would put
undue stress on the second host since it will receive as much traffic as the
more capable Host_1
.
This can be solved by using a weighted
random distribution rule block with
suitable rules for the two hosts:
{
"targets": [
{
"target": "Host_1",
"condition": "always()",
"weight": "100"
}
{
"target": "Host_2",
"condition": "always()",
"weight": "50"
},
]
}
resulting in Host_1
receiving twice as many requests as Host_2
as its
weight function is double that of Host_2
.
If the CDN is capable of reporting the free capacity of the hosts, for example by writing to a selection input variable for each host, it’s easy to write a more intelligent load balancing rule by making the weights correspond to the amount of capacity left on each host:
{
"targets": [
{
"target": "Host_1",
"condition": "always()",
"weight": "si('free_capacity_host_1')"
}
{
"target": "Host_2",
"condition": "always()",
"weight": "si('free_capacity_host_2')"
},
]
}
It is also possible to write custom Lua functions that return suitable weights, perhaps taking the host as an argument:
{
"targets": [
{
"target": "Host_1",
"condition": "always()",
"weight": "intelligent_weight_function('Host_1')"
}
{
"target": "Host_2",
"condition": "always()",
"weight": "intelligent_weight_function('Host_1')"
},
]
}
These different weight rules can of course be combined in the same rule block, with one target having a hard coded number, another using a dynamically updated selection input variable and yet another having a custom-built function.
Due to limitations in the random number generator used to distribute requests, it’s better to use somewhat large values, around 100–1000 or so, than to use small values near 0.
Built-in Functions
The following built-in functions are available when writing rules:
in_session_group(str name)
: True if session belongs to session group<name>
in_all_session_groups(str sg_name, ...)
: True if session belongs to all specified session groupsin_any_session_group(str sg_name, ...)
: True if session belongs to any specified session groupin_subnet(str subnet_name)
: True if client IP belongs to the named subnetgt(str si_var, number value)
: True if selection_inputs[si_var] > valuegt(str si_var1, str si_var2)
: True if selection_inputs[si_var1] > selection_inputs[si_var2]ge(str si_var, number value)
: True if selection_inputs[si_var] >= valuege(str si_var1, str si_var2)
: True if selection_inputs[si_var1] >= selection_inputs[si_var2]lt(str si_var, number value)
: True if selection_inputs[si_var] < valuelt(str si_var1, str si_var2)
: True if selection_inputs[si_var1] < selection_inputs[si_var2]le(str si_var, number value)
: True if selection_inputs[si_var] <= valuele(str si_var1, str si_var2)
: True if selection_inputs[si_var1] <= selection_inputs[si_var2]eq(str si_var, number value)
: True if selection_inputs[si_var] == valueeq(str si_var1, str si_var2)
: True if selection_inputs[si_var1] == selection_inputs[si_var2]neq(str si_var, number value)
: True if selection_inputs[si_var] != valueneq(str si_var1, str si_var2)
: True if selection_inputs[si_var1] != selection_inputs[si_var2]si(str si_var)
: Returns the value of selection_inputs[si_var] if it is defined and non-negative, otherwise it returns 0.always()
: Returns true, useful when creating weighted rule blocks.never()
: Returns false, opposite ofalways()
.
These functions, as well as custom functions written in Lua and uploaded to the ESB3024 Router, can be combined to make suitably precise rules.
Combining Multiple Boolean Functions
In order to make the rule language easy to work with, it is fairly restricted
and simple. One restriction is that it’s only possible to chain multiple
function results together using either and
or or
, but not a
combination of both conjunctions.
Statements joined with and
or or
keywords are evaluated one by one,
starting with the left-most statement and moving right. As soon as the end
result of the entire expression is certain, the evaluation ends. This means that
evaluation ends with the first false
statement for and
expressions since a
single false
component means the entire expression must also be false
. It
also means that evaluation ends with the first true
statement for or
expressions since only one component must be true
for the entire statement to
be true
as well. This is known as short-circuit or lazy evaluation.
Custom Functions
It is possible to write extremely complex Lua functions that take many parameters or calculations into consideration when evaluating an incoming client request. By writing such functions and making sure that they return only non-negative integer values and uploading them to the router they can be used from the rule language. Simply call them like any of the built-in functions listed above, using strings and numbers as arguments if necessary, and their result will be used to determine the routing path to use.
Formal Syntax
The full syntax of the language can be described in just a few lines of BNF grammar:
<rule> := <weight_rule> | <match_rule> | <value_rule>
<weight_rule> := "if" <compound_predicate> "then" <weight> "else" <weight>
<match_rule> := <compound_predicate>
<value_rule> := <weight>
<compound_predicate> := <logical_predicate> |
<logical_predicate> ["and" <logical_predicate> ...] |
<logical_predicate> ["or" <logical_predicate> ...] |
<logical_predicate> := ["not"] <predicate>
<predicate> := <function_name> "(" ")" |
<function_name> "(" <argument> ["," <argument> ...] ")"
<function_name> := <letter> [<function_name_tail> ...]
<function_name_tail> := empty | <letter> | <digit> | "_"
<argument> := <string> | <number>
<weight> := integer | <predicate>
<number> := float | integer
<string> := "'" [<letter> | <digit> | <symbol> ...] "'"
Building a Routing Configuration
This example sets up an entire routing configuration for a system with a ESB3008 Request Router, two streamers and the Apple devices outside of Europe example used earlier in this document. Any clients not matching the criteria will be sent to an offload CDN with two streamers in a simple uniformly randomized load balancing setup.
Set up Session Group
First make a classifier and a session group that uses it:
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: userAgent
Adding a 'userAgent' element
classifier : {
name (default: ): Apple
type (default: userAgent): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *apple*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "Apple",
"type": "userAgent",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*apple*"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): Apple
classifiers : [
classifier (default: ): Apple
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "Apple",
"classifiers": [
"Apple"
]
}
]
}
Merge and apply the config? [y/n]: y
Set up Hosts
Create two host groups and add a Request Router to the first and two streamers to the second, which will be used for offload:
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: redirecting
Adding a 'redirecting' element
hostGroup : {
name (default: ): internal
type (default: redirecting): ⏎
httpPort (default: 80): ⏎
httpsPort (default: 443): ⏎
hosts : [
host : {
name (default: ): rr1
hostname (default: ): rr1.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: y
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: host
Adding a 'host' element
hostGroup : {
name (default: ): external
type (default: host): ⏎
httpPort (default: 80): ⏎
httpsPort (default: 443): ⏎
hosts : [
host : {
name (default: ): offload-streamer1
hostname (default: ): streamer1.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: y
host : {
name (default: ): offload-streamer2
hostname (default: ): streamer2.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "internal",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "rr1",
"hostname": "rr1.example.com",
"ipv6_address": ""
}
]
},
{
"name": "external",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "offload-streamer1",
"hostname": "streamer1.example.com",
"ipv6_address": ""
},
{
"name": "offload-streamer2",
"hostname": "streamer2.example.com",
"ipv6_address": ""
}
]
}
]
}
Merge and apply the config? [y/n]: y
Create Load Balancing and Offload Block
Add both offload streamers as targets in a randomgroup
block:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: random
Adding a 'random' element
rule : {
name (default: ): balancer
type (default: random): ⏎
targets : [
target (default: ): offload-streamer1
Add another 'target' element to array 'targets'? [y/N]: y
target (default: ): offload-streamer2
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "balancer",
"type": "random",
"targets": [
"offload-streamer1",
"offload-streamer2"
]
}
]
}
Merge and apply the config? [y/n]: y
Then create a split block with the request router and the load balanced CDN as targets:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): offload
type (default: split): ⏎
rule (default: ): in_session_group('Apple') and not in_subnet('Europe') and lt('europe_load_mbps', 1000)
onMatch (default: ): rr1
onMiss (default: ): balancer
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "offload",
"type": "split",
"condition": "in_session_group('Apple') and not in_subnet('Europe') and lt('europe_load_mbps', 1000)",
"onMatch": "rr1",
"onMiss": "balancer"
}
]
}
Merge and apply the config? [y/n]: y
The last step required is to set the entrypoint of the routing tree so the router knows where to start evaluating:
$ confcli services.routing.entrypoint offload
services.routing.entrypoint = 'offload'
Evaluate
Now that all the rules have been set up properly and the router has been reconfigured. The translated configuration can be read from the router’s configuration API:
$ curl -k https://router-host:5001/v2/configuration 2> /dev/null | jq .routing
{
"id": "offload",
"member_order": "sequential",
"members": [
{
"host_id": "rr1",
"id": "offload.rr1",
"weight_function": "return ((in_session_group('Apple') ~= 0) and
(in_subnet('Europe') == 0) and
(lt('europe_load_mbps', 1000) ~= 0) and 1) or 0 "
},
{
"id": "offload.balancer",
"member_order": "weighted",
"members": [
{
"host_id": "offload-streamer1",
"id": "offload.balancer.offload-streamer1",
"weight_function": "return 100"
},
{
"host_id": "offload-streamer2",
"id": "offload.balancer.offload-streamer2",
"weight_function": "return 100"
}
],
"weight_function": "return 1"
}
],
"weight_function": "return 100"
}
Note that the configuration language code has been translated into its Lua equivalent.
2.1.1.5.3 - Session Groups and Classification
ESB3024 Router provides a flexible classification engine, allowing the assignment of clients into session groups that can then be used to base routing decisions on.
Session Classification
In order to perform routing it is necessary to classify incoming sessions according to the relevant parameters. This is done through session groups and their associated classifiers.
There are different ways of classifying a request:
Strings with wildcards
: Simple case-insensitive string pattern with support for adding asterisks (’*’) in order to match any value at that point in the pattern.String with regular expressions
: A complex string matching pattern capable of matching more complicated strings than the simple wildcard matching type.
Valid string matching sources are
content_url_path
,content_url_query_params
,hostname
anduser_agent
, examples of which will be shown below.
GeoIP
: Based on the geographic location of the client, supporting wildcard matching. Geographic location data is provided by MaxMind. The possible values to match with are any combinations of:- Continent
- Country
- Cities
- ASN
Anonymous IP
: Classifies clients using an anonymous IP. Database of anonymous IPs is provided by MaxMind.IP range
: Based on whether a client’s IP belongs to any of the listed IP ranges or not.Subnet
: Tests if a client’s IP belongs to a named subnet, see Subnets for more details.ASN ID list
: Checks to see if a client’s IP belongs to any of the specified ASN IDs.Random
: Randomly classifies clients according to a given probability. The classifier is deterministic, meaning that a session will always get the same classification, even if evaluated multiple times.
A session group may have more than one classifier. If it does, all the classifiers must match the incoming client request for it to belong to the session group. It is also possible for a request to belong to multiple session groups, or to none.
To send certain clients to a specific host you first need to create a suitable
classifier using confcli
in wizard mode. The wizard will guide you through the
process of creating a new entry, asking you what value to input for each field
and helping you by telling you what inputs are allowed for restricted fields
such as the string comparison source mentioned above:
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: geoip
Adding a 'geoip' element
classifier : {
name (default: ): sweden_matcher
type (default: geoip): ⏎
inverted (default: False): ⏎
continent (default: ): ⏎
country (default: ): sweden
cities : [
city (default: ): ⏎
Add another 'city' element to array 'cities'? [y/N]: ⏎
]
asn (default: ): ⏎
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "sweden_matcher",
"type": "geoip",
"inverted": false,
"continent": "",
"country": "sweden",
"cities": [
""
],
"asn": ""
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: ipranges
Adding a 'ipranges' element
classifier : {
name (default: ): company_matcher
type (default: ipranges): ⏎
inverted (default: False): ⏎
ipranges : [
iprange (default: ): 90.128.0.0/12
Add another 'iprange' element to array 'ipranges'? [y/N]: ⏎
]
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "company_matcher",
"type": "ipranges",
"inverted": false,
"ipranges": [
"90.128.0.0/12"
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: stringMatcher
Adding a 'stringMatcher' element
classifier : {
name (default: ): apple_matcher
type (default: stringMatcher): ⏎
inverted (default: False): ⏎
source (default: content_url_path): user_agent
pattern (default: ): *apple*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "apple_matcher",
"type": "stringMatcher",
"inverted": false,
"source": "user_agent",
"pattern": "*apple*"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: regexMatcher
Adding a 'regexMatcher' element
classifier : {
name (default: ): content_matcher
type (default: regexMatcher): ⏎
inverted (default: False): ⏎
source (default: content_url_path): ⏎
pattern (default: ): .*/(live|news_channel)/.*m3u8
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "content_matcher",
"type": "regexMatcher",
"inverted": false,
"source": "content_url_path",
"pattern": ".*/(live|news_channel)/.*m3u8"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: subnet
Adding a 'subnet' element
classifier : {
name (default: ): company_matcher
type (default: subnet): ⏎
inverted (default: False): ⏎
pattern (default: ): company
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "company_matcher",
"type": "subnet",
"inverted": false,
"pattern": "company"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: hostName
Adding a 'hostName' element
classifier : {
name (default: ): host_name_classifier
type (default: hostName): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *live.example*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "host_name_classifier",
"type": "hostName",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*live.example*"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlPath
Adding a 'contentUrlPath' element
classifier : {
name (default: ): vod_matcher
type (default: contentUrlPath): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *vod*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "vod_matcher",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*vod*"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlQueryParameters
Adding a 'contentUrlQueryParameters' element
classifier : {
name (default: ): bitrate_matcher
type (default: contentUrlQueryParameters): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): regex
pattern (default: ): .*bitrate=100000.*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "bitrate_matcher",
"type": "contentUrlQueryParameters",
"inverted": false,
"patternType": "regex",
"pattern": ".*bitrate=100000.*"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: userAgent
Adding a 'userAgent' element
classifier : {
name (default: ): iphone_matcher
type (default: userAgent): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): regex
pattern (default: ): i(P|p)hone
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "iphone_matcher",
"type": "userAgent",
"inverted": false,
"patternType": "regex",
"pattern": "i(P|p)hone"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: asnIds
Adding a 'asnIds' element
classifier : {
name (default: ): asn_matcher
type (default: asnIds): ⏎
inverted (default: False): ⏎
asnIds <The list of ASN IDs to accept. (default: [])>: [
asnId: 1
Add another 'asnId' element to array 'asnIds'? [y/N]: y
asnId: 2
Add another 'asnId' element to array 'asnIds'? [y/N]: y
asnId: 3
Add another 'asnId' element to array 'asnIds'? [y/N]: ⏎
]
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "asn_matcher",
"type": "asnIds",
"inverted": false,
"asnIds": [
1,
2,
3
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: random
Adding a 'random' element
classifier <A classifier randomly applying to clients based on the provided probability. (default: OrderedDict())>: {
name (default: ): random_matcher
type (default: random):
probability (default: 0.5): 0.7
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "random_matcher",
"type": "random",
"probability": 0.7
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: anonymousIp
Adding a 'anonymousIp' element
classifier : {
name (default: ): anon_ip_matcher
type (default: anonymousIp):
inverted (default: False):
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "anon_ip_matcher",
"type": "anonymousIp",
"inverted": false
}
]
}
Merge and apply the config? [y/n]: y
These classifiers can now be used to construct session groups and properly classify clients. Using the examples above, let’s create a session group classifying clients from Sweden using an Apple device:
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): inSwedenUsingAppleDevice
classifiers : [
classifier (default: ): sweden_matcher
Add another 'classifier' element to array 'classifiers'? [y/N]: y
classifier (default: ): apple_matcher
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "inSwedenUsingAppleDevice",
"classifiers": [
"sweden_matcher",
"apple_matcher"
]
}
]
}
Merge and apply the config? [y/n]: y
Clients classified by the sweden_matcher
and apple_matcher
classifiers
will now be put in the session group inSwedenUsingAppleDevice
. Using session
groups in routing will be demonstrated later in this document.
Advanced Classification
The above example will simply apply all classifiers in the list, and as long as they all evaluate to true for a session, that session will be tagged with the session group. For situations where this isn’t enough, classifiers can instead be combined using simple logic statements to form complex rules.
A first simple example can be a session group that accepts any viewers in either
ASN 1, 2 or 3 (corresponding to the classifier asn_matcher
or living in Sweden.
This can be done by creating a session group, and adding the following logic
statement:
'sweden_matcher' OR 'asn_matcher'
A slightly more advanced case is where a session group should only contain sessions neither in any of the three ASNs nor in Sweden. This is done by negating the previous example:
NOT ('sweden_matcher' OR 'asn_matcher')
A single classifier can also be negated, rather than the whole statement, for example to accept any Swedish viewers except those in the three ASNs:
'sweden_matcher' AND NOT 'asn_matcher'
Arbitrarily complex statements can be created using classifier names, parentheses,
and the keywords AND
, OR
and NOT
.
For example a session group accepting any Swedish viewers except those in the Stockholm region unless they are also Apple users:
'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')
Note that the classifier names must be enclosed in single quotes when using this syntax.
Applying this kind of complex classifier using confcli is no more difficult than adding a single classifier at a time:
$ confcli services.routing.sessionGroups. -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): complex_group
classifiers : [
classifier (default: ): 'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "complex_group",
"classifiers": [
"'sweden_matcher' AND (NOT 'stockholm_matcher' OR 'apple_matcher')"
]
}
]
}
Merge and apply the config? [y/n]: y
2.1.1.5.4 - Advanced features
2.1.1.5.4.1 - Content popularity
ESB3024 Router allows routing decisions based on content popularity. All incoming content requests are tracked to continuously update a content popularity ranking list. The popularity ranking algorithm is designed to let popular content quickly rise to the top while unpopular content decays and sinks towards the bottom.
Routing
A content popularity based routing rule can be created by running
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: contentPopularity
Adding a 'contentPopularity' element
rule : {
name (default: ): content_popularity_rule
type (default: contentPopularity):
contentPopularityCutoff (default: 10): 5
onPopular (default: ): edge-streamer
onUnpopular (default: ): offload
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "content_popularity_rule",
"type": "contentPopularity",
"contentPopularityCutoff": 5.0,
"onPopular": "edge-streamer",
"onUnpopular": "offload"
}
]
}
Merge and apply the config? [y/n]: y
This rule will route requests for top 5 most popular content to
edge-streamer
and all other requests to offload
.
Some configuration settings attributed to content popularity are available:
$ confcli services.routing.settings.contentPopularity
{
"contentPopularity": {
"enabled": true,
"algorithm": "score_based",
"sessionGroupNames": []
}
}
enabled
: Whether or not to track content popularity. Whenenabled
is set tofalse
, content popularity will not be tracked. Note that routing on content popularity is possible even ifenabled
isfalse
and content popularity has been tracked previously.algorithm
: Choice of content popularity tracking algorithm. There are two possible choices:score_based
ortime_based
(detailed below).sessionGroupNames
: Names of the session groups for which content popularity should be tracked. Note that content popularity is tracked globally, not per session group.
Algorithm tuning
The behaviour of each content popularity tracking algorithm can be tuned using the raw JSON API.
All configuration parameters for content popularity reside in the
settings
object of the configuration, an example of which can be
seen below:
{
"settings": {
"content_popularity": {
"algorithm": "scored_based",
"session_group_names": ["vod_only"],
"score_based:": {
"requests_between_popularity_decay": 1000,
"popularity_list_max_size": 100000,
"popularity_prediction_factor": 2.5,
"popularity_decay_fraction": 0.2
},
"time_based": {
"intervals_per_hour": 10
}
}
}
}
The field algorithm
dictates which content popularity tracking
algorithm to use, can either be score_based
or time_based
.
The field session_group_names
defines the sessions for which content
popularity should be tracked. In the example above, session belonging to
the vod_only
session group will be tracked for content popularity.
If left empty, content popularity will be tracked for all sessions.
The remaining configuration parameters are algorithm specific.
Score based algorithm
The field popularity_list_max_size
defines
the maximum amount of unique contents to track for popularity. This can
be used to limit memory growth. A single entry in the popularity ranking
list will at most consume 180 bytes of memory. E.g. using
"popularity_list_max_size": 1000
would consume at most
180⋅1,000 = 180,000 B = 0.18 MB. If the content popularity list is full,
a request to unique content would replace the least popular content.
Setting a very high max size will not impact performance, it will only consume more memory.
The field requests_between_popularity_decay
defines the number of requests
between each popularity decay update, an integral component of this feature.
The fields popularity_prediction_factor
and popularity_decay_fraction
tune
the behaviour of the content popularity ranking algorithm, explained further
below.
Decay update
To allow for popular content to quickly rise in popularity and unpopular content to sink, a dynamic popularity ranking algorithm is used. The goal of the algorithm is to track content popularity in real time, allowing routing decisions based on the requested content’s popularity. The algorithm is applied every decay update.
The algorithm uses current trending content to predict content popularity. The
field popularity_prediction_factor
regulates how much the algorithm should rely
on predicted popularity. A high prediction factor allows rising content to quickly
rise to high popularity but can also cause unpopular content with a sudden burst
of requests to wrongfully rise to the top. A low prediction factor can cause
stagnation in the popularity ranking, not allowing new popular content to rise
to the top.
Unpopular content decays in popularity, the magnitude of which is regulated by
popularity_decay_fraction
. A high value will aggressively decay content popularity
every decay update while a low value will bloat the ranking, causing stagnation.
Once content decays to a trivially low popularity score, it is pruned from the
content popularity list.
When configuring these tuning parameters, the most crucial data to consider is
the size of your asset catalog, i.e. the number of unique contents you offer.
The recommended values, obtained through testing, are presented in the table below.
Note that the field popularity_prediction_factor
is the principal factor in
controlling the algorithm’s behaviour.
Catalog size n | popularity_prediction_factor | popularity_decay_fraction |
---|---|---|
n < 1000 | 2.2 | 0.2 |
1000 < n < 5000 | 2.3 | 0.2 |
5000 < n < 10000 | 2.5 | 0.2 |
n > 10000 | 2.6 | 0.2 |
Time based algorithm
The time based algorithm only requires the configuration parameter
intervals_per_hour
. E.g., the value "intervals_per_hour": 10
would give 10 six minute intervals per hour. During each interval,
all unique content requests has an associated counter, increasing
by one for each incoming request. After an hour, all intervals have
been cycled through. The counters in the first interval will be reset
and all incoming content requests will increase the counters in the
first interval again. This cycle continues forever.
When determining a single content’s popularity, the sum of each content’s counter in all intervals is used to determine a popularity ranking.
2.1.1.5.4.2 - Consistent Hashing
Consistent hashing based routing is a feature that can be used to distribute requests to a set of hosts in a cache friendly manner. By using Agile Content’s consistent distributed hash algorithm, the amount of cache redistribution is minimized within a set of hosts. Requests for a content will always be routed to the same set of hosts, the amount of which is configured by the spread factor, allowing high cache usage. When adding or removing hosts, the algorithm minimizes cache redistribution.
Say you have the host group [s1, s2, s3, s4, s5]
and have
configured spreadFactor = 3
. A request for a content asset1
would then be
routed to the same three hosts with one of them being selected randomly for each
request. Requests for a different content asset2
would also be routed to one
of three different hosts, most likely a different combination of hosts than
requests for content asset1
.
Example routing results with spreadFactor = 3
:
- Request for
asset1
→ route to one of[s1, s3, s4]
. - Request for
asset2
→ route to one of[s2, s4, s5]
. - Request for
asset3
→ route to one of[s1, s2, s5]
.
Since consistent hashing based routing ensures that requests for a specific content always get routed to the same set of hosts, the risk of cache misses are lowered on the hosts since they will be served the same content requests over and over again.
Note that the maximum value of
spreadFactor
is 64. Consequently, the highest amount of hosts you can use in aconsistentHashing
rule block is 64.
Three different hashing algorithms are available: MD5
, SDBM
and Murmur
.
The algorithm is chosen during configuration.
Configuration
Configuring consistent hashing based routing is easily done using confcli. Let’s configure the example described above:
confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: consistentHashing
Adding a 'consistentHashing' element
rule : {
name (default: ): consistentHashingRule
type (default: consistentHashing):
spreadFactor (default: 1): 3
hashAlgorithm (default: MD5):
targets : [
target : {
target (default: ): s1
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): s2
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): s3
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): s4
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): s5
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: n
]
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "consistentHashingRule",
"type": "consistentHashing",
"spreadFactor": 3,
"hashAlgorithm": "MD5",
"targets": [
{
"target": "s1",
"enabled": true
},
{
"target": "s2",
"enabled": true
},
{
"target": "s3",
"enabled": true
},
{
"target": "s4",
"enabled": true
},
{
"target": "s5",
"enabled": true
}
]
}
]
}
Adding hosts
Adding a host to the list will give an additional target for the consistent hashing algorithm to route requests to. This will shift content distribution onto the new host.
confcli services.routing.rules.consistentHashingRule.targets -w
Running wizard for resource 'targets'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
targets : [
target : {
target (default: ): s6
enabled (default: True):
}
Add another 'target' element to array 'targets'? [y/N]: n
]
Generated config:
{
"targets": [
{
"target": "s6",
"enabled": true
}
]
}
Merge and apply the config? [y/n]: y
Removing hosts
There is one very important caveat of using a consistent hashing rule block. As long as you don’t modify the list of hosts, the consistent hashing algorithm will keep routing requests to the same hosts. However, if you remove a host from the block in any position except the last, the consistent hashing algorithm’s behaviour will change and the algorithm cannot maintain a minimum amount of cache redistribution.
If you’re in a situation where you have to remove a host from the routing
targets but want to keep the same consistent hashing behaviour, e.g. during
very high load, you’ll have to toggle that target’s enabled
field to false
.
E.g., disabling requests to s2
can be accomplished by:
$ confcli services.routing.rules.consistentHashingRule.targets.1.enabled false
services.routing.rules.consistentHashingRule.targets.1.enabled = False
$ confcli services.routing.rules.consistentHashingRule.targets.1
{
"1": {
"target": "s2",
"enabled": false
}
}
If you modify the list order or remove hosts, it is highly recommended to do so during moments where a higher rate of cache misses are acceptable.
2.1.1.5.4.3 - Security token verification
The security token verification feature allows for ESB3024 Router to only process requests that contain a correct security token. The token is generated by the client, for example in the portal, using an algorithm that it shares with the router. The router verifies the token and rejects the request if the token is incorrect.
It is beyond the scope of this document to describe how the token is generated, that is described in the Security Tokens application note that is installed with the ESB3024 Router’s extra documentation.
Setting up a routing rule
The token verification is performed by calling the verify_security_token()
function from a routing rule. The function returns 1
if the token is
correct, otherwise it returns 0
. It should typically be called from the
first routing rule, to make requests with bad tokens fail as early as possible.
The confcli example assumes that the router already has rules configured, with
an entry point named select_cdn
. Token verification is enabled by inserting an
“allow” rule first in the rule list.
confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: allow
Adding a 'allow' element
rule : {
name (default: ): token_verification
type (default: allow):
condition (default: always()): verify_security_token()
onMatch (default: ): select_cdn
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "token_verification",
"type": "allow",
"condition": "verify_security_token()",
"onMatch": "select_cdn"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint token_verification
services.routing.entrypoint = 'token_verification'
"routing": {
"id": "token_verification",
"member_order": "sequential",
"members": [
{
"id": "token_verification.0.select_cdn",
"member_order": "weighted",
"members": [
...
],
"weight_function": "return verify_security_token() ~= 0"
},
{
"id": "token_verification.1.rejected",
"member_order": "sequential",
"members": [],
"weight_function": "return 1"
}
],
"weight_function": "return 100"
},
Configuring security token options
The secret
parameter is not part of the router request, but needs to be
configured separately in the router. That can be done with the host-config
tool that is installed with the router.
Besides configuring the secret, host-config
can also configure floating
sessions and a URL prefix. Floating sessions are sessions that are not tied to a
specific IP address. When that is enabled, the token verification will not take
the IP address into account when verifying the token.
The security token verification is configured per host, where a host is the name
of the host that the request was sent to. This makes it possible for a router to
support multiple customer accounts, each with their own secret. If no
configuration is found for a host, a configuration with the name default
is
used.
host-config
supports three commands: print
, set
and delete
.
The print
command prints the current configuration for a host. The following
parameters are supported:
host-config print [-n <host-name>]
By default it prints the configuration for all hosts, but if the optional -n
flag is given it will print the configuration for a single host.
Set
The set
command sets the configuration for a host. The configuration is given
as command line parameters. The following parameters are supported:
host-config set
-n <host-name>
[-f floating]
[-p url-prefix]
[-r <secret-to-remove>]
[-s <secret-to-add>]
-n <host-name>
- The name of the host to configure.-f floating
- A boolean option that specifies if floating sessions are accepted. The parameter accepts the valuestrue
andfalse
.-p url-prefix
- A URL prefix that is used for identifying requests that come from a certain account. This is not used when verifying tokens.-r <secret-to-remove>
- A secret that should be removed from the list of secrets.-s <secret-to-add>
- A secret that should be added to the list of secrets.
For example, to set the secret “secret-1” and enable floating sessions for the default host, the following command can be used:
host-config set -n default -s secret-1 -f true
The set
command only touches the configuration options that are mentioned on
the command line, so the following command line will add a second secret to the
default host without changing the floating session setting:
host-config set -n default -s secret-2
It is possible to set multiple secrets per host. This is useful when updating a secret, then both the old and the new secret can be valid during the transition period. After the transition period the old secret can be removed by typing:
host-config set -n default -r secret-1
Delete
The delete
command deletes the configuration for a host. It supports the
following parameters:
host-config delete -n <host-name>
For example, to delete the configuration for example.com
, the following
command can be used:
host-config delete -n example.com
Global options
host-config
also has a few global options. They are:
-k <security-key>
- The security key that is used when communicating with the router. This is normally retrieved automatically.-h
- Print a help message and exit.-r <router>
- The router to connect to. This default tolocalhost
, but can be changed to connect to a remote router.-v
- Verbose output, can be given multiple times.
Debugging security token verification
The security token verification only logs messages when the log level is set to
4 or higher. Then it will only log some errors. It is possible to enable more
verbose logging using the security-token-config
that is installed together
with the router.
When verbose logging is enabled, the router will log information about the token verification, including the configured token secrets, so it needs to be used with care.
The logged lines are prefixed with verify_security_token
.
The security-token-config
tool supports the commands print
and set
.
The print
command prints the current configuration. If nothing is configured
it will not print anything.
Set
The set
command sets the configuration. The following parameters are
supported:
security-token-config set
[-d <enabled>]
-d <enabled>
- A boolean option that specifies if debug logging should be enabled or not. The parameter accepts the valuestrue
andfalse
.
2.1.1.5.4.4 - Subnets API
ESB3024 Router provides utilities to quickly match clients into subnets. Any combination of IPv4 and IPv6 addresses can be used. To begin, a JSON file is needed, defining all subnets, e.g:
{
"255.255.255.255/24": "area1",
"255.255.255.255/16": "area2",
"255.255.255.255/8": "area3",
"90.90.1.3/16": "area4",
"5.5.0.4/8": "area5",
"2a02:2e02:9bc0::/48": "area6",
"2a02:2e02:9bc0::/32": "area7",
"2a02:2e02:9bc0::/16": "area8",
"2a02:2e02:9de0::/44": "combined_area",
"2a02:2e02:ada0::/44": "combined_area"
}
and PUT
it to the endpoint :5001/v1/subnets
or :5001/v2/subnets
, the
API version doesn’t matter for subnets:
curl -k -T subnets.json -H "Content-Type: application/json" https://router-host:5001/v1/subnets
Note that it is possible for several subnet CIDR strings to share the same label, effectively grouping them together.
The router provides the built-in function in_subnet(subnet_name)
that
can to make routing decisions based on a client’s subnet. For more details, see
Built-in Lua functions.
To configure a rule that only allows clients in the area1
subnet, run the
command
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: allow
Adding a 'allow' element
rule : {
name (default: ): only_allow_area1
type (default: allow):
condition (default: always()): in_subnet('area1')
onMatch (default: ): example-host
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "only_allow_area1",
"type": "allow",
"condition": "in_subnet('area1')",
"onMatch": "example-host"
}
]
}
Merge and apply the config? [y/n]: y
Invalid IP-addresses will be omitted during subnet list construction accompanied by a message in the log displaying the invalid IP address.
2.1.1.5.4.5 - Lua Features
Detailed descriptions and examples of Lua features offered by ESB3024 Router.
2.1.1.5.4.5.1 - Built-in Lua Functions
This section details all built-in Lua functions provided by the router.
Logging functions
The router provides Lua logging functionality that is convenient when creating custom Lua functions. A prefix can be added to the log message which is useful to differentiate log messages from different lua files. At the top of the Lua source file, add the line
local log = log.add_prefix("my_lua_file")
to prepend all log messages with "my_lua_file"
.
The logging functions support formatting and common log levels:
log.critical('A log message with number %d', 1.5)
log.error('A log message with string %s', 'a string')
log.warning('A log message with integer %i', 1)
log.info('A log message with a local number variable %d', some_local_number)
log.debug('A log message with a local string variable %s', some_local_string)
log.trace('A log message with a local integer variable %i', some_local_integer)
log.message('A log message')
Many of the router’s built-in Lua functions use the logging functions.
Logging functions
The router provides Lua logging functionality that is convenient when creating custom Lua functions. A prepend can be added to the log message which is useful to differentiate log messages from different lua files. At the top of the file, add the line
local log = log.add_prefix("my_lua_file")
to prepend all log messages with "my_lua_file"
.
The logging functions support formatting and common log levels:
log.critical('A log message with number %d', 1.5)
log.error('A log message with string %s', 'a string')
log.warning('A log message with integer %i', 1)
log.info('A log message with a local number variable %d', some_local_number)
log.debug('A log message with a local string variable %s', some_local_string)
log.trace('A log message with a local integer variable %i', some_local_integer)
log.message('A log message')
Many of the router’s built in Lua functions use the logging functions.
Predictive load balancing functions
Predictive load balancing is a tool that can be used to avoid overloading hosts with traffic. Consider the case where a popular event starts at a certain time, let’s say 12 PM. A spike in traffic will be routed to the hosts that are streaming the content at 12 PM, most of them starting at low bitrates. A host might have sufficient bandwidth left to take on more clients but when the recently connected clients start ramping up in video quality and increase their bitrate, the host can quickly become overloaded, possibly dropping incoming requests or going offline. Predictive load balancing solves this issue by considering how many times a host recently been redirected to.
Four functions for predictive load balancing are provided by the router
that can be used when constructing conditions/weight functions: host_bitrate()
, host_bitrate_custom()
, host_has_bw()
and host_has_bw_custom()
.
All require data to be supplied to the selection input API and apply
only to leaf nodes in the routing tree. In order for predictive load balancing
to work properly the data must be updated at regular intervals. The data needs
to be supplied by the target system.
These functions are suitable to used as host health checks. To configure host health checks, see configuring CDNs and hosts.
Note that host_bitrate()
and host_has_bw()
rely on data supplied by metrics
agents, detailed in Cache hardware metrics: monitoring and routing.
host_bitrate_custom()
and host_has_bw_custom()
rely on
manually supplied selection input data, detailed in selection input API. The
bitrate unit depends on the data submitted to the selection input API.
Example metrics
The data supplied to the selection input API by the metrics agents uses the following structure:
{
"streamer-1": {
"hardware_metrics": {
"/": {
"free": 1741596278784,
"total": 1758357934080,
"used": 16761655296,
"used_percent": 0.9532561585516977
},
"cpu_load1": 0.02,
"cpu_load15": 0.12,
"cpu_load5": 0.02,
"mem_available": 4895789056,
"mem_available_percent": 59.551760354263074,
"mem_total": 8221065216,
"mem_used": 2474393600,
"n_cpus": 4
},
"per_interface_metrics": {
"eths1": {
"link": 1,
"interface_up": true,
"megabits_sent": 22322295739.378456,
"megabits_sent_rate": 8085.2523952,
"speed": 100000
}
}
}
}
Note that all built-in functions interacting with selection input values support indexing into nested selection input data. Consider the selection input data in above. The nested values can be accessed by using dots between the keys:
si('streamer-1.per_interface_metrics.eths1.megabits_sent_rate')
Note that the whole selection input variable name must be within single quotes.
The function si()
is documented under
general purpose functions.
host_bitrate({})
host_bitrate()
returns the predicted bitrate (in megabits per second) of
the host after the recently connected clients start ramping up in streaming
quality. The function accepts an argument table with the following keys:
interface
: The name of the interface to use for bitrate prediction.- Optional
avg_bitrate
: the average bitrate per client, defaults to 6 megabits per second. - Optional
num_routers
: the number of routers that can route to this host, defaults to 1. This is important to accurately predict the incoming load if multiple routers are used. - Optional
host
: The name of the host to use for bitrate prediction. Defaults to the current host if not provided.
Required selection input data
This function relies on the field megabits_sent_rate
, supplied by the Telegraf
metrics agent, as seen in example metrics. If these fields
are missing from your selection input data, this function will not work.
Examples of usage:
host_bitrate({interface='eths0'})
host_bitrate({avg_bitrate=1, interface='eths0'})
host_bitrate({num_routers=2, interface='eths0'})
host_bitrate({avg_bitrate=1, num_routers=4, interface='eths0'})
host_bitrate({avg_bitrate=1, num_routers=4, host='custom_host', interface='eths0'})
host_bitrate({})
calculates the predicted bitrate as:
predicted_host_bitrate = current_host_bitrate + (recent_connections * avg_bitrate * num_routers)
host_bitrate_custom({})
Same functionality as host_bitrate()
but uses a custom selection input
variable as bitrate input instead of accessing hardware metrics. The function
accepts an argument table with the following keys:
custom_bitrate_var
: The name of the selection input variable to be used for accessing current host bitrate.- Optional
avg_bitrate
: seehost_bitrate()
documentation above. - Optional
num_routers
: seehost_bitrate()
documentation above.
host_bitrate_custom({custom_bitrate_var='host1_current_bitrate'})
host_bitrate_custom({avg_bitrate=1, custom_bitrate_var='host1_current_bitrate'})
host_bitrate_custom({num_routers=4, custom_bitrate_var='host1_current_bitrate'})
host_has_bw({})
Instead of accessing the predicted bitrate of a host through host_bitrate()
,
host_has_bw()
returns 1 if the host is predicted to have enough
bandwidth left to take on more clients after recent connections ramp up in
bitrate, otherwise it returns 0. The function accepts an argument table with the
following keys:
interface
: seehost_bitrate()
documentation above.- Optional
avg_bitrate
: seehost_bitrate()
documentation above. - Optional
num_routers
: seehost_bitrate()
documentation above. - Optional
host
: seehost_bitrate()
documentation above. - Optional
margin
: the bitrate (megabits per second) headroom that should be taken into account during calculation, defaults to 0.
host_has_bw({})
returns whether or not the following statement is true:
predicted_host_bitrate + margin < host_bitrate_capacity
Required selection input data
host_has_bw({})
relies on the fields megabits_sent_rate
and speed
,
supplied by the Telegraf metrics agent, as seen in
example metrics. If these fields are missing from your
selection input data, this function will not work.
Examples of usage:
host_has_bw({interface='eths0'})
host_has_bw({margin=10, interface='eth0'})
host_has_bw({avg_bitrate=1, interface='eth0'})
host_has_bw({num_routers=4, interface='eth0'})
host_has_bw({host='custom_host', interface='eth0'})
host_has_bw_custom({})
Same functionality as host_has_bw()
but uses a custom selection input
variable as bitrate. It also uses a number or a custom selection input
variable for the capacity. The function accepts an argument table
with the following keys:
custom_capacity_var
: a number representing the capacity of the network interface OR the name of the selection input variable to be used for accessing host capacity.custom_bitrate_var
: seehost_bitrate_custom()
documentation- Optional
margin
: seehost_has_bw()
documentation above. above. - Optional
avg_bitrate
: seehost_bitrate()
documentation above. - Optional
num_routers
: seehost_bitrate()
documentation above.
Examples of usage:
host_has_bw_custom({custom_capacity_var=10000, custom_bitrate_var='streamer-1.per_interface_metrics.eths1.megabits_sent_rate'})
host_has_bw_custom({custom_capacity_var='host1_capacity', custom_bitrate_var='streamer-1.per_interface_metrics.eths1.megabits_sent_rate'})
host_has_bw_custom({margin=10, custom_capacity_var=10000, custom_bitrate_var='streamer-1.per_interface_metrics.eths1.megabits_sent_rate'})
host_has_bw_custom({avg_bitrate=1, custom_capacity_var=10000, custom_bitrate_var='streamer-1.per_interface_metrics.eths1.megabits_sent_rate'})
host_has_bw_custom({num_routers=4, custom_capacity_var=10000, custom_bitrate_var='streamer-1.per_interface_metrics.eths1.megabits_sent_rate'})
Health check functions
This section details built-in Lua functions that are meant to be used for host health checks. Note that these functions rely on data supplied by metric agents detailed in Cache hardware metrics: monitoring and routing. Make sure cache hardware metrics are supplied to the router before using any of these functions.
cpu_load_ok({})
The function accepts an optional argument table with the following keys:
- Optional
host
: The name of the host. Defaults to the name of the selected host if not provided. - Optional
cpu_load5_limit
: The acceptable limit for the 5-minute CPU load. Defaults to 0.9 if not provided.
The function returns 1 if the five minute CPU load average is below their respective limits, and 0 otherwise.
Examples of usage:
cpu_load_ok()
cpu_load_ok({host = 'custom_host'})
cpu_load_ok({cpu_load5_limit = 0.8})
cpu_load_ok({host = 'custom_host', cpu_load5_limit = 0.8})
memory_usage_ok({})
The function accepts an optional argument table with the following keys:
- Optional
host
: The name of the host. Defaults to the host of the selected host if not provided. - Optional
memory_usage_limit
: The acceptable limit for the memory usage. Defaults to 0.9 if not provided.
The function returns 1 if the memory usage is below the limit, and 0 otherwise.
Examples of usage:
memory_usage_ok()
memory_usage_ok({host = 'custom_host'})
memory_usage_ok({memory_usage_limit = 0.7})
memory_usage_ok({host = 'custom_host', memory_usage_limit = 0.7})
interfaces_online({})
The function accepts an argument table with the following keys:
- Required
interfaces
: A string or a table of strings representing the network interfaces to check. - Optional
host
: The name of the host. Defaults to the host of the selected host if not provided.
The function returns 1 if all the specified interfaces are online, and 0 otherwise.
Required selection input data
This function relies on the fields link
and interface_up
, supplied by
the Telegraf metrics agent, as seen in example metrics. If
these fields are missing from your selection input data, this function will not
work.
Examples of usage:
interfaces_online({interfaces = 'eth0'})
interfaces_online({interfaces = {'eth0', 'eth1'}})
interfaces_online({host = 'custom_host', interfaces = 'eth0'})
interfaces_online({host = 'custom_host', interfaces = {'eth0', 'eth1'}})
health_check({})
The function accepts an optional argument table with the following keys:
- Required
interfaces
: A string or a table of strings representing the network interfaces to check. - Optional
host
: The name of the host. Defaults to the host of the selected host if not provided. - Optional
cpu_load5_limit
: The acceptable limit for the 5-minute CPU load. Defaults to 0.9 if not provided. - Optional
memory_usage_limit
: The acceptable limit for the memory usage. Defaults to 0.9 if not provided.
The function calls the health check functions cpu_load_ok({})
,
memory_usage_ok({})
and interfaces_online({})
. The functions returns 1 if
all these functions returned 1, otherwise it returns 0.
Examples of usage:
health_check({interfaces = 'eths0'})
health_check({host = 'custom_host', interfaces = 'eths0'})
health_check({cpu_load5_limit = 0.7, memory_usage_limit = 0.8, interfaces = 'eth0'})
health_check({host = 'custom_host', cpu_load5_limit = 0.7, memory_usage_limit = 0.8, interfaces = {'eth0', 'eth1'}})
General purpose functions
The router supplies a number of general purpose Lua functions.
always()
Always returns 1.
never()
Always returns 0. Useful for temporarily disabling caches by using it as a health check.
Examples of usage:
always()
never()
si(si_name)
The function reads the value of the selection input variable si_name
and
returns it if it exists, otherwise it returns 0. The function accepts a string
argument for the selection input variable name.
Examples of usage:
si('some_selection_input_variable_name')
si('streamer-1.per_interface_metrics.eths1.megabits_sent_rate')
Comparison functions
All comparison functions use the form function(si_name, value)
and compares
the selection input value with the name si_name
with value
.
ge(si_name, value)
- greater than or equal
gt(si_name, value)
- greater than
le(si_name, value)
- less than or equal
lt(si_name, value)
- less than
eq(si_name, value)
- equal to
neq(si_name, value)
- not equal to
Examples of usage:
ge('streamer-1.hardware_metrics.mem_available_percent', 30)
gt('streamer-1.hardware_metrics./.free', 1000000000)
le('streamer-1.hardware_metrics.cpu_load5', 0.8)
lt('streamer-1.per_interface_metrics.eths1.megabits_sent_rate', 9000)
eq('streamer-1.per_interface_metrics.eths1.link.', 1)
neq('streamer-1.hardware_metrics.n_cpus', 4)
Session checking functions
in_subnet(subnet)
Returns 1 if the current session belongs to subnet
, otherwise it returns 0.
See Subnets API for more details on how to use
subnets in routing. The function accepts a string argument for the subnet name.
Examples of usage:
in_subnet('stockholm')
in_subnet('unserviced_region')
in_subnet('some_other_subnet')
These functions checks the current session’s session groups.
in_session_group(session_group)
Returns 1 if the current session has been classified into session_group
,
otherwise it returns 0. The function accepts a string argument for the session
group name.
in_any_session_group({})
Returns 1 if the current session has been classified into any of
session_groups
, otherwise it returns 0. The function accepts a table array of
strings as argument for the session group names.
in_all_session_groups({})
Returns 1 if the current session has been classified into all of
session_groups
, otherwise it returns 0. The function accepts a table array of
strings as argument for the session group names.
Examples of usage:
in_session_group('safari_browser')
in_any_session_group({ 'in_europe', 'in_asia'})
in_all_session_group({ 'vod_content', 'in_america'})
Configuration examples
Many of the functions documented are suitable to use in host health checks. To configure host health checks, see configuring CDNs and hosts. Here are some configuration examples of using the built-in Lua functions, utilizing the example metrics:
"healthChecks": [
"gt('streamer-1.hardware_metrics.mem_available_percent', 20)", // More than 20% memory is left
"lt('streamer-1.per_interface_metrics.eths1.megabits_sent_rate', 9000)" // Current bitrate is lower than 9000 Mbps
"host_has_bw({host='streamer-1', interface='eths1', margin=1000})", // host_has_bw() uses 'streamer-1.per_interface_metrics.eths1.speed' to determine if there is enough bandwidth left with a 1000 Mbps margin
"interfaces_online({host='streamer-1', interfaces='eths1'})",
"memory_usage_ok({host='streamer-1'})",
"cpu_load_ok({host='streamer-1'})",
"health_check({host='streamer-1', interfaces='eths1'})" // Combines interfaces_online(), memory_usage_ok(), cpu_load_ok()
]
2.1.1.5.4.5.2 - Global Lua Tables
There are multiple global tables containing important data available while writing Lua code for the router.
selection_input
Contains arbitrary, custom fields fed into the router by clients, see API overview for details on how to inject data into this table.
Note that the selection_input
table is iterable.
Usage examples:
print(selection_input['some_value'])
-- Iterate over table
if selection_input then
for k, v in pairs(selection_input) do
print('here is '..'selection_input!')
print(k..'='..v)
end
else
print('selection_input is nil')
end
session_groups
Defines a mapping from session group name to boolean
, indicating whether
the session belongs to the session group or not.
Usage examples:
if session_groups.vod then print('vod') else print('not vod') end
if session_groups['vod'] then print('vod') else print('not vod') end
session_count
Provides counters of number of session types per session group. The table
uses the structure qoe_score.<session_type>.<session_group>
.
Usage examples:
print(session_count.instream.vod)
print(session_count.initial.vod)
qoe_score
Provides the quality of experience score per host per session group. The table
uses the structure qoe_score.<host>.<session_group>
.
Usage examples:
print(qoe_score.host1.vod)
print(qoe_score.host1.live)
request
Contains data related to the HTTP request between the client and the router.
request.method
- Description: HTTP request method.
- Type:
string
- Example:
'GET'
,'POST'
request.body
- Description: HTTP request body string.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
request.major_version
- Description: Major HTTP version such as
x
inHTTP/x.1
. - Type:
integer
- Example:
1
- Description: Major HTTP version such as
request.minor_version
- Description: Minor HTTP version such as
x
inHTTP/1.x
. - Type:
integer
- Example:
1
- Description: Minor HTTP version such as
request.protocol
- Description: Transfer protocol variant.
- Type:
string
- Example:
'HTTP'
,'HTTPS'
request.client_ip
- Description: IP address of the client issuing the request.
- Type:
string
- Example:
'172.16.238.128'
request.path_with_query_params
- Description: Full request path including query parameters.
- Type:
string
- Example:
'/mycontent/superman.m3u8?b=y&c=z&a=x'
request.path
- Description: Request path without query parameters.
- Type:
string
- Example:
'/mycontent/superman.m3u8'
request.query_params
- Description: The query parameter string.
- Type:
string
- Example:
'b=y&c=z&a=x'
request.filename
- Description: The part of the path following the final slash, if any.
- Type:
string
- Example:
'superman.m3u8'
request.subnet
- Description: Subnet of
client_ip
. - Type:
string
ornil
- Example:
'all'
- Description: Subnet of
session
Contains data related to the current session.
session.client_ip
- Description: Alias for
request.client_ip
. See documentation for table request above.
- Description: Alias for
session.path_with_query_params
- Description: Alias for
request.path_with_query_params
. See documentation for table request above.
- Description: Alias for
session.path
- Description: Alias for
request.path
. See documentation for table request above.
- Description: Alias for
session.query_params
- Description: Alias for
request.query_params
. See documentation for table request above.
- Description: Alias for
session.filename
- Description: Alias for
request.filename
. See documentation for table request above.
- Description: Alias for
session.subnet
- Description: Alias for
request.subnet
. See documentation for table request above.
- Description: Alias for
session.host
- Description: ID of the currently selected host for the session.
- Type:
string
ornil
- Example:
'host1'
session.id
- Description: ID of the session.
- Type:
string
- Example:
'8eb2c1bdc106-17d2ff-00000000'
session.session_type
- Description: Type of the session.
- Type:
string
- Example:
'initial'
or'instream'
. Identical to the value of theType
argument of the session translation function.
session.is_managed
- Description: Identifies managed sessions.
- Type:
boolean
- Example:
true
ifType
/session.session_type
is'instream'
request_headers
Contains the headers from the request between the client and the router, keyed by name.
Usage example:
print(request_headers['User-Agent'])
request_query_params
Contains the query parameters from the request between the client and the router, keyed by name.
Usage example:
print(request_query_params.a)
session_query_params
Alias for metatable request_query_params
.
response
Contains data related to the outgoing response apart from the headers.
response.body
- Description: HTTP response body string.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
response.code
- Description: HTTP response status code.
- Type:
integer
- Example:
200
,404
response.text
- Description: HTTP response status text.
- Type:
string
- Example:
'OK'
,'Not found'
response.major_version
- Description: Major HTTP version such as
x
inHTTP/x.1
. - Type:
integer
- Example:
1
- Description: Major HTTP version such as
response.minor_version
- Description: Minor HTTP version such as
x
inHTTP/1.x
. - Type:
integer
- Example:
1
- Description: Minor HTTP version such as
response.protocol
- Description: Transfer protocol variant.
- Type:
string
- Example:
'HTTP'
,'HTTPS'
response_headers
Contains the response headers keyed by name.
Usage example:
print(response_headers['User-Agent'])
2.1.1.5.4.5.3 - Request Translation Function
Specifies the body of a Lua function that inspects every incoming HTTP request and overwrites individual fields before further processing by the router.
Returns nil
when nothing is to be changed, or HTTPRequest(t)
where t
is a table with any of the following optional fields:
Method
- Description: Replaces the HTTP request method in the request being processed.
- Type:
string
- Example:
'GET'
,'POST'
Path
- Description: Replaces the request path in the request being processed.
- Type:
string
- Example:
'/mycontent/superman.m3u8'
ClientIp
- Description: Replaces client IP address in the request being processed.
- Type:
string
- Example:
'172.16.238.128'
Body
- Description: Replaces body in the request being processed.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
QueryParameters
- Description: Adds, removes or replaces individual query parameters in the request being processed.
- Type: nested
table
(indexed by number) representing an array of query parameters as{[1]='Name',[2]='Value'}
pairs that are added to the request being processed, or overwriting existing query parameters with colliding names. To remove a query parameter from the request, specifynil
as value, i.e.QueryParameters={..., {[1]='foo',[2]=nil} ...}
. Returning a query parameter with a name but no value, such asa
in the request'/index.m3u8?a&b=22'
is currently not supported.
Headers
- Description: Adds, removes or replaces individual headers in the request being processed.
- Type: nested
table
(indexed by number) representing an array of request headers as{[1]='Name',[2]='Value'}
pairs that are added to the request being processed, or overwriting existing request headers with colliding names. To remove a header from the request, specifynil
as value, i.e.Headers={..., {[1]='foo',[2]=nil} ...}
. Duplicate names are supported. A multi-value header such asFoo: bar1,bar2
is defined by specifyingHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar2'}, ...}
.
Example of a request_translation_function
body that sets the request path
to a hardcoded value and adds the hardcoded query parameter a=b
:
-- Statements go here
print('Setting hardcoded Path and QueryParameters')
return HTTPRequest({
Path = '/content.mpd',
QueryParameters = {
{'a','b'}
}
})
Arguments
The following (iterable) arguments will be known by the function:
QueryParameters
Type: nested
table
(indexed by number).Description: Array of query parameters as
{[1]='Name',[2]='Value'}
pairs that were present in the query string of the request. Format identical to theHTTPRequest.QueryParameters
-field specified for the return value above.Example usage:
for _, queryParam in pairs(QueryParameters) do print(queryParam[1]..'='..queryParam[2]) end
Headers
Type: nested
table
(indexed by number).Description: Array of request headers as
{[1]='Name',[2]='Value'}
pairs that were present in the request. Format identical to theHTTPRequest.Headers
-field specified for the return value above. A multi-value header such asFoo: bar1,bar2
is seen inrequest_translation_function
asHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar1'}, ...}
.Example usage:
for _, header in pairs(Headers) do print(header[1]..'='..header[2]) end
Additional data
In addition to the arguments above, the following Lua tables, documented in Global Lua Tables, provide additional data that is available when executing the request translation function:
If the request translation function modifies the request, the request
,
request_query_params
and request_headers
tables will be updated with the
modified request and made available to the routing rules.
2.1.1.5.4.5.4 - Session Translation Function
Specifies the body of a Lua function that inspects a newly created session and may override its suggested type from “initial” to “instream” or vice versa. A number of helper functions are provided to simplify changing the session type.
Returns nil
when the session type is to remain unchanged, or Session(t)
where t
is a table with a single field:
Type
- Description: New type of the session.
- Type:
string
- Example:
'instream'
,'initial'
Basic Configuration
It is possible to configure the maximum number of simultaneous managed sessions
on the router. If the maximum number is reached, no more managed sessions can be
created. Using confcli
, it can be configured by running
$ confcli services.routing.tuning.general.maxActiveManagedSessions
{
"maxActiveManagedSessions": 1000
}
$ confcli services.routing.tuning.general.maxActiveManagedSessions 900
services.routing.tuning.general.maxActiveManagedSessions = 900
Common Arguments
While executing the session translation function, the following arguments are available:
Type
: The current type of the session ('instream'
or'initial'
).
Usage examples:
-- Flip session type
local newType = 'initial'
if Type == 'initial' then
newType = 'instream'
end
print('Changing session type from ' .. Type .. ' to ' .. newType)
return Session({['Type'] = newType})
Session Translation Helper Functions
The standard Lua library prodives four helper functions to simplify the configuration of the session translation function:
set_session_type(session_type)
This function will set the session type to the supplied session_type
and
the maximum number of sessions of that type has not been reached.
Parameters
session_type
: The type of session to create, possible values are ‘initial’ or ‘instream’.
Usage Examples
return set_session_type('instream')
return set_session_type('initial')
set_session_type_if_in_group(session_type, session_group)
This function will set the session type to the supplied session_type
if the
session is part of session_group
and the maximum number of sessions of that
type has not been reached.
Parameters
session_type
: The type of session to create, possible values are ‘initial’ or ‘instream’.session_group
: The name of the session group.
Usage Examples
return set_session_type_if_in_group('instream', 'sg1')
set_session_type_if_in_all_groups(session_type, session_groups)
This function will set the session type to the supplied session_type
if the
session is part of all session groups given by session_groups
and the maximum
number of sessions of that type has not been reached.
Parameters
session_type
: The type of session to create, possible values are ‘initial’ or ‘instream’.session_groups
: A list of session group names.
Usage Examples
return set_session_type_if_in_all_groups('instream', {'sg1', 'sg2'})
set_session_type_if_in_any_group(session_type)
This function will set the session type to the supplied session_type
if the
session is part of one or more of the session groups given by session_groups
and the maximum number of sessions of that type has not been reached.
Parameters
session_type
: The type of session to create, possible values are ‘initial’ or ‘instream’.session_groups
: A list of session group names.
Usage Examples
return set_session_type_if_in_any_group('instream', {'sg1', 'sg2'})
Configuration
Using confcli
, example of how the functions above can be used in the session
translation function can be configured by running any of
$ confcli services.routing.translationFunctions.session "return set_session_type('instream')"
services.routing.translationFunctions.session = "return set_session_type('instream')"
$ confcli services.routing.translationFunctions.session "return set_session_type_if_in_group('instream', 'sg1')"
services.routing.translationFunctions.session = "return set_session_type_if_in_group('instream', 'sg1')"
$ confcli services.routing.translationFunctions.session "return set_session_type_if_in_all_groups('instream', {'sg1', 'sg2'})"
services.routing.translationFunctions.session = "return set_session_type_if_in_all_groups('instream', {'sg1', 'sg2'})"
$ confcli services.routing.translationFunctions.session "return set_session_type_if_in_any_group('instream', {'sg1', 'sg2'})"
services.routing.translationFunctions.session = "return set_session_type_if_in_any_group('instream', {'sg1', 'sg2'})"
Additional data
In addition to the arguments above, the following Lua tables, documented in Global Lua Tables, provide additional data that is available when executing the response translation function:
The selection_input
table will not change while a routing request is handled.
A request_translation_function
and the corresponding
response_translation_function
will see the same selection_input
table, even
if the selection data is updated while the request is being handled.
2.1.1.5.4.5.5 - Host Request Translation Function
The host request translation function defines a Lua function that modifies
HTTP requests sent to a host. These hosts are configured in
services.routing.hostGroups
.
Hosts can receive requests for a manifest. A regular host will respond with the manifest itself, while a redirecting host and a DNS host will respond with a redirection to a streamer. This function can modify all these types of requests.
The function returns nil
when nothing is to be changed, or HTTPRequest(t)
where t
is a table with any of the following optional fields:
Method
- Description: Replaces the HTTP request method in the request being processed.
- Type:
string
- Example:
'GET'
,'POST'
Path
- Description: Replaces the request path in the request being processed.
- Type:
string
- Example:
'/mycontent/superman.m3u8'
Body
- Description: Replaces body in the request being processed.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
QueryParameters
- Description: Adds, removes or replaces individual query parameters in the request being processed.
- Type: nested
table
(indexed by number) representing an array of query parameters as{[1]='Name',[2]='Value'}
pairs that are added to the request being processed, or overwriting existing query parameters with colliding names. To remove a query parameter from the request, specifynil
as value, i.e.QueryParameters={..., {[1]='foo',[2]=nil} ...}
. Returning a query parameter with a name but no value, such asa
in the request'/index.m3u8?a&b=22'
is currently not supported.
Headers
- Description: Adds, removes or replaces individual headers in the request being processed.
- Type: nested
table
(indexed by number) representing an array of request headers as{[1]='Name',[2]='Value'}
pairs that are added to the request being processed, or overwriting existing request headers with colliding names. To remove a header from the request, specifynil
as value, i.e.Headers={..., {[1]='foo',[2]=nil} ...}
. Duplicate names are supported. A multi-value header such asFoo: bar1,bar2
is defined by specifyingHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar2'}, ...}
.
Host
- Description: Replaces the host that the request is sent to.
- Type:
string
- Example:
'new-host.example.com'
,'192.0.2.7'
Port
- Description: Replaces the TCP port that the request is sent to.
- Type:
number
- Example:
8081
Protocol
- Description: Decides which protocol that will be used for sending the
request. Valid protocols are
'HTTP'
and'HTTPS'
. - Type:
string
- Example:
'HTTP'
,'HTTPS'
- Description: Decides which protocol that will be used for sending the
request. Valid protocols are
Example of a host_request_translation_function
body that sets the request path
to a hardcoded value and adds the hardcoded query parameter a=b
:
-- Statements go here
print('Setting hardcoded Path and QueryParameters')
return HTTPRequest({
Path = '/content.mpd',
QueryParameters = {
{'a','b'}
}
})
Arguments
The following (iterable) arguments will be known by the function:
QueryParameters
Type: nested
table
(indexed by number).Description: Array of query parameters as
{[1]='Name',[2]='Value'}
pairs that are present in the query string of the request from the client to the router. Format identical to theHTTPRequest.QueryParameters
-field specified for the return value above.Example usage:
for _, queryParam in pairs(QueryParameters) do print(queryParam[1]..'='..queryParam[2]) end
Headers
Type: nested
table
(indexed by number).Description: Array of request headers as
{[1]='Name',[2]='Value'}
pairs that are present in the request from the client to the router. Format identical to theHTTPRequest.Headers
-field specified for the return value above. A multi-value header such asFoo: bar1,bar2
is seen inhost_request_translation_function
asHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar1'}, ...}
.Example usage:
for _, header in pairs(Headers) do print(header[1]..'='..header[2]) end
Global tables
The following non-iterable global tables are available for use by the
host_request_translation_function
.
Table outgoing_request
The outgoing_request
table contains the request that is to be sent to the
host.
outgoing_request.method
- Description: HTTP request method.
- Type:
string
- Example:
'GET'
,'POST'
outgoing_request.body
- Description: HTTP request body string.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
outgoing_request.major_version
- Description: Major HTTP version such as
x
inHTTP/x.1
. - Type:
integer
- Example:
1
- Description: Major HTTP version such as
outgoing_request.minor_version
- Description: Minor HTTP version such as
x
inHTTP/1.x
. - Type:
integer
- Example:
1
- Description: Minor HTTP version such as
outgoing_request.protocol
- Description: Transfer protocol variant.
- Type:
string
- Example:
'HTTP'
,'HTTPS'
Table outgoing_request_headers
Contains the request headers from the request that is to be sent to the host, keyed by name.
Example:
print(outgoing_request_headers['X-Forwarded-For'])
Multiple values are separated with a comma.
Additional data
In addition to the arguments above, the following Lua tables, documented in Global Lua Tables, provide additional data that is available when executing the request translation function:
2.1.1.5.4.5.6 - Response Translation Function
Specifies the body of a Lua function that inspects every outgoing HTTP response and overwrites individual fields before being sent to the client.
Returns nil
when nothing is to be changed, or HTTPResponse(t)
where t
is a table with any of the following optional fields:
Code
- Description: Replaces status code in the response being sent.
- Type:
integer
- Example:
200
,404
Text
- Description: Replaces status text in the response being sent.
- Type:
string
- Example:
'OK'
,'Not found'
MajorVersion
- Description: Replaces major HTTP version such as
x
inHTTP/x.1
in the response being sent. - Type:
integer
- Example:
1
- Description: Replaces major HTTP version such as
MinorVersion
- Description: Replaces minor HTTP version such as
x
inHTTP/1.x
in the response being sent. - Type:
integer
- Example:
1
- Description: Replaces minor HTTP version such as
Protocol
- Description: Replaces protocol in the response being sent.
- Type:
string
- Example:
'HTTP'
,'HTTPS'
Body
- Description: Replaces body in the response being sent.
- Type:
string
ornil
- Example:
'{"foo": "bar"}'
Headers
- Description: Adds, removes or replaces individual headers in the response being sent.
- Type: nested
table
(indexed by number) representing an array of response headers as{[1]='Name',[2]='Value'}
pairs that are added to the response being sent, or overwriting existing request headers with colliding names. To remove a header from the response, specifynil
as value, i.e.Headers={..., {[1]='foo',[2]=nil} ...}
. Duplicate names are supported. A multi-value header such asFoo: bar1,bar2
is defined by specifyingHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar2'}, ...}
.
Example of a response_translation_function
body that sets the Location
header to a hardcoded value:
-- Statements go here
print('Setting hardcoded Location')
return HTTPResponse({
Headers = {
{'Location', 'cdn1.com/content.mpd?a=b'}
}
})
Arguments
The following (iterable) arguments will be known by the function:
Headers
Type: nested
table
(indexed by number).Description: Array of response headers as
{[1]='Name',[2]='Value'}
pairs that are present in the response being sent. Format identical to theHTTPResponse.Headers
-field specified for the return value above. A multi-value header such asFoo: bar1,bar2
is seen inresponse_translation_function
asHeaders={..., {[1]='foo',[2]='bar1'}, {[1]='foo',[2]='bar1'}, ...}
.Example usage:
for _, header in pairs(Headers) do print(header[1]..'='..header[2]) end
Additional data
In addition to the arguments above, the following Lua tables, documented in Global Lua Tables, provide additional data that is available when executing the response translation function:
2.1.1.5.5 - Trusted proxies
When a request with the header X-Forwarded-For
is sent to the router, the
router will check if the client is in the list of trusted proxies. If the client
is not a trusted proxy, the router will drop the connection, returning an empty
reply to the client. If the client is a trusted proxy, the IP address defined
in the X-Forwarded-For
will be regarded as the client’s IP address.
The list of trusted proxies can be configured by modifying the configuration
field services.routing.settings.trustedProxies
with the IP addresses of
trusted proxies:
$ confcli services.routing.settings.trustedProxies -w
Running wizard for resource 'trustedProxies'
<A list of IP addresses from which the proxy IP address of requests with the X-Forwarded-For header defined are checked. If the IP isn't in this list, the connection is dropped. (default: [])>
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
trustedProxies <A list of IP addresses from which the proxy IP address of requests with the X-Forwarded-For header defined are checked. If the IP isn't in this list, the connection is dropped. (default: [])>: [
trustedProxy (default: ): 1.2.3.4
Add another 'trustedProxy' element to array 'trustedProxies'? [y/N]: n
]
Generated config:
{
"trustedProxies": [
"1.2.3.4"
]
}
Merge and apply the config? [y/n]: y
Note that by configuring 0.0.0.0/0
as a trusted proxy, all proxied requests
will be trusted.
2.1.1.5.6 - Confd Auto Upgrade Tool
The confd-auto-upgrade
tool is a simple utility to automatically migrate the confd
configuration schema between different versions of the Director. Starting with version
1.12.0, it is possible to automatically apply the necessary configuration changes in a
controlled and predictable manner. While this tool is intended to help transition the
configuration format between the different versions, it is not a substitute for proper
backups, and while downgrading to an earlier version, it may not be possible to recover
previously modified or deleted configuration values.
When using the tool, both the “from” and “to” versions must be specified. Internally, the tool will calculate a list of migrations which must be applied to transition between the given versions, and apply them, outputting the final configuration to standard output. The current configuration can either be piped in to the tool via standard input, or supplied as a static file. Providing a “from” version which is later than the “to” version will result in the downgrade migrations being applied in reverse order, effectively downgrading the configuration to the lower version.
For convenience, the tool is deployed to the ACD Nodes automatically at install time as a standard Podman container, however since it is not intended to run as a service, only the image will be present, not a running container.
Performing the Upgrade
In the following example scenario, a system with version 1.10.1 has been upgraded
to 1.14.0. Before upgrading a backup of the configuration was taken and saved to
current_config.json
.
Using the image and tag as determined in the above section. Issue the following command:
cat current_config.json | \
podman run -i --rm images.edgeware.tv/acd-confd-migration:1.14.0 \
--in - --from 1.10.1 --to 1.14.0 \
| tee upgraded_config.json
In the above example, the updated configuration is saved to upgraded_config.json
.
It is recommended to manually verify the generated configuration, and after
which apply the config to confd by using cat upgraded_config.json | confcli -i
.
It is also possible to combine the two commands, by piping the output of the auto-upgrade
tool directly to confcli -i
. E.g.
cat current_config.json | podman run ... | tee upgraded_config.json | confcli -i
This will save a backup of the upgraded configuration to upgraded_config.json
and
at the same time apply the changes to confd immediately.
Downgrading the Configuration
The steps for downgrading the configuration are exactly the same as for upgrade except for the --from
and --to
versions should be swapped. E.g. --from 1.14.0 --to 1.10.1
. Keep in mind however,
that during an upgrade some configuration properties may have been deleted or modified, and while
downgrading over those steps, some data loss may occur. In those cases, it may be easier and safer
to simply restore from backup. In most cases where configuration properties are removed during upgrade,
the corresponding downgrade will simply restore the default values of those properties.
2.1.1.6 - Operations
This guide describes how to perform day-to-day operations of the ACD Router and its associated services, collectively known as the Director.
Component Overview
To effectively operate the Director software, it is important to understand the composition of the various software components and how they are deployed.
Each Director instance functions as an independent system, comprising multiple containerized services. These containers are managed by a standard container runtime and are seamlessly integrated with the host’s operating system to enhance the overall operator experience.
The containers are managed by the Podman container runtime, which operates without additional daemon services running on the host. Unlike Docker, Podman manages each container as a separate process, eliminating the reliance on a shared daemon and mitigating the risk of a single-point-of-failure scenario.
Although several distinct services make up the Director, the primary component is the router. The router is responsible for listening for incoming requests, processing the request, and redirecting the client to the appropriate host, or CDN to deliver the requested content.
Two additional containers are responsible for configuration management. Those are
confd
and confd-transformer
. The former manages a local database of configuration
metadata and provides a REST API for managing the configuration. The confd-transformer
simply listens for configuration changes from confd
and adapts that configuration
to a format suitable for the router to ingest. For additional information about
setting up and using confd see here..
The next two components, the edns-proxy
and the convoy-bridge
allow the router
to communicate with an EDNS server for EDNS-based routing, and with synchronization
with Convoy respectively. Additional information about the EDNS-Proxy is available
here.. For the Convoy Bridge
service see here..
The remaining containers are useful for metrics, monitoring, and alerting. These
include prometheus
and grafana
for monitoring and analytics, and alertmanager
for monitoring and alarms.
2.1.1.6.1 - Services
Each container shipped with the Director is fully-integrated with the systemd
service on the host, enabling easy management using standard systemd
commands.
The logs for each container are also full-integrated with journald to simplify
troubleshooting.
In order to integrate the Podman containers with systemd
, a common prefix
of acd-
has been applied to each service name. For example the router
container is managed by the service acd-router
, and the confd
container
is managed by the service acd-confd
. These same prefixed names apply while
fetching logs via journald
. This common prefix aids in grouping the related
services as well as provides simpler filtering for tab-completion.
Starting / Stopping Services
Standard systemd commands should be used to start and stop the services.
systemctl start acd-router
- Starts therouter
container.systemctl stop acd-router
- Stops therouter
container.systemctl status acd-router
- Displays the status of therouter
container.
Due to the limitation of needing the acd-
prefix, it provides the ability to
work with all ACD services in a group. For example:
systemctl status 'acd-*'
- Display the status of all installed ACD components.systemctl start 'acd-*'
- Start all ACD components.
Logging
Each ACD component corresponds to a journal entry with the same unit name, with
the acd-
prefix. Standard journald commands can be used to view and manage the
logging.
journalctl -u acd-router
- Display the logs for therouter
container
Access Log
HTTP access logging can be enabled by typing this:
confcli services.routing.tuning.general.accessLog true
When access logging is enabled, the Director will log all content requests. The logs can be obtained from journald by using the following command:
journalctl SYSLOG_IDENTIFIER=router ACCESSLOG=1
This will output the router’s access logs in a standard format.
Troubleshooting
Some additional logging may be available in the filesystem, the paths of which can
be determined by executing the ew-sysinfo
command. See
Diagnostics. for additional details.
2.1.1.7 - Convoy Bridge
The convoy-bridge is an optional integration service, pre-installed alongside the router which provides two-way communication between the router and a separate Convoy installation.
The convoy-bridge is designed to allow the Convoy account metadata to be available from within the router for such use-cases as inserting the account specific prefixes in the redirect URL and validating per-account internal security tokens. The service works by periodically polling the Convoy server for changes to the configuration, and when detected, the relevant configuration information is pushed to the router.
In addition, the convoy-bridge has the ability to integrate the router with the Convoy analytics service, such that client sessions started by the router are properly collected by Convoy, and are available in the dashboards.
Configuration
The convoy-bridge service is configured using confcli
on the router host.
All configuration for the convoy-bridge exists under the path
integration.convoy.bridge
.
{
"logLevel": "info",
"accounts": {
"enabled": true,
"dbUrl": "mysql://convoy:eith7jee@convoy:3306",
"dbPollInterval": 60
},
"analytics": {
"enabled": true,
"brokers": ["broker1:9092", "broker2:9092"],
"batchInterval": 10,
"maxBatchSize": 500
},
"otherRouters": [
{
"url": "https://router2:5001",
"apiKey": "key1",
"validateCerts": true
}
]
}
In the above configuration block, there are three main sections. The accounts
section enables fetching account metadata from Convoy towards the router. The
analytics
section controls the integration between the router and the Convoy
analytics service. The otherRouters
section is used to synchronize additional
router instances. The local router instance will always be implicitly included.
Additional routers listed in this section will be handled by this instance of
the convoy-bridge service.
Logging
The logs are available in the system journal and can be viewed using:
journalctl -u acd-convoy-bridge
2.1.1.8 - Monitoring
2.1.1.8.1 - System troubleshooting
ESB3024 contains the tool ew-sysinfo
that gives an overview of how the
system is doing. Simply use the command and the tool will output information
about the system and the installed ESB3024 services.
The output format can be changed using the --format
flag, possible values
are human
(default) and json
, e.g.:
$ ew-sysinfo
system:
os: ['5.4.17-2136.321.4.el8uek.x86_64', 'Oracle Linux Server 8.8']
cpu_cores: 2
cpu_load_average: [0.03, 0.03, 0.0]
memory_usage: 478 MB
memory_load_average: [0.03, 0.03, 0.0]
boot_time: 2023-09-08T08:30:57Z
uptime: 6 days, 3:43:44.640665
processes: 122
open_sockets:
ipv4: 12
ipv6: 18
ip_total: 30
tcp_over_ipv4: 9
tcp_over_ipv6: 16
tcp_total: 25
udp_over_ipv4: 3
udp_over_ipv6: 2
udp_total: 5
total: 145
system_disk (/):
total: 33271 MB
used: 7978 MB (24.00%)
free: 25293 MB
journal_disk (/run/log/journal):
total: 1954 MB
used: 217 MB (11.10%)
free: 1736 MB
vulnerabilities:
meltdown: Mitigation: PTI
spectre_v1: Mitigation: usercopy/swapgs barriers and __user pointer sanitization
spectre_v2: Mitigation: Retpolines, STIBP: disabled, RSB filling, PBRSB-eIBRS: Not affected
processes:
orc-re:
pid: 177199
status: sleeping
cpu_usage_percent: 1.0%
cpu_load_average: 131.11%
memory_usage: 14 MB (0.38%)
num_threads: 10
hints:
get_raw_router_config: cat /opt/edgeware/acd/router/cache/config.json
get_confd_config: cat /opt/edgeware/acd/confd/store/__active
get_router_logs: journalctl -u acd-router
get_edns_proxy_logs: journalctl -u acd-edns-proxy
check_firewall_status: systemctl status firewalld
check_firewall_config: iptables -nvL
# For --format=json, it's recommended to pipe the output to a JSON interpreter
# such as jq
$ ew-sysinfo --format=json | jq
{
"system": {
"os": [
"5.4.17-2136.321.4.el8uek.x86_64",
"Oracle Linux Server 8.8"
],
"cpu_cores": 2,
"cpu_load_average": [
0.01,
0.0,
0.0
],
"memory_usage": "479 MB",
"memory_load_average": [
0.01,
0.0,
0.0
],
"boot_time": "2023-09-08 08:30:57",
"uptime": "6 days, 5:12:24.617114",
"processes": 123,
"open_sockets": {
"ipv4": 13,
"ipv6": 18,
"ip_total": 31,
"tcp_over_ipv4": 10,
"tcp_over_ipv6": 16,
"tcp_total": 26,
"udp_over_ipv4": 3,
"udp_over_ipv6": 2,
"udp_total": 5,
"total": 146
}
},
"system_disk (/)": {
"total": "33271 MB",
"used": "7977 MB (24.00%)",
"free": "25293 MB"
},
"journal_disk (/run/log/journal)": {
"total": "1954 MB",
"used": "225 MB (11.50%)",
"free": "1728 MB"
},
"vulnerabilities": {
"meltdown": "Mitigation: PTI",
"spectre_v1": "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
"spectre_v2": "Mitigation: Retpolines, STIBP: disabled, RSB filling, PBRSB-eIBRS: Not affected"
},
"processes": {
"orc-re": {
"pid": 177199,
"status": "sleeping",
"cpu_usage_percent": "0.0%",
"cpu_load_average": "137.63%",
"memory_usage": "14 MB (0.38%)",
"num_threads": 10
}
}
}
Note that your system might have different monitored processes and field names.
The field hints
is different from the rest. It lists common commands
that can be used to further monitor system performance, useful for
quickly troubleshooting a faulty system.
2.1.1.8.2 - Scraping data with Prometheus
Prometheus is a third-party data scraper which is installed as a containerized service in the default installation of ESB3024 Router. It periodically reads metrics data from different services, such as acd-router, aggregates it and makes it available to other services that visualize the data. Those services include Grafana and Alertmanager.
The Prometheus configuration file can be found on the host at
/opt/edgeware/acd/prometheus/prometheus.yaml
.
Accessing Prometheus
Prometheus has a web interface that is listening for HTTP connections on port 9090. There is no authentication, so anyone who has access to the host that is running Prometheus can access the interface.
Starting / Stopping Prometheus
After the service is configured, it can be managed via systemd, under the
service unit acd-prometheus
.
systemctl start acd-prometheus
Logging
The container logs are automatically published to the system journal, under
the same unit descriptor, and can be viewed using journalctl
journalctl -u acd-prometheus
2.1.1.8.3 - Visualizing data with Grafana
2.1.1.8.3.1 - Managing Grafana
Grafana displays graphs based on data from Prometheus. A default deployment of Grafana is running in a container alongside ESB3024 Router.
Grafana’s configuration and runtime files are stored under
/opt/edgeware/acd/grafana
. It comes with default dashboards that are
documented at Grafana dashboards.
Accessing Grafana
Grafana’s web interface is listening for HTTP connections on port
3000. It has two default accounts, edgeware
and admin
.
The edgeware
account can only view graphs, while the admin
account can also
edit graphs. The accounts with default passwords are shown in the table below.
Account | Default password |
---|---|
edgeware | edgeware |
admin | edgeware |
Starting / Stopping Grafana
Grafana can be managed via systemd, under the service unit acd-grafana
.
systemctl start acd-grafana
Logging
The container logs are automatically published to the system journal, under
the same unit descriptor, and can be viewed using journalctl
journalctl -u acd-grafana
2.1.1.8.3.2 - Grafana Dashboards
Grafana will be populated with pre-configured graphs which present some metrics on a time scale. Below is a comprehensive list of those dashboards, along with short descriptions.
Router Monitoring dashboard
This dashboard is by default set as home
directory - it’s what user will see
after logging in.
Number Of Initial Routing Decisions
HTTP Status Codes
Total number of responses sent back to incoming requests, shown by their status codes. Metric: client-response-status
Incoming HTTP and HTTPS Requests
Total number of incoming requests that were deemed valid, divided into SSL
and Unencrypted
categories.
Metric: num_valid_http_requests
Debugging Information dashboard
Number of Lua Exceptions
Number of exceptions encountered so far while evaluating Lua rules. Metric: lua_num_errors
Number of Lua Contexts
Number of active Lua interpreters, both running and idle. Metric: lua_num_evaluators
Time Spent In Lua
Number of microseconds the Lua interpreters were running. Metric: lua_time_spent
Router Latencies
Histogram-like graph showing how many responses were sent within the given latency interval. Metric: orc_latency_bucket
Internal debugging
A folder that contains dashboards intended for internal use.
ACD: Incoming Internet Connections dashboard
SSL Warnings
Rate of warnings logged during TLS connections Metric: num_ssl_warnings_total
SSL Errors
Rate of errors logged during TLS connections Metric: num_ssl_errors_total
Valid Internet HTTPS Requests
Rate of incoming requests that were deemed valid, HTTPS only. Metric: num_valid_http_requests
Invalid Internet HTTPS Requests
Rate of incoming requests that were deemed invalid, HTTPS only. Metric: num_invalid_http_requests
Valid Internet HTTP Requests
Rate of incoming requests that were deemed valid, HTTP only. Metric: num_valid_http_requests
Invalid Internet HTTP Requests
Rate of incoming requests that were deemed invalid, HTTP only. Metric: num_invalid_http_requests
Prometheus: ACD dashboard
Logged Warnings
Rate of logged warnings since the router has started, divided into CDN-related and CDN-unrelated. Metric: num_log_warnings_total
Logged Errors
Rate of logged errors since the router has started. Metric: num_log_errors_total
HTTP Requests
Rate of responses sent to incoming connections. Metric: orc_latency_count
Number Of Active Sessions
Number of sessions opened on router that are still active. Metric: num_sessions
Total Number Of Sessions
Total number of sessions opened on router. Metric: num_sessions
Session Type Counts (Non-Stacked)
Number of active sessions divided by type; see metric documentation linked below for up-to-date list of types. Metric: num_sessions
Prometheus/ACD: Subrunners
Client Connections
Number of currently open client connections per subrunner. Metric: subrunner_client_conns
Asynchronous Queues (Current)
Number of queued events per subrunner, roughly corresponding to load. Metric: subrunner_async_queue
Used <Send/receive> Data Blocks
Number of send or receive data blocks currently in use per subrunner, as decided by the “Send/receive” drop down box. Metric: subrunner_used_send_data_blocks and subrunner_used_receive_data_blocks
Asynchronous Queues (Max)
Maximum number of events waiting in queue. Metric: subrunner_max_async_queue
Total <Send/receive> Data Blocks
Number of send or receive data blocks allocated per subrunner, as decided by the “Send/receive” drop down box. Metric: subrunner_total_send_data_blocks and subrunner_total_receive_data_blocks
Low Queue (Current)
Number of low priority events queued per subrunner. Metric: subrunner_low_queue
Medium Queue (Current)
Number of medium priority events queued per subrunner. Metric: subrunner_medium_queue
High Queue (Current)
Number of high priority events queued per subrunner. Metric: subrunner_high_queue
Low Queue (Max)
Maximum number of events waiting in low priority queue. Metric: subrunner_max_low_queue
Medium Queue (Max)
Maximum number of events waiting in medium priority queue. Metric: subrunner_max_medium_queue
High Queue (Max)
Maximum number of events waiting in high priority queue. Metric: subrunner_max_high_queue
Wakeups
The number of times a subrunner has been waken up from sleep. Metric: subrunner_io_wakeups
Overloaded
The number of times the number of queued events for a subrunner exceeded its maximum. Metric: subrunner_times_worker_overloaded
Autopause
Number of sockets that have been automatically paused. This happens when the work manager is under heavy load. Metric: subrunner_io_autopause_sockets
2.1.1.8.4 - Alarms and Alerting
Alerts are generated by the third-party service Prometheus, which sends them to the Alertmanager service. A default containerized instance of Alertmanager is deployed alongside ESB3024 Router. Out of the box, Alertmanager ships with only a sample configuration file, and will require manual configuration prior to enabling the alerting functionality. Due to the many different possible configurations for how alerts are both detected and where they are pushed, the official Alertmanager documentation should be followed for how to configure the service.
The router ships with Alertmanager 0.25, the documentation
for which can be found at prometheus.io.
The Alertmanager configuration file can be found on the host at
/opt/edgeware/acd/alertmanager/alertmanager.yml
.
Accessing Alertmanager
Alertmanager has a web interface that is listening for HTTP connections on port 9093. There is no authentication, so anyone who has access to the host that is running Alertmanager can access the interface.
Starting / Stopping Alertmanager
After the service is configured, it can be managed via systemd, under the
service unit acd-alertmanager
.
systemctl start acd-alertmanager
Logging
The container logs are automatically published to the system journal, under
the same unit descriptor, and can be viewed using journalctl
journalctl -u acd-alertmanager
2.1.1.8.5 - Monitoring multiple routers
By default an instance of Prometheus only monitors the ESB3024 Router that is installed on the same host as where Prometheus is installed. It is possible to make it monitor other router instances and visualize all instances on one Grafana instance.
Configuring of Prometheus
This is configured in the scraping configuration of Prometheus, which is found
in the file /opt/edgeware/acd/prometheus/prometheus.yaml
, which typically
looks like this:
global:
scrape_interval: 15s
rule_files:
- recording-rules.yaml
# A scrape configuration for router metrics
scrape_configs:
- job_name: 'router-scraper'
scheme: https
tls_config:
insecure_skip_verify: true
static_configs:
- targets:
- acd-router-1:5001
metrics_path: /m1/v1/metrics
honor_timestamps: true
- job_name: 'edns-proxy-scraper'
scheme: http
static_configs:
- targets:
- acd-router-1:8888
metrics_path: /metrics
honor_timestamps: true
More routers can be added to the scrape configuration by simply adding more
routers under targets
in the scraper jobs.
For instance, to monitor acd-router-2
and acd-router-3
along acd-router-1
,
the configuration file needs to be modified like this:
global:
scrape_interval: 15s
rule_files:
- recording-rules.yaml
# A scrape configuration for router metrics
scrape_configs:
- job_name: 'router-scraper'
scheme: https
tls_config:
insecure_skip_verify: true
static_configs:
- targets:
- acd-router-1:5001
- acd-router-2:5001
- acd-router-3:5001
metrics_path: /m1/v1/metrics
honor_timestamps: true
- job_name: 'edns-proxy-scraper'
scheme: http
static_configs:
- targets:
- acd-router-1:8888
- acd-router-2:8888
- acd-router-3:8888
metrics_path: /metrics
honor_timestamps: true
After the file has been modified, Prometheus needs to be restarted by typing
systemctl restart acd-prometheus
It is possible to use the same configuration on multiple routers, so that all routers in a deployment can monitor each other.
Selecting router in Grafana
In the top left corner the Grafana dashboards have a drop-down menu labeled “ACD Router”, which allows to choose which router to monitor.
2.1.1.8.6 - Routing Rule Evaluation Metrics
ESB3024 Router counts the number of times a node and any of its children is selected in the routing table.
The visit counters can be retrieved with the following end points:
/v1/node_visits
Returns visit counters for each node as a flat list of
host:counter
pairs in JSON.Example output:
{ "node1": "1", "node2": "1", "node3": "1", "top": "3" }
/v1/node_visits_graph
Returns a full graph of nodes with their respective visit counters in GraphML.
Example output:
<?xml version="1.0"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <key id="visits" for="node" attr.name="visits" attr.type="string" /> <graph id="G" edgedefault="directed"> <node id="routing_table"> <data key="visits">5</data> </node> <node id="cdn1"> <data key="visits">1</data> </node> <node id="node1"> <data key="visits">1</data> </node> <node id="cdn2"> <data key="visits">2</data> </node> <node id="node2"> <data key="visits">2</data> </node> <node id="cdn3"> <data key="visits">2</data> </node> <node id="node3"> <data key="visits">2</data> </node> <edge id="e0" source="cdn1" target="node1" /> <edge id="e1" source="routing_table" target="cdn1" /> <edge id="e2" source="cdn2" target="node2" /> <edge id="e3" source="routing_table" target="cdn2" /> <edge id="e4" source="cdn3" target="node3" /> <edge id="e5" source="routing_table" target="cdn3" /> </graph> </graphml>
To receive the graph as JSON, specify
Accept:application/json
in the request headers.Example output:
{ "edges": [ { "source": "cdn1", "target": "node1" }, { "source": "routing_table", "target": "cdn1" }, { "source": "cdn2", "target": "node2" }, { "source": "routing_table", "target": "cdn2" }, { "source": "cdn3", "target": "node3" }, { "source": "routing_table", "target": "cdn3" } ], "nodes": [ { "id": "routing_table", "visits": "5" }, { "id": "cdn1", "visits": "1" }, { "id": "node1", "visits": "1" }, { "id": "cdn2", "visits": "2" }, { "id": "node2", "visits": "2" }, { "id": "cdn3", "visits": "2" }, { "id": "node3", "visits": "2" } ] }
Resetting Visit Counters
A node visit counter with an id
not matching any node id
of a newly applied
routing table is destroyed.
Reset all counters to zero by momentarily applying a configuration with a
placeholder routing
root node, that has unique id
and an empty members
list, e.g:
"routing": {
"id": "empty_routing_table",
"members": []
}
… and immediately reapply the desired configuration.
2.1.1.8.7 - Metrics
ESB3024 Router collects a large number of metrics that can give insight into
it’s condition at runtime. Those metrics are available in
Prometheus’ text-based exposition format
at endpoint :5001/m1/v1/metrics
.
Below is the description of these metrics along with their labels.
client_response_status
Number of responses sent back to incoming requests.
- Type: counter
lua_num_errors
Number of errors encountered when evaluating Lua rules.
- Type:
counter
lua_num_evaluators
Number of Lua rules evaluators (active interpreters).
- Type: gauge
lua_time_spent
Time spent by running Lua evaluators, in microseconds.
- Type:
counter
num_configuration_changes
Number of times configuration has been changed since the router has started.
- Type:
counter
num_endpoint_requests
Number of requests redirected per CDN endpoint.
- Type:
counter
- Labels:
endpoint
- CDN endpoint address.selector
- whether the request was counted duringinitial
orinstream
selection.
num_invalid_http_requests
Number of client requests that either use wrong method or wrong URL path. Also number of all requests that cannot be parsed as HTTP.
- Type:
counter
- Labels:
source
- name of internal filter function that classified request as invalid. Probably not of much use outside debugging.type
- whether the request was HTTP (Unencrypted
) or HTTPS (SSL
).
num_log_errors_total
Number of logged errors since the router has started.
- Type:
counter
num_log_warnings_total
Number of logged warnings since the router has started.
- Type:
counter
num_managed_redirects
Number of redirects to the router itself, which allows session management.
- Type:
counter
num_manifests
Number of cached manifests.
- Type:
gauge
- Labels:
count
- state of manifest in cache, can be eitherlru
,evicted
ortotal
.
num_qoe_losses
Number of “lost” QoE decisions per CDN.
- Type:
counter
- Labels:
cdn_id
- ID of CDN that loose QoE battle.cdn_name
- name of CDN that loose QoE battle.selector
- whether the decision was taken duringinitial
orinstream
selection.
num_qoe_wins
Number of “won” QoE decisions per CDN.
- Type:
counter
- Labels:
cdn_id
- ID of CDN that won QoE battle.cdn_name
- name of CDN that won QoE battle.selector
- whether the decision was taken duringinitial
orinstream
selection.
num_rejected_requests
Deprecated, should always be at 0.
- Type:
counter
- Labels:
selector
- whether the request was counted duringinitial
orinstream
selection.
num_requests
Total number of requests received by the router.
- Type:
counter
- Labels:
selector
- whether the request was counted duringinitial
orinstream
selection.
num_sessions
Number of sessions opened on router.
- Type:
gauge
- Labels:
state
- eitheractive
orinactive
.type
- one of:initial
,instream
,qoe_on
,qoe_off
,qoe_agent
orsp_agent
.
num_ssl_errors_total
Number of all errors logged during TLS connections, both incoming and outgoing.
- Type:
counter
num_ssl_warnings_total
Number of all warnings logged during TLS connections, both incoming and outgoing.
- Type:
counter
- Labels:
category
- which kind of TLS connection triggered the warning. Can be one of:cdn
,content
,generic
,repeated_session
or empty.
num_unhandled_requests
Number of requests for which no CDN could be found.
- Type:
counter
- Labels:
selector
- whether the request was counted duringinitial
orinstream
selection.
num_unmanaged_redirects
Number of redirects to “outside” the router - usually to CDN.
- Type:
counter
- Labels:
cdn_id
- ID of CDN picked for redirection.cdn_name
- name of CDN picked for redirection.selector
- whether the redirect was result ofinitial
orinstream
selection.
num_valid_http_requests
Number of received requests that were not deemed invalid, see
num_invalid_http_requests
.
- Type:
counter
- Labels:
source
- name of internal filter function that classified request as invalid. Probably not of much use outside debugging.type
- whether the request was HTTP (Unencrypted
) or HTTPS (SSL
).
orc_latency_bucket
Total number of responses sorted into “latency buckets” - labels denoting latency interval.
- Type:
counter
- Labels:
le
- latency bucket that given response falls into.orc_status_code
- HTTP status code of given response.
orc_latency_count
Total number of responses.
- Type:
counter
- Labels:
tls
- whether the response was sent via SSL/TLS connection or not.orc_status_code
- HTTP status code of given response.
ssl_certificate_days_remaining
Number of days until a SSL certificate expires.
- Type:
gauge
- Labels:
domain
- the common name of the domain that the certificate authenticates.not_valid_after
- the expiry time of the certificate.not_valid_before
- when the certificate starts being valid.usable
- if the certificate is usable to the router, see the ssl_certificate_usable_count metric for an explanation.
ssl_certificate_usable_count
Number of usable SSL certificates. A certificate is usable if it is valid and authenticates a domain name that points to the router.
- Type:
gauge
2.1.1.8.7.1 - Internal Metrics
A subrunner is an internal module of ESB3024 Router which handles routing requests. The subrunner metrics are technical and mainly of interest for Agile Content. These metrics will be briefly described here.
subrunner_async_queue
Number of queued events per subrunner, roughly corresponding to load.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_client_conns
Number of currently open client connections per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_high_queue
Number of high priority events queued per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_io_autopause_sockets
Number of sockets that have been automatically paused. This happens when the work manager is under heavy load.
- Type:
counter
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_io_send_data_fast_attempts
A fast data path was added that in many cases increases the performance of the router. This metric was added to verify that the fast data path is taken.
- Type:
counter
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_io_wakeups
The number of times a subrunner has been waken up from sleep.
- Type:
counter
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_low_queue
Number of low priority events queued per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_max_async_queue
Maximum number of events waiting in queue.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_max_high_queue
Maximum number of events waiting in high priority queue.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_max_low_queue
Maximum number of events waiting in low priority queue.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_max_medium_queue
Maximum number of events waiting in medium priority queue.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_medium_queue
Number of medium priority events queued per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_times_worker_overloaded
Number of times when queued events for given subrunner exceeded
the tuning.overload_threshold
value (defaults to 32).
- Type:
counter
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_total_receive_data_blocks
Number of receive data blocks allocated per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_total_send_data_blocks
Number of send data blocks allocated per subrunner.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_used_receive_data_blocks
Number of receive data blocks currently in use per subrunner. Same as subrunner_total_receive_data_blocks.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
subrunner_used_send_data_blocks
Number of send data blocks currently in use per subrunner. Same as subrunner_total_send_data_blocks.
- Type:
gauge
- Labels:
subrunner_id
- ID of given subrunner.
2.1.1.9 - Releases
2.1.1.9.1 - Release esb3024-1.14.2
Build date
2024-10-01
Release status
Type: production
Breaking changes
- If upgrading from a release prior to 1.10.0, the Director needs to be upgraded to 1.10.0, 1.10.1 or 1.10.2 before installing 1.14.2. See Installing a 1.14 release for more information.
- In esb3024-1.14.0, the configuration setting
services.routing.settings.allowedProxies
has been renamed toservices.routing.settings.trustedProxies
and has changed default behavior. If empty, proxy connections are now denied by default. See Trusted proxies for more information. - Starting with esb3024-1.14.0, a minimum CPU architecture level of x86-64-v2 is required. See system requirements below for more information.
Change log
- NEW: Define
custom_capacity_var
as a number inhost_has_bw_custom()
. Using a selection input variable forcustom_capacity_var
is no longer necessary. [ESB3024-1119] - FIXED: Predictive load balancing functions do not handle missing interface [ESB3024-1100]
- FIXED: Client closing socket can cause proxy IP to resolve to “?” [ESB3024-1139]
- FIXED: ACD crashes when attempting to read corrupt cached data. The cached data can become corrupt if the filesystem is manipulated by a user or the system runs out of storage. [ESB3024-1147]
- FIXED: Subnets are not being persisted to disk [ESB3024-1149]
- FIXED: ACD overwrites custom GeoIP MMDB files with the default shipped MMDB files when upgrading [ESB3024-1150]
Deprecations
- From esb3024-1.14.0, the grafana-loki and fluentbit containers have been deprecated and are no longer installed with the system. Previously installed containers may be manually stopped and removed if not used, but they will not be uninstalled automatically.
System Requirements
- Starting with esb3024-1.14.0 the ACD Router now requires a minimum CPU architecture level of x86-64-v2 due to inclusion of Oracle Linux 9 inside the container. While all modern CPUs support this archetecture level, virtual hypervisors may default to a CPU type that has more compatibility with older processors. If this minimum CPU architecture level is not attained the containers may refuse to start. See Operating System Compatibility and Building Red Hat Enterprise Linux 9 for the x86-64-v2 Microarchitecture Level for more information.
Known Limitations
- The GUI is not working for this release.
- The Telegraf metrics agent might not be able to read all relevant network
interface data on some releases of ESB2001. The predictive load balancing
function
host_has_bw()
and the health check functioninterfaces_online()
might therefore not work as expected.- The recommended workaround for
host_has_bw()
is to usehost_has_bw_custom()
, documented in Built-in Lua functions.host_has_bw_custom()
accepts a numeric argument for the host’s network interface capacity which can be used if the data supplied by the Telegraf metrics agents do not contain this information. - It is not recommended to use
interfaces_online()
until the issue is resolved on ESB2001.
- The recommended workaround for
2.1.1.9.2 - Release esb3024-1.14.0
Build date
2024-09-03
Release status
Type: production
Breaking changes
If upgrading from a release prior to 1.10.0, the Director needs to be upgraded to 1.10.0, 1.10.1 or 1.10.2 before installing 1.14.0. See Installing an 1.14 release for more information.
In esb3024-1.14.0, the configuration setting
services.routing.settings.allowedProxies
has been renamed toservices.routing.settings.trustedProxies
and has changed default behavior. If empty, proxy connections are now denied by default. See Trusted proxies for more information.Starting with esb3024-1.14.0, a minimum CPU architecture level of x86-64-v2 is required. See system requirements below for more information.
Change log
- NEW: Remove grafana-loki and fluentbit containers [ESB3024-774]
- NEW: Extend
num_endpoint_requests
metric with host ID [ESB3024-975] - NEW: Improved subnets endpoint. See API overview documentation for details. [ESB3024-1018]
- NEW: Support RHEL-9 / OL9 [ESB3024-1022]
- NEW: Support OpenSSL 3 [ESB3024-1025]
- NEW: Changed the router base image to oracle linux 9. See breaking changes [ESB3024-1034]
- NEW: Rename allowedProxies to trustedProxies [ESB3024-1085]
- NEW: Deny proxy connections by default if trustedProxies is empty [ESB3024-1088]
- FIXED: Too long classifier name crashes confd-transformer [ESB3024-949]
- FIXED: Lua condition si() doesn’t handle boolean values [ESB3024-1017]
- FIXED: Classifiers of type stringMatcher and regexMatcher can’t use content query params as source [ESB3024-1032]
- FIXED: ConsistentHashing algorithm is not content aware [ESB3024-1053]
- FIXED: Large configurations fail to apply. The REST API max body size is now configurable. [ESB3024-1056]
- FIXED: Convoy-bridge DB connection failure spams logs [ESB3024-1080]
- FIXED: Convoy-bridge does not send correctly formatted session-id [ESB3024-1081]
- FIXED: Response translation removes message body [ESB3024-1082]
Deprecations
- From esb3024-1.14.0, the grafana-loki and fluentbit containers have been deprecated and are no longer installed with the system. During upgrade these containers may manually be stopped and removed if not used.
System Requirements
- Starting with esb3024-1.14.0 the ACD-Router now requires a minimum CPU architecture level of x86-64-v2 due to inclusion of Oracle Linux 9 inside the container. While all modern CPUs support this archetecture level, virtual hypervisors may default to a CPU type that has more compatibility with older processors. If this minimum CPU architecture level is not attained the containers may refuse to start. See Operating System Compatibility and Building Red Hat Enterprise Linux 9 for the x86-64-v2 Microarchitecture Level for more information.
Known Limitations
The GUI is not working for this release.
The Telegraf metrics agent might not be able to read all relevant network interface data on some releases of ESB2001. The predictive load balancing function
host_has_bw()
and the health check functioninterfaces_online()
might therefore not work as expected.- The recommended workaround for
host_has_bw()
is to usehost_has_bw_custom()
, documented in Built-in Lua functions. A manual integration of setting a custom selection input variable representing the network interface capacity and using this inhost_has_bw_custom()
is necessary. See API Overview for details on using the selection input API. to usehost_has_bw_custom()
- The recommended workaround for
interfaces_online()
is to not use the function until the issue is resolved.
- The recommended workaround for
2.1.1.9.3 - Release esb3024-1.12.1
Build date
2024-07-03
Release status
Type: production
Breaking changes
If upgrading from a release prior to 1.10.0, the Director needs to be upgraded to 1.10.0, 1.10.1 or 1.10.2 before installing 1.12.1. See Installing an 1.12 release for more information.
Change log
- NEW: Remove support for EL7 [ESB3024-1046]
- FIXED: Large configuration causes crash [ESB3024-1043]
Known Limitations
The GUI is not working for this release.
2.1.1.9.4 - Release esb3024-1.12.0
Build date
2024-06-19
Release status
Type: production
Breaking changes
If upgrading from a release prior to 1.10.0, the Director needs to be upgraded to 1.10.0, 1.10.1 or 1.10.2 before installing 1.12.0. See Installing release 1.12.0 for more information.
Change log
- NEW: Move managed session creation to Lua. Creating managed sessions is now handled by using the session translation function. [ESB3024-454]
- NEW: Grafana dashboards to monitor Quality [ESB3024-511]
- NEW: Measure and expose quality scores. A quality score per host and session group is now available when making routing decisions. [ESB3024-512]
- NEW: Add default session classifiers. When resetting the list of classifiers in confd, it is now populated with commonly used classifers. [ESB3024-769]
- NEW: Add configuration migration tool [ESB3024-824]
- NEW: Add new Random classifier [ESB3024-899]
- NEW: Add URL parsing code to Lua library. An URL parser based on https://github.com/golgote/neturl/ with extensions for path splitting and joining [ESB3024-936]
- NEW: Standard library Lua functions now use the same log mechanism as the Director [ESB3024-966]
- NEW: Extend ’num_sessions’ metric to include a label with the selected host [ESB3024-973]
- NEW: Add quality level metrics [ESB3024-974]
- NEW: Add host request translation function [ESB3024-996]
- FIXED: ConsistentHashing Algorithm only supports MD5. MD5, SDBM and Murmur are now supported. [ESB3024-929]
- FIXED: Confd IPv4 validation rejects IPs with /29 netmask [ESB3024-1010]
- FIXED: Stale timestamped selection input not being pruned. Added configurable timestamped selection input timeout limit. [ESB3024-1016]
Known Limitations
The GUI is not working for this release.
2.1.1.9.5 - Release esb3024-1.10.2
Build date
2024-06-03
Release status
Type: production
Breaking changes
If upgrading from a release prior to 1.10.0, the configuration needs to be manually updated after upgrading to 1.10.2. See Installing release 1.10.x for more information.
Change log
- FIXED: ConsistentHashing rule broken [ESB3024-969]
- FIXED: Increase configuration size limit [ESB3024-983]
Known Limitations
None
2.1.1.9.6 - Release esb3024-1.10.1
Build date
2024-04-18
Release status
Type: production
Breaking changes
If upgrading from a release prior to 1.10.0, the configuration needs to be manually updated after upgrading to 1.10.1. See Installing release 1.10.x for more information.
Change log
- NEW: Change predictive load balancing functions to use megabits/s [ESB3024-932]
- FIXED: Logic classifier statements can consume all memory [ESB3024-937]
Known Limitations
None
2.1.1.9.7 - Release esb3024-1.10.0
Build date
2024-04-02
Release status
Type: production
Breaking changes
The configuration needs to be manually updated after upgrading to 1.10.0. See Installing release 1.10.0 for more information.
Change log
- NEW: Use metrics from streamers in routing decisions. Added standard library Lua support to use hardware metrics in routing decisions. Added host health checks in the configuration. [ESB3024-154]
- NEW: Remove unused field “apiKey” from configuration [ESB3024-426]
- NEW: Support integration with Convoy Analytics [ESB3024-694]
- NEW: Support combining classifiers using AND/OR in session groups [ESB3024-776]
- NEW: Enable access logging by default [ESB3024-816]
- NEW: Improved Lua translation function error handling [ESB3024-874]
- NEW: Updated predictive load balancing functions to support hardware metrics [ESB3024-887]
- NEW: Remove apiKey from documentation [ESB3024-927]
- FIXED: Condition with ‘or’ statement sometimes generate faulty Lua [ESB3024-863]
Known Limitations
None
2.1.1.9.8 - Release esb3024-1.8.0
Build date
2024-02-07
Release status
Type: production
Breaking changes
The configuration needs to be manually updated after upgrading to 1.8.0. See Installing release 1.8.0 for more information.
Change log
- NEW: Remove ESB3026 Account Monitor from installer. [ESB3024-354]
- NEW: Improve selection input endpoint flexibility and security. See API overview documentation for details. [ESB3024-423]
- NEW: Support anonymous geoip rules [ESB3024-699]
- NEW: Add ASN IDs list classifiers to confd [ESB3024-778]
- NEW: Enable content popularity tracking by default. Added option to enable/disable in confd/confcli. [ESB3024-781]
- NEW: Remove dependency on session from security token verification [ESB3024-809]
- FIXED: A lot of JSON output on failed routing. HTTP response no longer contains internal routing information. [ESB3024-523]
- FIXED: Returning Lua table from Lua debug endpoint can crash router. Selection Input values now support floating point values in a Lua context [ESB3024-691]
- FIXED: Floating point selection inputs are truncated to ints when passed to Lua context [ESB3024-710]
- FIXED: Race condition between
RestApi
andSession
[ESB3024-753] - FIXED: confd/concli doesn’t support “forward_host_header” on hostGroups [ESB3024-761]
- FIXED: Support Lua vector keys in reverse order [ESB3024-780]
Known Limitations
None
2.1.1.9.9 - Release esb3024-1.6.0
Build date
2023-12-20
Release status
Type: production
Breaking changes
The configuration needs to be manually updated after upgrading to 1.6.0. See configuration changes between 1.4.0 and 1.6.0 for more information.
Change log
- NEW: Remove the
lua_paths
array from the config . Lua scripts are now added using a REST API on the/v1/lua/
endpoint. [ESB3024-204] - NEW: Separate “account-monitor” from installer [ESB3024-238]
- NEW: Consistent hashing based routing . Added support for content distribution control for load balancing and cache partitioning [ESB3024-274]
- NEW: Predictive load balancing . Account for in-transit traffic to prevent cache overload when there is a sudden burst of new sessions. [ESB3024-275]
- NEW: Support Convoy security tokens [ESB3024-386]
- NEW: Expose quality, host and session ID in the session object in Lua context [ESB3024-429]
- NEW: Support upgrade of system python in installer [ESB3024-442]
- NEW: Do not configure selinux and firewalld in installer [ESB3024-493]
- NEW: Convoy Distribution/Account integration [ESB3024-503]
- NEW: Make eDNS server port configurable . The router configuration
hosts.proxy_address
has been renamed tohosts.proxy_url
and now accepts a port that is used when connecting to the proxy. Thecdns.http_port
andcdns.https_port
configurations now configure the port that is used for connecting to the EDNS server, before they configured the port that was used for connecting to the proxy. [ESB3024-509] - NEW: Expand node table in Lua context . New fields are:
node.id
,node.visits
,host.id
,host.recent_selections
[ESB3024-630] - FIXED: DNS lookup can fail . DNS lookup can fail when same content requested from both IPv4 and IPv6 clients [ESB3024-427]
- FIXED: Failed DNS requests are not retried . Fixed bug where failed eDNS requests were not retried [ESB3024-504]
- FIXED: Lua functions are not updated when uploaded [ESB3024-544]
- FIXED: Undefined metatable fields evaluate to
false
rather thannil
[ESB3024-642] - FIXED:
Evaluator::evaluate()
doesn’t support different types of its variadic arguments [ESB3024-687] - FIXED: Segfault when accessing REST api with empty path [ESB3024-752]
- FIXED: Container UID/GID may change between versions [ESB3024-755]
2.1.1.9.10 - Release esb3024-1.4.0
Build date
2023-09-29
Release status
Type: production
Breaking changes
- All configuration is now stored under /opt/edgeware/acd, see [ESB3024-425]. Any configuration that is to be kept needs to be manually migrated.
Typically/opt/edgeware/etc/confd/store/store.json
needs to be copied to/opt/edgeware/acd/confd/store/store.json
,/opt/edgeware/var/lib/acd-router/cached-acd-router-config.json
needs to be copied to/opt/edgeware/acd/router/cache/config.json
and/opt/edgeware/var/lib/acd-router/cached-router-rest-api-key.json
needs to be copied to/opt/edgeware/acd/router/cache/rest-api-key.json
. Custom Lua functions need to be migrated from/opt/edgeware/acd/var/lib/custom_lua
to/opt/edgeware/acd/router/lib/custom_lua
. The Prometheus and Grafana configurations also need to be copied if they have been modified.
The following changes were made to the confcli configuration [ESB3024-455]. - The
rule
fields inside the routing rule items were renamed tocondition
to avoid confusion with therules
list. This applies to the blocksallow
,deny
,split
andweighted
. - The
popularityThreshold
in thecontentPopularity
routing rule was renamed tocontentPopularityCutoff
.
Change log
- NEW: 1-Page Status Report . Added command
ew-sysinfo
that can be used on any machine with an ESB3024 installation. The command outputs various information about the system and installed services which can be used for monitoring and diagnostics. [ESB3024-391] - NEW: Update routing rule property names . Routing rule property names updated for consistency and clarity [ESB3024-455]
- FIXED: Deleting confd API array element inside oneOf object fails [ESB3024-355]
- FIXED: Container logging not captured by
systemd
until services are restarted [ESB3024-359] - FIXED: Alertmanager restricts the configuration to a single file [ESB3024-381]
- FIXED: Split rules in routing configuration should terminate on error [ESB3024-420]
- FIXED: Improve alert configuration in Prometheus [ESB3024-422]
- FIXED: Inconsistent storage paths of service configuration and data [ESB3024-425]
- FIXED: confd-transformer is not working in el7 [ESB3024-430]
2.1.1.9.11 - Release acd-router-1.2.3
Build date
2023-08-16
Release status
Type: production
Breaking changes
None
Change log
- NEW: Add more classifiers . New classifiers are
hostName
,contentUrlPath
,userAgent
,contentUrlQueryParameters
[ESB3024-298] - NEW: Add allow- and denylist rule blocks [ESB3024-380]
- NEW: Add enhanced validation of scriptable field in routing rules [ESB3024-393]
- NEW: Add
services
to the config tree [ESB3024-410] - NEW: Prohibit unknown configuration properties [ESB3024-416]
- FIXED: Duplicate session group IDs are allowed [ESB3024-49]
- FIXED: Invalid URL returned for IPv4 requests when using a DNS backend [ESB3024-374]
- FIXED: Not possible to set log level in eDNS proxy [ESB3024-378]
- FIXED: Instream selection fails when DASH manifest has template paths using “../” [ESB3024-384]
2.1.1.9.12 - Release acd-router-1.2.0
Build date
2023-06-27
Release status
Type: production
Breaking changes
None
Change log
- NEW: Add meta fields to the configuration . The API now allows the meta data fields “created_at”, “source” and “source_checksum” that can be used for the API consumer to track who did what change when.
- NEW: Control routing behavior based on backend response code . This gives control over when to return backend response codes to the end user and when to trigger a failover to another CDN or host.
- NEW: Manage Lua scripts via API
- NEW: Support popularity-based routing . Content can be ordered in multiple groups with descending popularity. Popularity can also be tracked per session group.
- NEW: Improved support for IPv6 routing . It is now possible to select backend depending on the IP protocol version.
- NEW: Add DNS backend support . This allows delegating routing decisions to an EDNS0 server.
- NEW: Support HMAC with SHA256 in Lua scripts
- NEW: Add alarm support . The alarms are handled by Prometheus and Alertmanager.
- NEW: Support saving Grafana Dashboards
- NEW: Add simplified configuration API and CLI tool . A new configuration API with an easier to use model has been added. The “confcli” tool present in many other Edgeware products is now supported.
- NEW: Add authentication to the REST API
- FIXED: Host headers not forwarded to Request Router when ‘redirecting: true’ is enabled
- FIXED: IP range classifier 0.0.0.0/0 does not work in session groups
2.1.1.9.13 - Release acd-router-1.0.0
Build date
2022-11-22
Release status
Type: First production release
Known Limitations
The setting “allowed_clients” should not be used since the functionality does not work as expected.
Change log
- Flexible routing rule engine with support for Lua plugins. Support many use cases, including CDN Offload and CDN Selection.
- Advanced client classification mechanisms for routing based on group memberships (device type, content type, etc).
- Geobased routing including dedicated high-performing API for subnet matching, associating an incoming request with a region.
- Integration API to feed the service with arbitrary variables to use for routing decisions. Can be used to get streaming bitrate in public CDNs, status from network probes, etc.
- Flexible request/response translation manipulation on the client facing interface. Can be used for URL manipulation, encoding/decoding tokens or adapting the interface to e.g. the PowerDNS backend protocol.
- Metrics API that can be monitored with standard monitoring software. Out-of-the-box integration with Prometheus and Grafana.
- Robust deployment with each service instance running independently, and allowing the service to stay in operational state even when backends become temporarily unavailable.
- RHEL 7/8 support.
- Online documentation at https://docs.agilecontent.com/
2.1.1.10 - Glossary
- ACD
- Agile CDN Director. See “Director”.
- Confd
- A backend service that hosts the service configuration. Comes with an API, a CLI and a GUI.
- Classifier
- A filter that associate a request with a tag that can be used to define session groups.
- Director
- The Agile Delivery OTT router and related services.
- ESB
- A software bundle that can be separately installed and upgraded, and is released as one entity with one change log. Each ESB is identified with a number. Over time, features and functions within an ESB can change.
- Lua
- A widely available scripting language that is often used to extend the capabilities of a piece of software.
- Router
- Unless otherwise specified, an HTTP router that manages an OTT session using HTTP redirect. There are also ways to use DNS instead of HTTP.
- Selection Input API
- Data posted to this API can be accessed by the routing rules and hence influence the routing decisions.
- Subnet API
- An API to define mappings between subnets and names (typically regions) for those subnets. Routing rules can then refer to the names rather than the subnets.
- Session Group
- A handle on a group of requests, defined via classifiers.
2.1.2 - ESB3032 ACD Aggregator
2.1.2.1 - Getting Started
The account aggregator is a service responsible for monitoring various input streams, compiling and aggregating statistics, and selectively reporting to one or more output streams. It acts primarily as a centralized collector of metrics which may have various aggregations applied before being published to one or more endpoints.
Modes of operation
There are two primary modes of operation, a live-monitoring mode, as well as a reporting mode. The live-monitoring mode measures the account records in real-time, filters, and aggregates the data to the various outputs in real-time. In this mode, only the most recent data will be considered, and any historical context upon startup may be skipped. In the reporting mode, the account record data will be consumed and processed in the order in which they were published to Kafka, and the service will guarantee that all records, still available within the Kafka topic will be processed and reported upon.
Activating the various modes of operation is performed by way of the set of
input
and output
blocks within the configuration file. The file may
contain one or more input
blocks which specify where the data is sourced,
e.g. account records from Kafka, and one or more output
blocks which
determine how and where the aggregated statistics are published.
While it is possible to specify multiple input
and output
blocks within
a single configuration file, it is highly recommended to separate each pairing
of input
and output
blocks into separate instances running on different
nodes. This will yield the best performance and provide for better load
balancing, since each instance will be responsible for a single mode of
operation.
Real-time account monitoring
In the real-time account monitoring mode, account records, which are sent from each streaming server through the Kafka message broker, are processed by the account aggregator, and current real-time throughput metrics are updated in a Redis database. These metrics, which are constantly being updated, reflect the most current state of the CDN, and can be used by the Convoy Request Router to make real-time routing decisions.
PCX Reporting
In the PCX collector mode, account records are consumed in such a way that past throughput and session statistics can be aggregated to produce billing related reports. These reports are not considered real-time metrics, but represent usage statistics over fixed time intervals. This mode of operation requires a PCX API compatible reporting endpoint. See Appendix B for additional information regarding the PCX reporting format.
Installation
Prerequisites
The account aggregator is shipped as a compressed OCI formatted container image and as such, it requires a supported container runtime such as one of the following:
- Docker
- Podman
- Kubernetes
Any runtime capable of running a Linux container should work the same. For simplicity, the following installation instructions assume that Docker is being used, and that Docker is already configured and running on the target system.
To test that Docker is setup and running, and that the current user has the required privileges to create a container, you may execute the following command.
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
If you get a permission denied error, ensure that the current user is a member
of the docker
group or execute all Docker commands under sudo
.
Loading the container image
The container image is delivered as a compressed OCI formatted image, which
can be loaded directly via the docker load
command. The following assumes
that the image is in /tmp/esb3032-acd-aggregator-0.0.0.gz
docker load --input /tmp/esb3032-acd-aggregator-0.0.0.gz
You will now be able to verify that the image was loaded successfully by executing the following and looking for the image name in the output.
$ docker images | grep acd-aggregator
images.edgeware.tv/esb3032-acd-aggregator latest 4bbe28b444d3 1 day ago 2.08GB
Creating the configuration file
The configuration file may be located anywhere on the filesystem, however
it is recommended to keep everything under the /opt/edgeware/acd/aggregator
folder to be consistent with other products under the ACD product family.
If that folder doesn’t already exist, you may create the folder with the
following command.
mkdir -p /opt/edgeware/acd/aggregator
If using a different location, you will need to map the folder to the container while creating the Docker container. Additional information describing how to map the volume is available in the section “Creating and starting the container” below.
The configuration file for the account aggregator is divided into several
sections, input
, output
and tuning
. One or more input
blocks may
be specified to configure from where the data should be sourced. One or
more output
blocks may be configured which determine to where the resulting
aggregated data is published. Finally the tuning
block configures various
global settings for how the account aggregator operates, such as the global
log_level
.
Configuring the input source
As of the current version of the account aggregator, there is only a single
type of input source supported, and that is account_records
. This input
source connects to a Kafka message broker, and consumes account records.
Depending on which output types are configured, the Kafka consumer may either
start by processing the oldest or most recent records first.
The following configuration block sample will be used as an example in the description below.
Note that the key input
is surrounded by double-square-brackets. This is
a syntax element to indicate that there may be multiple input
sections in
the configuration.
[[input]]
type = "account_records"
servers = [
"kafka://192.0.2.1:9092",
"kafka://192.0.2.2:9092",
]
group_name = "acd-aggregator"
kafka_max_poll_interval_ms = 30000
kafka_session_timeout_ms = 3000
log_level = "off"
The type
property is used to determine the type of input, and the only
valid value is account_records
.
The servers
list must contain at least 1 Kafka URL, prefixed with the
URL scheme kafka://
. If not specified, the default Kafka port of 9092
will be used. It is recommended but not required to specify all servers
here, as the Kafka client library will obtain the full list of endpoints
from the server on startup, however, the initial connection will be made
to one or more of the provided URLs.
The group_name
property identifies to which consumer group the aggregator
should belong. Due to the type of data which account records represent, each
instance of the aggregator connecting to the same Kafka message broker
MUST have a unique group name. If two instances belong to the same group,
the data will be partitioned among both instances, and the resulting
aggregations may not be correct. If only a single instance of the account
aggregator is used, this property is optional and defaults to “acd-aggregator”.
The kafka_*
properties, for max_poll_interval
and session_timeout
are
used to tune the connection parameters for the internal Kafka consumer. More
details for these properties can be found in the documentation for the
rdkafka
library. See Kafka documentation
for more details.
The log_level
property configures the logging level for the Kafka library
and supports the values “off”, “trace”, “debug”, “info”, “warn”, and “error”.
By default, logging from this library is disabled. This should only be
enabled for troubleshooting purposes, as it is extremely verbose, and any
warnings or error messages will be repeated in the account aggregator’s log.
The logging level for the Kafka library must be higher then the general
logging level for the aggregator, as defined in the “tuning” section or the
lower-level messages from the Kafka library will be skipped.
Configuring output
The account aggregator currently supports two types of output blocks, depending on the desired mode of operation. For reference purposes, both types will be described within this section, but it is recommended to only use a single type per instance of the account aggregator.
Note that the key output
is surrounded by double-square-brackets. This is
a syntax element to indicate that there may be multiple output
sections in
the configuration.
[[output]]
type = "account_monitor"
redis_servers = [
"redis://192.0.2.7:6379/0",
"redis://:password@192.0.2.8:6379/1",
]
stale_threshold_s = 12
throughput_correction_mbps = 0
minimum_check_interval_ms = 1000
[[output]]
type = "pcx_collector"
report_url = "https://192.0.2.5:8000/v1/collector"
client_id = "edgeware"
secret = "abc123"
report_timeout_ms = 2000
report_interval_s = 30
report_delay_s = 30
Real-time account monitor output
The first output block has the type account_monitor
and represents the
live account monitoring functionality, which publishes per-account bandwidth
metrics to one or more Redis servers. When this type of output
block is
configured, the account records will be consumed starting with the most
recent messages first, and offsets will not be committed. Stopping or
restarting the service may cause account records to be skipped. This type
of output
is suitable for making real-time routing decisions, but should
not be relied upon for critical billing or reporting metrics.
The redis_servers
list consists of URLs to Redis instances which shall be
updated with the current real-time bandwidth metrics. If the Redis instance
requires authentication, the global instance password can be specified as part
of the URL as in the second entry in the list. Since Redis does not support
usernames, anything before the :
in the credentials part of the URL will
be ignored. At least 1 Redis URL must be provided.
The stale_threshold_s
property determines the maximum timeout in seconds,
after which, if no account records have been received for a given host,
the host will be considered stale and removed.
The throughput_correction_mbps
property can be used to add or subtract a
fixed correction factor to the bandwidth reported in Redis. This is specified
in megabits per second, and this may be either positive or negative. If
the value is negative, and the calculated bandwidth is less than the correction
factor, a minimum bandwidth of 0 will be reported.
The minimum_check_interval_ms
property is used to throttle how frequently
the statistics will be processed. By default, the account aggregator will not
recalculate the statistics more than once per second. Setting this value too
low will result in potentially higher CPU usage, while setting it too high may
result in some account records being missed. The default of 1 second should
be adequate for most situations.
PCX Collector output
The pcx_collector
type configures the account aggregator as a reporting
agent for the PCX API. Whenever this configuration is present, the account
record consumer will be configured to always start at the oldest records
retained within the Kafka topic. It then processes the records one at a time,
committing the Kafka offset each time a report is successfully received.
This mode does not make any guarantees as to how recent the data is on which
the reports are made, but does guarantee that every record will be counted
in the aggregated report. Stopping or restarting the service will result in
the account record consumer resuming processing from the last successful
report. This type of reporting is suitable for billing purposes assuming
that there are multiple replicated Kafka nodes, and that the service is not
stopped for longer than the maximum retention period configured within
Kafka. Stopping the service for longer than the retention period will result
in messages being unavailable. Because this type of output
requires that
the Kafka consumer is processed in a specific order, and will not proceed
with reading additional messages until all reports have been successfully
received, it is not recommended to have both pcx_collector
and the
account_monitor
type output
blocks configured within the same instance.
The report_url
property is a single HTTP endpoint URL where the PCX API
can be reached. This property is required and may be either an HTTP or HTTPS
URL. For HTTPS, the validity of the TLS certificate will be enforced, meaning
that self-signed certificates will not be considered valid.
The client_id
and secret
fields are used to authenticate the client with
the PCX API via token-based authentication. These fields are both required,
however if not used by the specific PCX API instance, the empty string ""
may be provided.
The report_timeout_ms
field is an optional maximum timeout for the HTTP
connection to the PCX API before the connection will fail. Failed reports
will be retried indefinitely.
The report_interval_s
property represents the interval bucket size for
reporting metrics. The timing for this type of output
is based solely
on the embedded timestamp
value of the account records, meaning that this
property is not an absolute period on which the reports will be sent, but
instead represents the duration between the start and ending timestamps of
the report. Especially upon startup, reports may be sent much more frequently
than this interval, but will always cover this duration of time.
The report_delay_s
property is an optional offset used to account for both
clock synchronization between servers as well as propagation delay of the
account records through the message broker. The default delay is 30 seconds.
This means that the ending timestamp of a given report will be no more recent
than this many seconds in the past. It is important to include this delay, as
any account records received with a timestamp that would be within period which
has already been reported upon, will be dropped.
Tuning the account aggregator
The tuning
configuration block represents the global properties for tuning
how the account aggregator functions. Currently only one tuning property
can be configured, and that is the log_level
. The default log_level
is
“info”, which should be used in normal operation of the account aggregator,
however, other possible values in order of verbosity include “trace”,
“debug”, “info”, “warn”, “error”, and “off”.
Note that the tuning
key is surrounded by single square-brackets. This is
TOML syntax meaning that only one instance of tuning
is allowed.
[tuning]
log_level = "info"
Example configurations
This section describes some example configuration files which can be used as a starting template depending on which mode of operation is desired.
Real-time account monitoring
This configuration will consume account records from a Kafka server running on 3 hosts, kafka-1, kafka-2, and kafka-3. The account records will be consumed starting with the most recent records. The resulting aggregations will be published to two Redis instances, running on redis-1 and redis-2. The reported bandwidth will have a 2Gb/s correction factor applied.
[[input]]
type = "account_records"
servers = [
"kafka://kafka-1:9092",
"kafka://kafka-2:9092",
"kafka://kafka-3:9092"
]
group_name = "acd-aggregator-live"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"
[[output]]
type = "account_monitor"
redis_servers = [
"redis://redis-1:6379/0",
"redis://redis-2:6379/0",
]
# stale_threshold_s = 12
throughput_correction_mbps = 2000
# minimum_check_interval_ms = 1000
[tuning]
log_level = "info"
The keys prefixed by #
are commented out, since the default values will
be used. They are included in the example for completeness.
PCX collector
This configuration will consume account records starting from the earliest
record, calculate aggregated statistics for every 30 seconds, offset with
a delay of 30 seconds, and publish the results to
https://pcx.example.com/v1/collector
.
[[input]]
type = "account_records"
servers = [
"kafka://kafka-1:9092",
"kafka://kafka-2:9092",
"kafka://kafka-3:9092"
]
group_name = "acd-aggregator-pcx"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"
[[output]]
type = "pcx_collector"
report_url = "https://pcx.example.com/v1/collector"
client_id = "edgeware"
secret = "abc123"
# report_timeout_ms = 2000
# report_interval_s = 30
# report_delay_s = 30
[tuning]
log_level = "info"
The keys prefixed by #
are commented out, since the default values will
be used. They are included in the example for completeness.
Combined PCX collector with real-time account monitoring
While this configuration is possible, it is not recommended, since the
pcx_collector
output
type will force all records to be consumed starting
at the earliest record. This will cause the live statistics to be delayed
until ALL earlier records have been consumed, and reports have been
successfully accepted by the PCX API. This combined role configuration can be
used to minimize the number of servers or services running if the above
limitations are acceptable.
Note: This is simply the combination of the above two output
blocks in the
same configuration file.
[[input]]
type = "account_records"
servers = [
"kafka://kafka-1:9092",
"kafka://kafka-2:9092",
"kafka://kafka-3:9092"
]
group_name = "acd-aggregator-combined"
# kafka_max_poll_interval_ms = 30000
# kafka_session_timeout_ms = 3000
# log_level = "off"
[[output]]
type = "account_monitor"
redis_servers = [
"redis://redis-1:6379/0",
"redis://redis-2:6379/0",
]
# stale_threshold_s = 12
throughput_correction_mbps = 2000
# minimum_check_interval_ms = 1000
[[output]]
type = "pcx_collector"
report_url = "https://pcx.example.com/v1/collector"
client_id = "edgeware"
secret = "abc123"
# report_timeout_ms = 2000
# report_interval_s = 30
# report_delay_s = 30
[tuning]
log_level = "info"
Upgrading
The upgrade procedure for the aggregator consists of simply stopping
the existing container with docker stop acd-aggregator
, removing the
existing container with docker rm acd-aggregator
, and following the
steps in “Creating and starting the container” below with the upgraded
Docker image.
To roll back to a previous version, simply perform the same steps with the
previous image. It is recommended to keep at least one previous image
around until such time that you are satisfied with the new version. After
which, you may remove the previous image with
docker rmi images.edgeware.tv/esb3032-acd-aggregator:1.2.3
where “1.2.3”
represents the previous version number.
Creating and starting the container
Now that the configuration file has been created, and the image has been
loaded, we will need to create and start the container instance. The
following docker run
command will create a new container called
“acd-aggregator”, start the process, and automatically resume the container
once the Docker daemon is loaded at startup.
docker run \
--name "acd-aggregator" \
--detach \
--restart=always \
-v <PATH_TO_CONFIG_FOLDER>:/opt/edgeware/acd/aggregator:ro \
<IMAGE NAME>:<VERSION> \
--config /opt/edgeware/acd/aggregator/aggregator.toml
As an example using version 1.4.0:
docker run \
--name "acd-aggregator" \
--detach \
--restart=always \
-v /opt/edgeware/acd/aggregator:/opt/edgeware/acd/aggregator:ro \
images.edgeware.tv/esb3032-acd-aggregator:1.4.0 \
--config /opt/edgeware/acd/aggregator/aggregator.toml
Note: The image tag in the example is “1.4.0”, you will need to replace
that tag with the image tag loaded from the compressed OCI formatted image
file, which can be obtained by running docker images
and searching for the
account aggregator image as described in the step “Loading the container image”
above.
If the configuration file saved in the previous step was at a different
location from /opt/edgeware/acd/aggregator/aggregator.toml
you will need to
change both the -v
option and the --config
option in the above
command to represent that location. The -v
option mounts the containing
folder from the host system on the left to the corresponding path inside
the container on the right, and the :ro
tells Docker that the volume is
mounted read-only. The --config
should be the absolute path to the
configuration file from INSIDE the container. For example, if you saved
the configuration file as /host/path/config.toml
on the host, and you need
to map that to /container/path/config.toml
within the container, the lines
should be -v /host/path:/container/path:ro
and
--config /container/path/config.toml
respectively.
The --restart=always
line tells Docker to automatically restart the
container when the Docker runtime is loaded, and is the equivalent in
systemd to “enabling” the service.
Starting and Stopping the container
To view the status of the running container, use the docker ps
command.
This will give a line of output for the acd-aggregator
container if it
is currently running. Appending the -a
flag, will list the aggregator
container if is not running as well.
Execute the following:
docker ps -a
You should see a line for the container with the container name “acd-aggregator” along with the current state of the container. If all is OK, you should see the container process running at this point, but it may show as “exited” if there was a problem.
To start and stop the container the docker start acd-aggregator
and
docker stop acd-aggregator
commands can be used.
Viewing the logs
By default, Docker will maintain the logs of the individual containers within its own internal logging subsystem, which requires the user to use the command
docker logs
to view them. It is possible however to configure the Docker daemon to send logs to the system journal, however configuring that is beyond the scope of this document. Additional details describing how to do that are described here
[https://docs.docker.com/config/containers/logging/journald/].
To view the complete log for the aggregator the following command can be used.
docker logs acd-aggregator
Supplying the -f
flag, can be used to “follow” the log until either the
process terminates or CTRL+C is pressed.
docker logs -f acd-aggregator
Appendix A: Real-time account monitoring
Redis key value pairs
Each account will have a single key-value stored in Redis with the current throughput with any correction factor applied, which will be updated in real-time every time all hosts for the given account have received a new account record. This should be approximately every 10 seconds, but may vary slightly due to processing time.
The keys are structured in the following format:
bandwidth:<account>:value
and the value is reported in bits-per-second.
For example for accounts foo
, bar
and baz
we may see the following:
bandwidth:foo:value = 123456789
bandwidth:bar:value = 234567890
bandwidth:baz:value = 102400
These values represent the most current throughput for each account, and will be updated periodically. A TTL of 48 hours is added to the keys, such that they will be pruned automatically after 48 hours since the last update. This is to prevent stale keys from remaining in Redis indefinitely. This TTL is not configurable by the end user.
Appendix B: PCX collector reporting
PCX reporting format
The following is an example of the report sent to the PCX HTTP endpoint.
{
timestamp_begin: 1674165540,
timestamp_end: 1674165570,
writer_id: "writer-1",
traffic: [
Traffic {
account_id: "unknown",
num_ongoing_sessions: 0,
bytes_transmitted: 0,
edges: [
Edge {
server: "orbit-1632",
num_ongoing_sessions: 0,
bytes_transmitted: 0,
},
],
},
Traffic {
account_id: "default",
num_ongoing_sessions: 747,
bytes_transmitted: 75326,
edges: [
Edge {
server: "orbit-1632",
num_ongoing_sessions: 747,
bytes_transmitted: 75326,
},
],
},
],
}
The report can be broken down into 3 parts. The outer root section includes
the starting and stopping timestamps, as well as a writer_id
field which is
currently unused. For each account a Traffic
section contains the
aggregated statistics for that account, as well as a detailed breakdown of
each Edge
. An Edge
is the portion of traffic for the account streamed
by each server. Within an Edge
the num_ongoing_sessions
represents the
peak ongoing sessions during the reporting interval, while the
bytes_transmitted
represents the total egress bandwidth in bytes over the
entire period. For each outer Traffic
section, the num_ongoing_sessions
and bytes_transmitted
represent the sum of the corresponding entries in
all Edges
.
Data protection and consistency
The ACD aggregator works by consuming messages from Kafka. Once a report has successfully been submitted, as determined by a 200 OK HTTP status from the reporting endpoint, the position in the Kafka topic will be committed. This means that if the aggregator process stops and is restarted, reporting will resume from the last successful report, and no data will be lost. There is a limitation to this, however, and that has to do with the data retention time of the messages in Kafka and the TTL value specified in the aggregator configuration. Both default to the same value of 24 hours. This means that if the aggregator process is stopped for more than 24 hours, data loss will result since the source account records will have expired from Kafka before they can be reported on by the aggregator.
Upon startup of the aggregator, all records stored in Kafka will be reported on in the order they are read, starting from either the last successful report or the oldest record currently in Kafka. Reports will be sent each time the timestamp in the current record read from Kafka exceeds the reporting interval meaning a large burst of reports will be sent at startup to cover each interval. Once the aggregator has caught up with the backlog of account records, it will send a single report roughly every 30 seconds (configurable).
It is not recommended to have more than a single account aggregator instance reading from Kafka at a time, as this will result in partial reports being sent to the HTTP endpoint which will require the endpoint to reconstruct the data upon receipt. All redundancy in the account aggregator is handled by the redundancy within Kafka itself. With this in mind, it is important to ensure that there are multiple Kafka instances running and that the aggregator is configured to read from all of them.
2.1.2.2 - Releases
2.1.2.2.1 - Release esb3032-0.2.0
Build date
2022-12-21
Release status
Type: devdrop
Change log
- NEW: Use config file instead of command line switches
- NEW: Reports are now aligned with wall-clock time
- NEW: Reporting time no longer contains gaps in coverage
- FIX: Per-account number of sessions only shows largest host
2.1.2.2.2 - Release esb3032-1.0.0
Build date
2023-02-14
Release status
Type: production
Change log
- NEW: Create user documentation for ACD Aggregator
- NEW: Simplify configuration . Changed from YAML to TOML format.
- NEW: Handle account records arriving late
- FIXED: Aggregator hangs if committing to Kafka delays more than 5 minutes
2.1.2.2.3 - Release esb3032-1.2.1
Build date
2023-04-24
Release status
Type: production
Breaking changes
No breaking changes
Change log
- NEW: Port Account Monitor functionality for Convoy Request Router
- NEW: Aggregator Performance Improvements
- FIXED: Reports lost when restarting acd-aggregator
2.1.2.2.4 - Release esb3032-1.4.0
Build date
2023-09-28
Release status
Type: production
Breaking changes
None
Change log
- NEW: Extend aggregator with additional metrics. Per streamer bandwidth and total bandwidth are now updated in Redis. [ESB3032-98]
- FIXED: Not all Redis instances are updated after a failure [ESB3032-99]
- FIXED: Kafka consumer restarts on Partition EOF [ESB3032-100]
2.1.3 - ACD Cache
Information about the ACD Cache Orbit version is available in
EDGS-103 Orbit TV Server User Guide
1 and information about the
ACD Cache SW Streamer version is available in EDGS-171 SW Streamer User Guide
1.
2.1.4 - ESB3013 BGP Sniffer
Information about the ACD BGP Sniffer is available in
EDGS-214 ESB3013 User Guide
1.
2.1.5 - Edgeware CDN Management System
Information about the classic Edgeware CDN Management System (aka Convoy)
is available in EDGS-069 Convoy Management Software User Guide
1.
2.1.6 - ESB3008 Edgeware CDN Request Router
Information about the convoy based Edgeware CDN Request Router
is available in EDGS-197 ESB3008 HTTP Request Router - User Guide
1.
2.2 - Introduction
ACD is a software suite for CDNs (Content Delivery Networks). The services built around the ACD software come into play when a user starts to view video content on a video streaming portal. The focus is on the server side of the delivery. The portal and players or set-to-boxes are not part of ACD, although they are part of Agile Contents product portfolio as a whole. Likewise, video stream repackaging and DRM are not part of ACD (see ACP).
The ACD software can be used to build a complete private CDN and/or to select between CDNs. A typical deployment is a nation-wide TV streaming service operated by a telecom operator or a broadcaster.
At the core of the system sits ESB3024 Router which will process an incoming client request and make an optimized decision from where to serve the user. The router will classify each playback request according to a variety of configured parameters such as device type, geographic region or content class. Based on the classification together with the current state of the network, its streaming capacity and public offload CDNs status, the best streaming location is determined. If desired, business rules for when to use public CDNs can be applied.
The ACD software suite includes the ACD Cache that is installed on servers placed in data centers that will guarantee an efficient and robust distribution of the content. Depending on the core network architecture, a centralized or decentralized approach is best. Agile Content can help find a good system solution.
Behind the client facing interfaces, there are backend services to monitor and measure the system. This information can be used to troubleshoot network problems, analyze viewing patterns or to plan upgrades of capacity.
Returning to the router, it is built around a very flexible routing rule evaluation engine that can route between and within CDNs. The rule evaluation engine weighs together multiple sources of information to optimize system behavior. Apart from the request classification of device type, content class etc, there are also several integration APIs that can be used to extend the product and solve problems that are particular to a specific customer. One of those integration APIs is the Selection Input API which can take any external information such as streaming bitrate of public CDNs, load balancing settings from a GUI slide bar or status from network probes and include it in the routing decision rules. Another is the Subnet API that can efficiently handle thousands of subnets and map each one to a high-level group membership (typically a region) and route based on that. There is also a metrics API to monitor the service. It integrates out-of-the-box with Prometheus and Grafana.
All APIs are documented under the API overview.
In addition to the flexibility provided by the APIs, there is also a possibility to extend functionality via plugins (using Lua). This can be used to support the decoding and encoding of security tokens (digital signatures of the URLs) or advanced routing rules that are not available out-of-the-box.
A modern TV CDN is considered as critical infrastructure and has very high requirements on uptime and robustness. This is in obtained via multiple independent and stand-alone instances of each service (although particular use cases might require sharing data via a redundant database). The ACD software services run on RHEL8 or RHEL9 Linux or compatible distributions such as Oraclelinux.
Note: Not all products or components that are part of ACD are documented here. Please contact our Sales for a complete overview.
2.3 - Solutions
2.3.1 - Cache hardware metrics: monitoring and routing
Observability and monitoring is important in a CDN. To facilitate this, we use the open source application Telegraf for two key roles: as a metrics agent and as a metrics aggregator. Telegraf performs both these roles depending on its configuration.
The image below demonstrates an example architecture when using multiple caches and instances of ESB3024 Router.
Metrics agent
All deployments of ESB2001 Orbit TV Server (from version 3.6.0) and ESB3004 SW Streamer (from version 1.36.0) come bundled with an instance of Telegraf running as a metrics agent, collecting information on hardware metrics such as usage of CPU, memory and network interfaces. If you are using other caches in your CDN, Telegraf can be manually installed and configured.
Telegraf is configured via a configuration daemon, telegraf-configd
. On the
Orbit TV Server is starts automatically, but on the SW Streamer it needs to be
started manually by typing this:
systemctl start telegraf-configd
To make it always start during boot, type
systemctl enable telegraf-configd
Once the configuration daemon is running, Telegraf can be configured using
confcli
:
$ confcli integration.acd.telegraf
{
"telegraf": {
"enable": true,
"exportUrls": [],
"hostname": ""
}
}
To enable or disable the Telegraf instance, type
$ confcli integration.acd.telegraf.enable true
integration.acd.telegraf.enable = True
$ confcli integration.acd.telegraf.enable false
integration.acd.telegraf.enable = false
The Telegraf agents need to export their metrics to an aggregator to be useful.
The field integration.acd.telegraf.exportUrls
is a list of Telegraf aggregator
instances to which the metrics will be exported. It is recommended to use at
least two Telegraf aggregator instances for redundancy.
As an example, type this to configure a cache to export metrics to
http://aggregator-host-1:8086
and http://aggregator-host-2:8086
:
$ confcli integration.acd.telegraf.exportUrls -w
Running wizard for resource 'exportUrls'
<A list of aggregator URLs to export metrics to (default: [])>
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
exportUrls <A list of aggregator URLs to export metrics to (default: [])>: [
exportUrl (default: ): http://aggregator-host-1:8086
Add another 'exportUrl' element to array 'exportUrls'? [y/N]: y
exportUrl (default: ): http://aggregator-host-2:8086
Add another 'exportUrl' element to array 'exportUrls'? [y/N]: n
]
Generated config:
{
"exportUrls": [
"http://aggregator-host-1:8086",
"http://aggregator-host-2:8086"
]
}
Merge and apply the config? [y/n]: y
The Telegraf agent tags all metrics it collects with the hostname of the machine
it is running on. To change this hostname, the field
integration.acd.telegraf.hostname
can be modifed:
$ confcli integration.acd.telegraf.hostname 'new-hostname'
integration.acd.telegraf.hostname = 'new-hostname'
Metrics aggregator
Telegraf is not installed together with the router since it is dependent on your system. Either follow these steps or ask an Agile Content integrator to set it up for your system. To set up Telegraf as an aggregator on your desired hosts, two steps need to be performed.
- Install Telegraf according to official instructions.
- Configure Telegraf to act as an aggregator by adding the following
configuration file:
/etc/telegraf/telegraf.conf
This makes Telegraf export the metrics to the timestamped selection input
endpoint (i.e. https://acd-host:5001/v2/timestamped_selection_input
). By
default, metrics sent to this endpoint have a timeout of 15 seconds, after which
the data will be removed to avoid using stale data. This timeout is configurable
by running
$ confcli services.routing.tuning.general.timestampedSelectionInputTimeoutSeconds 30
services.routing.tuning.general.timestampedSelectionInputTimeoutSeconds = 30
Due to a limitation of the [[outputs.http]]
plugin, multiple output URLs
cannot be defined as a list, the plugin only accepts a single URL. This means
that the whole [[outputs.http]]
and [outputs.http.headers]
needs to be
repeated for each router host.
Each router section needs to be modified in two places:
- Below
[[outputs.http]]
, theurl
directive has to be made direct to the router’s address. - Below
[outputs.http.headers]
,X-API-Key
has to contain the router’s REST API key. The key is stored in/opt/edgeware/acd/router/cache/rest-api-key.json
on the router server.
After the configuration file is complete, type systemctl reload telegraf
to
make Telegraf reload the new configuration.
When the aggregator is succesfully started and configured, the metrics JSON packet is sent to the selection input API with the following structure:
{
"cache-1": {
"hardware_metrics": {
"/": {
"free": 18113810432,
"total": 34887954432,
"used": 16774144000,
"used_percent": 48.08004445400899
},
"cpu_load1": 0.70,
"cpu_load5": 0.53,
"cpu_load15": 0.40,
"mem_available": 3129425920,
"mem_available_percent": 76.34786936062332,
"mem_total": 4098904064,
"mem_used": 519901184,
"n_cpus": 2
},
"per_interface_metrics": {
"eth0": {
"bytes_recv": 57585596566,
"bytes_recv_rate": 939.4, // bytes per second
"bytes_sent": 10127106702,
"bytes_sent_rate": 637.9, // bytes per second
"drop_in": 1800079,
"drop_in_rate": 0,
"drop_out": 0,
"drop_out_rate": 0,
"err_in": 0,
"err_in_rate": 0,
"err_out": 0,
"err_out_rate": 0,
"interface_up": true,
"link": 1,
"megabits_recv": 460684,
"megabits_recv_rate": 0.0075152, // megabits per second
"megabits_sent": 81016,
"megabits_sent_rate": 0.0051032, // megabits per second
"speed": 100
}
},
"timestamp": 1709296800
}
}
Monitoring
All router installations come bundled with a Prometheus instance that can be configured to scrape the aggregator instances, allowing alarms and visualization of all caches’ metrics.
On a router host, modify the configuration file /opt/edgeware/acd/prometheus/prometheus.yaml
to include a scrape job for the aggregators in your system:
global:
scrape_interval: 15s
rule_files:
- recording-rules.yaml
scrape_configs:
- job_name: 'router-scraper'
scheme: https
tls_config:
insecure_skip_verify: true
static_configs:
- targets:
- 10.16.48.106:5001
metrics_path: /m1/v1/metrics
honor_timestamps: true
- job_name: 'edns-proxy-scraper'
scheme: http
static_configs:
- targets:
- 10.16.48.106:8888
metrics_path: /metrics
honor_timestamps: true
- job_name: 'metric-aggregators'
scheme: http
static_configs:
- targets:
- aggregator-host-1:12001
- aggregator-host-2:12001
metrics_path: /metrics
honor_timestamps: true
Once the new configuration file is set, restart the Prometheus instance with
systemctl restart acd-prometheus
. When the Prometheus instance starts scraping the
aggregators, all caches’ metrics will be available for visualization in Grafana
and alarms in AlertManager.
Using hardware metrics in routing
When the hardware metrics have been succesfully injected into the selection input API, the data is ready to be used for routing decisions. In addition to creating routing conditions, hardware metrics are particularly suited to host health checks.
Host health checks
When the hardware metrics have been succesfully injected into the selection input API, the data is ready to make routing decisions with. In addition to creating routing conditions, hardware metrics are particularly suited to host health checks.
Host health checks
Host health checks are Lua functions that determine whether or not a host is ready to take on more clients. To configure host health checks, see configuring CDNs and hosts. See Built-in Lua functions for documentation on how to use the built-in health functions. Note that these health check functions can also be used for making routing conditions in the routing tree.
Routing based on cache metrics
Instead of using health check functions to incorporate hardware metrics into the routing decisions, regular routing conditions can be used.
As an example, using the health check function cpu_load_ok()
in routing can be
configured as follows:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: firstMatch
Adding a 'firstMatch' element
rule : {
name (default: ): dont_overload_cache
type (default: firstMatch):
targets : [
target : {
onMatch (default: ): default_host
condition (default: always()): cpu_load_ok()
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): offload_host
condition (default: always()):
}
Add another 'target' element to array 'targets'? [y/N]: n
]
}
Add another 'rule' element to array 'rules'? [y/N]: n
]
Generated config:
{
"rules": [
{
"name": "dont-overload-cache",
"type": "firstMatch",
"targets": [
{
"onMatch": "default_host",
"condition": "cpu_load_ok()"
},
{
"onMatch": "offload_host",
"condition": "always()"
}
]
}
]
}
Merge and apply the config? [y/n]: y
{
"routing": {
"id": "dont_overload_cache",
"member_order": "sequential",
"members": [
{
"id": "default-node",
"host_id": "default-host",
"weight_function": "return cpu_load_ok()"
}
{
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
2.3.2 - Private CDN Offload Routing with DNS
This shows a setup to do DNS based routing and 3rd party CDN offload from a private main CDN. The following components are used in the setup:
- A private Edgeware CDN with Convoy (ESB3006), Request Router (ESB3008) and SW Streamers (ESB3004)
- ESB3024 Router to offload traffic to an external CDN
- CoreDNS to support DNS based routing using ESB3024
The following figure shows an overview of the different components and how they interact.
A client retrieves a DNS name from it’s content portal. The DNS name is then resolved by CoreDNS that asks the router for a suitable host. The router either returns a host from ESB3008 Request Router or a configured offload host.
The following sequence diagram illustrates the flow.
Follow the links below to configure different use cases of this setup.
2.3.3 - Monitor ACD with Prometheus, Grafana and Alert Manager
ACD can be monitored with standard monitoring solutions. This allows you to adapt the monitoring to your needs. The following shows a setup with the following components
- Prometheus as metrics database
- Grafana to create Dashboards
- Alert Manager to create alarms from Prometheus alerts
Prometheus and Grafana can also be installed with ESB3024 Router installer in which case Grafana is also pre-populated with standard routing dashboards as well as the router troubleshooting Dashboards.
2.4 - Use Cases
2.4.1 - Route on GeoIP/ASN
This page describes how to write configuration for GeoIP and ASN-based routing. For configuration in general, see Configuration.
For more details on session groups and classifiers, see Session Groups and Classification.
ASN
Routing on ASN is done through a combination of session group classifiers and Lua script weight functions. We need to create ASN classifier(s) and then associate them with a session group:
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: geoip
Adding a 'geoip' element
classifier : {
name (default: ): allowed_asn_classifier
type (default: geoip): ⏎
inverted (default: False): ⏎
continent (default: ): ⏎
country (default: ): ⏎
cities : [
city (default: ): ⏎
Add another 'city' element to array 'cities'? [y/N]: ⏎
]
asn (default: ): Agile*ISP
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "allowed_asn_classifier",
"type": "geoip",
"inverted": false,
"continent": "",
"country": "",
"cities": [],
"asn": "Agile*ISP"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): allowed_asn
classifiers : [
classifier (default: ): allowed_asn_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "allowed_asn",
"classifiers": [
"allowed_asn_classifier"
]
}
]
}
Merge and apply the config? [y/n]: y
{
"session_groups": [
{
"id": 1,
"name": "allowed_asn",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_asn_classifier",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"asn": "Agile*ISP"
}
}
]
]
}
]
}
The asn
value is a string, matching an ISP name or similar. It supports
wildcard matching using asterisks and is case insensitive.
Note that each ASN classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different ASNs. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.
Simple Example
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): asn_split_node
type (default: split): ⏎
rule (default: ): return in_session_group("allowed_asn")
onMatch (default: ): allowed-asn-host
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "asn_split_node",
"type": "split",
"condition": "in_session_group('allowed_asn')",
"onMatch": "allowed-asn-host",
"onMiss": "offload-host"
}
]
}
Merge and apply the config? [y/n]: y
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"session_groups": [
{
"id": 1,
"name": "allowed_asn",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_asn_classifier_agile",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"asn": "Agile*ISP"
}
}
],
[
{
"id": 1,
"inverted": false,
"name": "allowed_asn_classifier_edgeware",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"asn": "Edgeware *"
}
}
]
]
}
],
"cdns": [
{
"id": "basic-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "default-host",
"cdn_id": "basic-cdn",
"address_family": "ipv4",
"host": "cdn-host.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"address_family": "ipv4",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "default-node",
"host-id": "default-host",
"weight_function": "return in_session_group('allowed_asn')"
},
{
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
Geographical Location
Routing on geographical location is done in a similar fashion. Once again, we create location classifier(s) and associate them with a session group:
Geographical locations are provided by a MaxMind database.
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: geoip
Adding a 'geoip' element
classifier : {
name (default: ): allowed_location
type (default: geoip): ⏎
inverted (default: False): ⏎
continent (default: ): ⏎
country (default: ): ⏎
cities : [
city (default: ): stockholm
Add another 'city' element to array 'cities'? [y/N]: ⏎
]
asn (default: ): ⏎
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "allowed_location",
"type": "geoip",
"inverted": false,
"continent": "",
"country": "",
"cities": [
"stockholm"
],
"asn": ""
}
]
}
Merge and apply the config? [y/n]: y
"session_groups": [
{
"id": 1,
"name": "allowed_location",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_location_classifier",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"continent": "",
"country": "",
"region": "",
"cities": ["stockholm"]
}
}
]
]
}
]
At least one of the optional fields continent
, country
, region
and
cities
are required. The classifier matches a request when all specified
fields do (for the cities
list, one matching member is sufficient). All
values support wildcard matching using asterisks and are case insensitive.
Note that each location classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different locations. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.
Simple Example
confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): geographic_location_split_node
type (default: split): ⏎
rule (default: ): return in_session_group("allowed_location")
onMatch (default: ): allowed-location-host
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "geographic_location_split_node",
"type": "split",
"condition": "in_session_group('allowed_location')",
"onMatch": "allowed-location-host",
"onMiss": "offload-host"
}
]
}
Merge and apply the config? [y/n]: y
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"session_groups": [
{
"id": 1,
"name": "allowed_location",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_location_classifier_sweden",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"country": "Sweden"
}
}
],
[
{
"id": 1,
"inverted": false,
"name": "allowed_location_classifier_oslo",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"country": "Norway",
"cities": ["Oslo"]
}
}
]
]
}
],
"cdns": [
{
"id": "basic-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "default-host",
"cdn_id": "basic-cdn",
"address_family": "ipv4",
"host": "cdn-host.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"address_family": "ipv4",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "default-node",
"host_id": "default-host",
"weight_function": "return in_session_group('allowed_location')"
}
{
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
2.4.2 - Route on Subnet
This page describes how to write configuration for subnet-based routing. For configuration in general, see Configuration.
For details on the subnets API, see Subnets API.
Subnet-based routing can be done either by using session groups and classifiers or by using the subnets API, allowing large amounts of named subnets.
Session Group Classifiers
Routing on subnets can be done through a combination of session group classifiers and Lua script weight functions. Configuring session groups and classifiers based on subnets and using them in routing may look like:
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: ipranges
Adding a 'ipranges' element
classifier : {
name (default: ): ip_ranges_classifier
type (default: ipranges): ⏎
inverted (default: False): ⏎
ipranges : [
iprange (default: ): 10.0.0.0/8
Add another 'iprange' element to array 'ipranges'? [y/N]: y
iprange (default: ): 192.168.0.0/16
Add another 'iprange' element to array 'ipranges'? [y/N]: y
iprange (default: ): 2001:0db8:85a3::/128
Add another 'iprange' element to array 'ipranges'? [y/N]: ⏎
]
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "ip_ranges_classifier",
"type": "ipranges",
"inverted": false,
"ipranges": [
"10.0.0.0/8",
"192.168.0.0/16",
"2001:0db8:85a3::/128"
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): allowed_subnets
classifiers : [
classifier (default: ): ip_ranges_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "allowed_subnets",
"classifiers": [
"ip_ranges_classifier"
]
}
]
}
Merge and apply the config? [y/n]: y
{
"session_groups": [
{
"id": 1,
"name": "allowed_subnets",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_subnet_classifier",
"rule": {
"rule_type": "ip_ranges_rule",
"source": "session/client_ip",
"ip_ranges": ["10.0.0.0/8", "192.168.0.0/16", "2001:0db8:85a3::/128"]
}
}
]
]
}
]
}
The field ip_ranges
is a list of CIDR-notation strings, supporting both IPv4
and IPv6 format. Incoming requests have their IP tested against the listed
ranges. The classifier evaluates as true if any of the ranges in the
classifier’s list matches the IP address of the request.
These session groups can then be used in routing as follows:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): subnet_split_node
type (default: split): ⏎
rule (default: ): return in_session_group('allowed_subnets')
onMatch (default: ): allowed-host
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "subnet_split_node",
"type": "split",
"condition": "in_session_group('allowed_subnets')",
"onMatch": "allowed-host",
"onMiss": "offload-host"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint subnet_split_node
services.routing.entrypoint = 'subnet_split_node'
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"cdns": [
{
"id": "allowed-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "allowed-host",
"cdn_id": "allowed-cdn",
"host": "allowed-host.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "allowed-node",
"host_id": "allowed-host",
"weight_function": "return in_session_group('allowed_subnets')"
},
{
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
},
"session_groups": [
{
"id": 1,
"name": "allowed_subnets",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "allowed_subnet_classifier",
"rule": {
"rule_type": "ip_ranges_rule",
"source": "session/client_ip",
"ip_ranges": ["10.0.0.0/8", "192.168.0.0/16", "2001:0db8:85a3::/128"]
}
}
]
]
}
]
}
Named Subnets
Named subnets are injected into the router in the form of JSON payloads to the Subnets API. Once the subnet data has been fed to the router, Lua functions can access the subnet name associated with an incoming request and use the result when it performs routing.
Note that confcli
cannot be used to inject named subnets into the router.
Assume we have injected the following subnet configuration into the router:
{
"10.0.0.0/8": "test_net_4",
"192.168.0.0/16": "test_net_4",
"2001:0db8:85a3::/128": "test_net_6"
}
A router configuration using this subnet configuration can then be constructed as:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: split
Adding a 'split' element
rule : {
name (default: ): subnet_split_node
type (default: split): ⏎
rule (default: ): in_subnet('test_net_4')
onMatch (default: ): allowed-host-4
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "subnet_split_node",
"type": "split",
"condition": "in_subnet('test_net_4')",
"onMatch": "allowed-host-4",
"onMiss": "offload-host"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint subnet_split_node
services.routing.entrypoint = 'subnet_split_node'
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"cdns": [
{
"id": "allowed-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "allowed-host-4",
"cdn_id": "allowed-cdn",
"address_family": "ipv4",
"host": "allowed-host4.example"
},
{
"id": "allowed-host-6",
"cdn_id": "allowed-cdn",
"address_family": "ipv6",
"host": "allowed-host6.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"address_family": "ipv4",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "allowed-node-4",
"host_id": "allowed-host-4",
"weight_function": "return in_subnet('test_net_4')"
},
{
"id": "allowed-node-6",
"host_id": "allowed-host-6",
"weight_function": "return in_subnet('test_net_6')"
},
{
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
Note the absence of session groups in this configuration, instead relying solely on the named subnet API to making routing decisions based on subnets.
2.4.3 - Route on Content Type
This page describes how to write configuration for content-based routing. For configuration in general, see Configuration.
Two ways to route on content type will be demonstrated: content path
based
and hostname
based using session groups and classifiers. For more details on
session groups and classifiers, see
Session Groups and Classification.
Content Path
Routing on content path is done through a combination of session group
classifiers and Lua script weight functions. Two suitable classifiers for
content path matching are string_match_rule
and regex_rule
.
The pattern is a string matching the path segment of a request URL, including
the file name. When selecting the string_match_rule
type, use asterisks for
wildcard matching. When selecting the regex_rule
follow the C++11 std::regex
ECMAScript
syntax to make valid patterns. Make sure to write patterns that match the
entire path segment, not just part of it.
Note that each content classifier normally has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different content paths. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.
Simple Example
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlPath
Adding a 'contentUrlPath' element
classifier : {
name (default: ): live_content_classifier
type (default: contentUrlPath): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *live_tv*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: y
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlPath
Adding a 'contentUrlPath' element
classifier : {
name (default: ): news_content_classifier
type (default: contentUrlPath): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): regex
pattern (default: ): /([^/]+/)?news_reports_\\d+/.*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: y
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlPath
Adding a 'contentUrlPath' element
classifier : {
name (default: ): hls_content_classifier
type (default: contentUrlPath): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *.m3u8
}
Add another 'classifier' element to array 'classifiers'? [y/N]: n
]
Generated config:
{
"classifiers": [
{
"name": "live_content_classifier",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*live_tv*"
},
{
"name": "news_content_classifier",
"type": "contentUrlPath",
"inverted": false,
"patternType": "regex",
"pattern": "/([^/]+/)?news_reports_\\\\d+/.*"
},
{
"name": "hls_content_classifier",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*.m3u8"
}
]
}
Merge and apply the config? [y/n]: y
confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): live_content
classifiers : [
classifier (default: ): live_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
sessionGroup : {
name (default: ): news_content
classifiers : [
classifier (default: ): news_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
sessionGroup : {
name (default: ): hls_content
classifiers : [
classifier (default: ): hls_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "live_content",
"classifiers": [
"live_content_classifier"
]
},
{
"name": "news_content",
"classifiers": [
"news_content_classifier"
]
},
{
"name": "hls_content",
"classifiers": [
"hls_content_classifier"
]
}
]
}
Merge and apply the config? [y/n]: y
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"session_groups": [
{
"id": 1,
"name": "live_content",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "live_content_classifier",
"rule": {
"rule_type": "string_match_rule",
"source": "session/content_url_path",
"pattern": "*live_tv*"
}
}
]
],
[
[
{
"id": 2,
"inverted": false,
"name": "news_content_classifier",
"rule": {
"rule_type": "regex_rule",
"source": "session/content_url_path",
"pattern": "/([^/]+/)?news_reports_\\d+/.*"
}
}
]
]
},
{
"id": 2,
"name": "hls_content",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "hls_content_classifier",
"rule": {
"rule_type": "string_match_rule",
"source": "session/content_url_path",
"pattern": "*.m3u8"
}
}
]
]
}
],
"cdns": [
{
"id": "live-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "vod-hls-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "vod-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "live-host",
"cdn_id": "live-cdn",
"address_family": "ipv4",
"host": "live-host.example"
},
{
"id": "vod-hls-host",
"cdn_id": "vod-hls-cdn",
"address_family": "ipv4",
"host": "vod-hls-host.example"
},
{
"id": "vod-host",
"cdn_id": "vod-cdn",
"address_family": "ipv4",
"host": "vod-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "live-node",
"host_id": "live-host",
"weight_function": "return session_groups.live_content and 1 or 0"
},
{
"id": "vod-hls-node",
"host_id": "vod-hls-host",
"weight_function": "return session_groups.hls_content and 1 or 0"
},
{
"id": "vod-node",
"host_id": "vod-host",
"weight_function": "return 1"
}
]
}
}
Hostname
In cases where there are separate domain or subdomain names for different content types, it’s simple to make classifiers that filter on those names.
The pattern is a string matching the hostname segment of a request URL,
including the file name. When selecting the string_match_rule
type, use
asterisks for wildcard matching. When selecting the regex_rule
follow the
C++11 std::regex
ECMAScript
syntax to make valid patterns. Make sure to write patterns that match the
entire hostname segment, not just part of it.
Note that each hostname classifier has to be in its own list. This is because classifiers within the same inner list all have to match for the entire list to be true, and that is impossible for classifiers that match against different hostnames. When the classifiers are in their own lists, it’s enough that one of them matches for the outer classifier list to also match.
Simple example
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: hostName
Adding a 'hostName' element
classifier : {
name (default: ): live_content_classifier
type (default: hostName): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): live.example.com
}
Add another 'classifier' element to array 'classifiers'? [y/N]: y
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: hostName
Adding a 'hostName' element
classifier : {
name (default: ): news_content_classifier
type (default: hostName): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): regex
pattern (default: ): /([^\\.]+/)\\.news_reports_\\d+/\\.example\\.com
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "live_content_classifier",
"type": "hostName",
"inverted": false,
"patternType": "stringMatch",
"pattern": "live.example.com"
},
{
"name": "news_content_classifier",
"type": "hostName",
"inverted": false,
"patternType": "regex",
"pattern": "/([^\\\\.]+/)\\\\.news_reports_\\\\d+/\\\\.example\\\\.com"
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): live_content
classifiers : [
classifier (default: ): live_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
sessionGroup : {
name (default: ): news_content
classifiers : [
classifier (default: ): news_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: y
sessionGroup : {
name (default: ): hls_content
classifiers : [
classifier (default: ): hls_content_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "live_content",
"classifiers": [
"live_content_classifier"
]
},
{
"name": "news_content",
"classifiers": [
"news_content_classifier"
]
},
{
"name": "hls_content",
"classifiers": [
"hls_content_classifier"
]
}
]
}
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"session_groups": [
{
"id": 1,
"name": "live_content",
"classifiers": [
[
{
"id": 1,
"inverted": false,
"name": "live_content_classifier",
"rule": {
"rule_type": "string_match_rule",
"source": "session/hostname",
"pattern": "live.example.com"
}
}
],
[
{
"id": 2,
"inverted": false,
"name": "news_content_classifier",
"rule": {
"rule_type": "regex_rule",
"source": "session/hostname",
"pattern": "/([^\\.]+/)\\.news_reports_\\d+/\\.example\\.com"
}
}
]
]
}
],
"cdns": [
{
"id": "live-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "vod-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "live-host",
"cdn_id": "live-cdn",
"address_family": "ipv4",
"host": "live-host.example"
},
{
"id": "vod-host",
"cdn_id": "vod-cdn",
"address_family": "ipv4",
"host": "vod-host.example"
}
],
"routing": {
"id": "routing_table",
"member_order": "sequential",
"members": [
{
"id": "live-node",
"host_id": "live-host",
"weight_function": "return session_groups.live_content and 1 or 0"
},
{
"id": "vod-node",
"host_id": "vod-host",
"weight_function": "return 1"
}
]
}
}
Using the session groups in confcli
The constructed session groups can be used in routing by creating a rule that references them:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: firstMatch
Adding a 'firstMatch' element
rule : {
name (default: ): classifier_routing_rule
type (default: firstMatch): ⏎
targets : [
target : {
onMatch (default: ): live-host
rule (default: ): in_all_session_groups('live_content', 'news_content')
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): vod-hls-host
rule (default: ): in_session_group('hls_content')
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): offload-host
rule (default: ): always()
}
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "classifier_routing_rule",
"type": "firstMatch",
"targets": [
{
"onMatch": "live-host",
"condition": "in_all_session_groups('live_content', 'news_content')"
},
{
"onMatch": "vod-hls-host",
"condition": "in_session_group('hls_content')"
},
{
"onMatch": "offload-host",
"condition": "always()"
}
],
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint classifier_routing_rule
services.routing.entrypoint = classifier_routing_rule
2.4.4 - Route on Content Popularity
This page describes how to write configuration for content popularity routing. For configuration in general, see Configuration.
For more details on content popularity tuning and routing, see
Content Popularity
The router tracks content popularity which can be utilized for routing.
Using the configuration tool confcli
, creating a content popularity based
routing configuration for hierarchical and multi-edge scenarios will be
demonstrated.
Hierarchical
Consider a CDN setup with edge streamers that has cached popular content and a central streamer where all content is available. You can decide where to route clients based on the requested content’s popularity.
Assuming that appropriate streamer hosts have already been configured, configuration will look like:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: contentPopularity
Adding a 'contentPopularity' element
rule : {
name (default: ): contentPopularityHierarchy
type (default: contentPopularity): ⏎
popularityThreshold (default: 10): 2000
onPopular (default: ): edgeStreamer
onUnpopular (default: ): centralStreamer
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "contentPopularityHierarchy",
"type": "contentPopularity",
"popularityThreshold": 2000.0,
"onPopular": "edgeStreamer",
"onUnpopular": "offloadStreamer"
}
]
}
Merge and apply the config? [y/n]: y
where name
is the name of the rule, isPopular
is the rule to route to if
the content is popular, otherwise the rule isUnpopular
is routed to. Lastly,
popularityThreshold
is the threshold for which content is considered popular.
Configuring popularityThreshold
= 2001 means that the top 2000 most popular
assets will be routed to edgeStreamer
.
The rule contentPopularityHierarchy
can then be used to construct your routing
tree.
Multi-edge
Consider a CDN setup with three edge streamers, edge1
, edge2
and
edge3
, configured to cache very popular content, mildly popular content
and unpopular content respectively. Assuming that appropriate streamer
hosts have already been configured, the following configuration can be used for
correctly routing a request in this scenario:
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: contentPopularity
Adding a 'contentPopularity' element
rule : {
name (default: ): mildlyAndUnpopular
type (default: contentPopularity): ⏎
popularityThreshold (default: 10): 2001
onPopular (default: ): edge2
onUnpopular (default: ): edge3
}
Add another 'rule' element to array 'rules'? [y/N]: y
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: contentPopularity
Adding a 'contentPopularity' element
rule : {
name (default: ): multiLevelPopularity
type (default: contentPopularity): ⏎
popularityThreshold (default: 10): 101
onPopular (default: ): edge1
onUnpopular (default: ): mildyAndUnpopular
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "mildlyAndUnpopular",
"type": "contentPopularity",
"popularityThreshold": 2001.0,
"onPopular": "edge2",
"onUnpopular": "edge3"
},
{
"name": "multiLevelPopularity",
"type": "contentPopularity",
"popularityThreshold": 101.0,
"onPopular": "edge1",
"onUnpopular": "mildyAndUnpopular"
}
]
}
Merge and apply the config? [y/n]: y
By configuring a rule to route to multiLevelPopularity
,
this configuration will route requests for the top 100 most popular content
to edge1
, popularity ranking 101-2000 to edge2
and popularity
ranking > 2000 to edge3
. Since the contentPopularity
rule offers a binary
routing choice of either isPopular
or isUnpopular
, multiple
contentPopularity
rules can be utilized to construct multi-leveled content
popularity based routing configurations.
Application
To use any of these two configurations in your installation, you’ll need to
configure either a rule or the entrypoint
to route to either
multiLevelPopularity
or contentPopularityHierarchy
.
2.4.5 - Route on Selection Input
This page describes how to write configuration for routing on bandwidth usage or number of ongoing sessions in Edgeware CDN:s by using the selection input API. For configuration in general, see Configuration.
For more details on the selection input API, see Selection Input.
Selection Input
The selection input API allows you to inject custom data, that can be used during routing, into the router. For this use case, we will use CDN bandwidth and the number of ongoing sessions to demonstrate the capabilities of the selection input API.
Imagine that we have a monitor constantly polling the bandwidth and ongoing sessions of hosts in a CDN. These values are injected into the selection input API as JSON packets:
{
"edge-host-available-bps": 1000000000,
"edge-host-ongoing-sessions": 300
}
These keys will end up in the router Lua context as “selection inputs”, arbitrary values or JSON objects that can be used to calculate routing weights.
The selection input variable edge-host-available-bps
will be available
through either selection_input.edge-host-available-bps
or
si('edge-host-available-bps')
. The function si(si_var)
fetches the selection input value if it exists, otherwise it returns 0.
However, when comparing selection input variables with numbers, there are a
number of built-in Lua functions that will simplify things, such as gt()
and
lt()
. For a complete list and more details on these functions, see
Built-in Functions.
Simple Example
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: firstMatch
Adding a 'firstMatch' element
rule : {
name (default: ): selection-input-routing
type (default: firstMatch): ⏎
targets : [
target : {
onMatch (default: ): edge-host
rule (default: ): lt('edge_host_ongoing_sessions', 1000)
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): edge-host
rule (default: ): gt('edge_host_available_bps', 5000000)
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): offload-host
rule (default: ): always()
}
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "selection-input-routing",
"type": "firstMatch",
"targets": [
{
"onMatch": "edge-host",
"condition": "lt('edge_host_ongoing_sessions', 1000)"
},
{
"onMatch": "edge-host",
"condition": "gt('edge_host_available_bps', 5000000)"
},
{
"onMatch": "offload-host",
"condition": "always()"
}
]
}
]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint selection-input-routing
services.routing.entrypoint = 'selection-input-routing'
{
"content_server": {
"http_enable": true,
"http_port": 80,
"https_enable": true,
"https_port": 443
},
"cdns": [
{
"id": "edge-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "edge-host",
"cdn_id": "edge-cdn",
"host": "edge-host.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing-table",
"member_order": "sequential",
"members": [
{
"id": "edge-host-sessions-available",
"host_id": "edge-host",
"weight_function": "return (lt('edge_host_ongoing_sessions', 1000) ~= 0) and 1 or 0"
},
{
"id": "edge-host-bandwith-available",
"host_id": "edge-host",
"weight_function": "return (gt('edge_host_available_bps', 5000000) ~= 0) and 1 or 0"
},
{
"id": "offload",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
2.4.6 - Adapt to multi-CDN
This page describes how to write configuration for setups that require the URL sent back to the client to be rewritten based on routing results, for example by adding a token to the path or as a query string parameter. For configuration in general, see Configuration.
In order to change the redirect location URL, we need to add a response translation function to the confd configuration. By default, all translation functions are empty:
$ confcli services.routing.translationFunctions
{
"translationFunctions": {
"request": "",
"response": ""
}
}
For full documentation of the response translation function, please see Lua Hooks.
Simple example
Translation functions tend to become large, which makes it hard to write
them inside a single string. Instead, the function can be written in a separate
.lua
script file that is uploaded to the router and referenced from the
confd
configuration.
The following example will take this approach, adding a script called
"rewrite.lua"
to the configured custom Lua folder /tmp/custom_lua
on
the router. For more information see the Configuration JSON Overview.
Lua script
The following script assumes the existence of the function parse_url
that
returns an object with URL segments that can be altered and then combined into
a URL string using the tostring(obj)
function again.
Beware that the router does not validate the URL in the Location header, it is up to the Lua script writer to ensure that only URLs are returned.
function response_rewrite(Headers)
-- The live server has the token as part of the path, added first before the
-- path from the request.
local location = parse_url(response_headers.location)
if location.host == "live-host.example" then
location.path = "/live-prefix" .. location.path
return HTTPResponse(
{
Headers = {
{"location", tostring(location)}
}
}
)
end
-- The VOD server expects the token as a query string rather than as part
-- of the path segment.
-- Since VOD can be used for offload, check that session_groups.is_vod
-- is set as well.
if location.host == "vod-host.example" and session_groups.is_vod then
location.query["token"] = md5sum(secret_key .. request.path)
return HTTPResponse(
{
Headers = {
{"location", tostring(location)}
}
}
)
end
-- If the request was neither in the is_live session group, nor contained
-- the path element "vod", we return a nil object to indicate that we don't
-- want to change anything in the response.
return nil
end
Configuration
To configure a response translation function using with the custom Lua function
response_rewrite()
using confcli
, run the command:
$ confcli services.routing.translationFunctions.response 'return response_rewrite()'
services.routing.translationFunctions.response = 'return response_rewrite()'
An example confd
configuration utilizing this translation function based on
session groups would look like this:
$ confcli services.routing
{
"translationFunctions": {
"request": "",
"response": "return response_rewrite()"
},
"sessionGroups": [
{
"name": "is_live",
"classifiers": [
"is_live_classifier"
]
},
{
"name": "is_vod",
"classifiers": [
"is_vod_classifier"
]
}
],
"classifiers": [
{
"name": "is_live_classifier",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*/live/*"
},
{
"name": "is_vod_classifier",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*/vod/*"
}
],
"hostGroups": [
{
"name": "live-cdn",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "live-host",
"hostname": "live-host.example",
"ipv6_address": ""
}
]
},
{
"name": "vod-cdn",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "vod-host",
"hostname": "vod-host.example",
"ipv6_address": ""
}
]
}
],
"rules": [
{
"name": "multiCdnExample",
"type": "firstMatch",
"targets": [
{
"condition": "in_session_group('is_live')",
"onMatch": "live-host"
},
{
"condition": "in_session_group('is_vod')",
"onMatch": "vod-host"
},
// Use the vod-host as offload for any content, but don't set any
// token for requests not classified as vod.
{
"condition": "always()",
"onMatch": "vod-host"
}
]
}
],
"entrypoint": "multiCdnExample",
"applyConfig": true
}
2.4.7 - How to use ACD router for EDNS routing
This page describes how to write configuration for EDNS routing. For configuration in general, see Configuration.
EDNS routing
In your CDN architecture, you might utilize EDNS routing to redirect clients. Whether it’s your own CDN or a third party CDN, the ESB3024 Router supports creating EDNS requests and sending them to any DNS server.
Configuration
To configure EDNS routing, you first need to create a DNS type host.
Using confcli
:
[user@acd-router ~]# confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: dns
Adding a 'dns' element
hostGroup : {
name (default: ): edns-cdn
type (default: dns): ⏎
hosts : [
host : {
name (default: ): edns-host
hostname (default: ): ednshost.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "edns-cdn",
"type": "dns",
"hosts": [
{
"name": "edns-host",
"hostname": "ednshost.com",
"ipv6_address": ""
}
]
}
]
}
Merge and apply the config? [y/n]: y
Note that the hostname
is the name of the DNS server that will receive
the EDNS request. You can now use the DNS host when creating the routing tree,
e.g. in a random
type rule:
[user@router ~]# confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: random
Adding a 'random' element
rule : {
name (default: ): random-rule
type (default: random): ⏎
targets : [
target (default: ): edns-host
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "random-rule",
"type": "random",
"targets": [
"edns-host"
]
}
]
}
Merge and apply the config? [y/n]: y
[user@router ~]# confcli services.routing.entrypoint random-rule
services.routing.entrypoint = 'random-rule'
Or simply use it as the entrypoint:
confcli services.routing.entrypoint edns-host
2.4.8 - How to use ESB3024 Router with Edgeware CDN Request Router
This page describes how to write configuration for using ESB3024 Router in conjunction with ESB3008 Request Router. It can request a host from an ESB3008 Request Router and forward the response to the client, perform load balancing between several Request Routers and handle fallback to an external CDN in case no Request Routers are able to service the request.
Simple Example
# The tuning parameter `target.requestAttempts` controls the number of attempts
# made to find a host. In this example we want to fallback to the external CDN
# in case both Request Routers are down, so we set it to at least 3.
$ confcli services.routing.tuning.target.requestAttempts 3
services.routing.tuning.target.requestAttempts = 3
# Create a classifier to filter incoming requests from Sweden.
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: geoip
Adding a 'geoip' element
classifier : {
name (default: ): sweden_classifier
type (default: geoip): ⏎
inverted (default: False): ⏎
continent (default: ): ⏎
country (default: ): sweden
cities : [
city (default: ): ⏎
Add another 'city' element to array 'cities'? [y/N]: ⏎
]
asn (default: ): ⏎
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "sweden_classifier",
"type": "geoip",
"inverted": false,
"continent": "",
"country": "sweden",
"cities": [
""
],
"asn": ""
}
]
}
Merge and apply the config? [y/n]: y
# Create a session group for the non-Swedish requests, to use in routing rules
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): sweden
classifiers : [
classifier (default: ): sweden_classifier
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "sweden",
"classifiers": [
"sweden_classifier"
]
}
]
}
Merge and apply the config? [y/n]: y
# The internal CDN uses Edgeware Request Routers that return a redirect
# location. The router takes the content from the client request,
# and makes its own request to the Request Router using that same
# content. The returned location is then forwarded to the client.
#
# In case the Request Router responds with an error code, or times out,
# the router will continue traversing the routing tree until a
# successful route is found or the entire tree has been evaluated.
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: redirecting
Adding a 'redirecting' element
hostGroup : {
name (default: ): internal-cdn
type (default: redirecting): ⏎
httpPort (default: 80): ⏎
httpsPort (default: 443): ⏎
hosts : [
host : {
name (default: ): internal-host-1
hostname (default: ): internal-host-1.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: y
host : {
name (default: ): internal-host-2
hostname (default: ): internal-host-2.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "internal-cdn",
"type": "redirecting",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "internal-host-1",
"hostname": "internal-host-1.example.com",
"ipv6_address": ""
},
{
"name": "internal-host-2",
"hostname": "internal-host-2.example.com",
"ipv6_address": ""
}
]
}
]
}
Merge and apply the config? [y/n]: y
# The offload CDN is non-redirecting, meaning that router does not
# make any request to its associated hosts to ask for a redirect location
# to forward to the clients, instead it simply returns a location using
# one of the CDN's hosts substituted for the router's host in the
# client request possibly with some kind of respsonse translation to add
# e.g. tokens or path prefixes.
$ confcli services.routing.hostGroups -w
Running wizard for resource 'hostGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
hostGroups : [
hostGroup can be one of
1: dns
2: host
3: redirecting
Choose element index or name: host
Adding a 'host' element
hostGroup : {
name (default: ): offload-cdn
type (default: host): ⏎
httpPort (default: 80): ⏎
httpsPort (default: 443): ⏎
hosts : [
host : {
name (default: ): offload-host
hostname (default: ): offload-host.example.com
ipv6_address (default: ): ⏎
}
Add another 'host' element to array 'hosts'? [y/N]: ⏎
]
}
Add another 'hostGroup' element to array 'hostGroups'? [y/N]: ⏎
]
Generated config:
{
"hostGroups": [
{
"name": "offload-cdn",
"type": "host",
"httpPort": 80,
"httpsPort": 443,
"hosts": [
{
"name": "offload-host",
"hostname": "offload-host.example.com",
"ipv6_address": ""
}
]
}
]
}
Merge and apply the config? [y/n]: y
# Begin with adding a load balancing route rule between the two internal
# hosts. Let's make internal-host-2 have twice the capacity of
# internal-host-1 by using a weighted rule.
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: weighted
Adding a 'weighted' element
rule : {
name (default: ): balancer
type (default: weighted): ⏎
targets : [
target : {
target (default: ): internal-host-1
weight (default: 100): 1,
rule (default: always()): always()
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
target (default: ): internal-host-2
weight (default: 100): 2,
rule (default: always()): always()
}
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "balancer",
"type": "weighted",
"targets": [
{
"target": "internal-host-1",
"weight": "1",
"rule:": "always()"
},
{
"target": "internal-host-2",
"weight": "2",
"rule:": "always()"
}
]
}
]
}
Merge and apply the config? [y/n]: y
# Make an offload rule to route any traffic not in Sweden to the
# offload CDN.
$ confcli services.routing.rules -w
Running wizard for resource 'rules'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
rules : [
rule can be one of
1: allow
2: consistentHashing
3: contentPopularity
4: deny
5: firstMatch
6: random
7: rawGroup
8: rawHost
9: split
10: weighted
Choose element index or name: firstMatch
Adding a 'firstMatch' element
rule : {
name (default: ): offload
type (default: firstMatch): ⏎
targets : [
target : {
onMatch (default: ): offload-host
rule (default: ): not in_session_group('sweden')
}
Add another 'target' element to array 'targets'? [y/N]: y
target : {
onMatch (default: ): balancer
rule (default: ): in_session_group('sweden')
}
Add another 'target' element to array 'targets'? [y/N]: ⏎
]
onMiss (default: ): offload-host
}
Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
"rules": [
{
"name": "offload",
"type": "firstMatch",
"targets": [
{
"onMatch": "offload-host",
"condition": "not in_session_group('sweden')"
},
{
"onMatch": "balancer",
"condition": "in_session_group('sweden')"
}
],
"onMiss": "offload-host"
}
]
}
Merge and apply the config? [y/n]: y
{
"tuning": {
// "target_request_attempts" controls the number of attempts to find a host.
// In this example we want to fallback to the external CDN in case both
// Request Routers are down, so we set it to 3.
"target_request_attempts": 3
},
"session_groups": [
{
"id": 1,
"name": "not_sweden",
"classifiers": [
[
{
"id": 1,
"inverted": true,
"name": "not_sweden_classifier",
"rule": {
"rule_type": "geoip_rule",
"source": "session/client_ip",
"country": "Sweden"
}
}
]
]
}
],
"cdns": [
{
"id": "internal-cdn",
"http_port": 80,
"https_port": 443,
// The internal CDN uses Edgeware Request Routers that return a redirect
// location. The router takes the content from the client request,
// and makes its own request to the Request Router using that same
// content. The returned location is then forwarded to the client.
//
// In case the Request Router responds with an error code, or times out,
// the router will continue traversing the routing tree until a
// successful route is found or the entire tree has been evaluated.
"redirecting": true,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
},
{
"id": "offload-cdn",
"http_port": 80,
"https_port": 443,
// The offload CDN is non-redirecting, meaning that router does not
// make any request to its associated hosts to ask for a redirect location
// to forward to the clients, instead it simply returns a location using
// one of the CDN's hosts substituted for the router's host in the
// client request possibly with some kind of respsonse translation to add
// e.g. tokens or path prefixes.
"redirecting": false,
"manifest_availability_check": {
"enabled": false,
"session_group_ids": []
}
}
],
"hosts": [
{
"id": "internal-host-1",
"cdn_id": "internal-cdn",
"address_family": "ipv4",
"host": "internal-host-1.example"
},
{
"id": "internal-host-2",
"cdn_id": "internal-cdn",
"address_family": "ipv4",
"host": "internal-host-2.example"
},
{
"id": "offload-host",
"cdn_id": "offload-cdn",
"address_family": "ipv4",
"host": "offload-host.example"
}
],
"routing": {
"id": "routing_table",
// "sequential" - Go through the rules at this level one by one, and pick
// the first that returns a positive weight.
"member_order": "sequential",
"members": [
{
"id": "reject-node",
"host_id": "offload-host",
// Send filtered-out clients to an offload host.
"weight_function": "return session_groups.not_sweden and 1 or 0"
},
{
"id": "internal_routing",
// Return 1 to make sure this tree is evaluated at all.
"weight_function": "return 1"
// "weighted" - Evaluate all the rules at this level, and pick one of
// them randomly based on their respective weights.
//
// In this example host 1 has half the capacity of host 2, so we just
// randomly route twice as many clients to host 2.
"member_order": "weighted",
"members": [
{
"id": "internal-node-1",
"host_id": "internal-host-1",
// Half the weight of the other host -> half as likely to be picked.
"weight_function": "return 1"
},
{
"id": "internal-node-2",
"host_id": "internal-host-2",
// Twice the weight of the other -> twice as likely to be picked.
"weight_function": "return 2"
}
]
},
{
// Add a non-redirecting offload host as the last target in case all the
// internal redirecting hosts are unavailable or respond with some kind
// of error code.
"id": "offload-node",
"host_id": "offload-host",
"weight_function": "return 1"
}
]
}
}
2.4.9 - How to use ESB3024 Router with CoreDNS
CoreDNS can be configured to work as a DNS server in front of ESB3024 Router. In this mode of operation the client DNS request is terminated by CoreDNS which requests an optimal streaming location from the router.
Contact Edgeware for detailed information on how to set this up, if you don’t already have an Edgeware Support account please contact us here.
2.4.10 - How to use the Director as a replacement for Edgeware CDN Request Router
This guide outlines how to replicate Convoy’s ESB3008 HTTP Request Router using the Director. This is accomplished using the Convoy Bridge, which is an integration service designed to allow the router and an existing Convoy installation to work together seamlessly.
Following the steps outlined below enables the replacement of existing ESB3008 HTTP Request Router instances with the Director. As of the current documentation, the Director is not a direct substitute for the ESB3008 HTTP Request Router. However, most of the functionality is available, and in the majority of cases, the Director can be used without any loss of functionality.
The purpose of this guide is to detail the process of transitioning from an existing Convoy installation, which includes one or more instances of ESB3008 HTTP Request Router, to a configuration utilizing the Director. This transition allows the existing Convoy installation to continue its role in CDN provisioning, content management, and analytics. Simultaneously, the router assumes responsibility for managing HTTP(S) redirects directly from clients to selected streamers.
One functional difference between ESB3008 HTTP Request Router and the Director is
in communication with the streamer to determine specific interface assignments.
ESB3008 uses a proprietary protocol to communicate with the streamer to help determine
the best interface for the client. For the Director, in order to work with both
streamers and third-party CDNs, the use of the proprietary protocol is not supported,
and the router’s rule engine must be used to accomplish the same result. It is for
this reason that it is recommended to configure each streaming interface as a distinct
host
entry in the router’s configuration. This allows the router to address each
interface separately.
Prerequisites
This guide assumes both an existing Convoy installation and a partiality configured
instance of the Director. The router should have all the necessary routing configuration
in place for hostGroups
, sessionGroups
and routing rules
to direct traffic
to the streaming interfaces of the streamers. It is also assumed that the proper
firewall rules are allowing the required traffic between the router, the Convoy
Bridge integration and the Convoy management nodes.
The minimum compatible version of Convoy which can be used with the analytics synchronization feature is Convoy 3.0.0. Previous versions may be used only if Convoy is not being used for analytics.
Firewall Configuration
Proper firewall configuration is required to allow both the router and Convoy to communicate through bidirectional connections established from the Convoy Bridge integration. The Convoy Bridge does not need to be enabled for each router instance, one instance of the Convoy Bridge can synchronize multiple instances of the router simultaneously. Only the router nodes with the Convoy Bridge enabled will need access through the firewall to establish outgoing connections to the Convoy management nodes, or whichever nodes are running MariaDB and Kafka. Additionally, if multiple router instances are to be synchronized by a single Convoy Bridge instance, the firewall must allow the Convoy Bridge to establish connections to each router instance on port 5001.
The following table outlines the necessary connections to be allowed through the firewall.
Source | Destination | Port | Description |
---|---|---|---|
Convoy Bridge | Convoy Management | 3306/TCP | Account Configuration |
Convoy Bridge | Convoy Management | 9092/TCP | Analytics Data |
Convoy Bridge | The router | 5001/TCP | Rest API |
Response Translation Functions
In order to have the router generate a redirect URL which is compatible with the
format generated by the ESB3008 HTTP Request Router, a response translation function
must be used to modify the redirect URL before it is returned to the client. A built-in
function convoy_compatibility_response
is available to be
used for this purpose. This function appends both the session-id
and storage-prefix
based on the account and distribution information in Convoy.
On the Director, set the response translation function as follows:
> confcli services.routing.translationFunctions.response "return convoy_compatibility_response(Headers, '')"
This function depends on the account synchronization feature of the Convoy bridge to
determine the correct storage prefix based on the incoming Host
header value. It works
by using the Host
header to lookup the storage prefix from the account configuration,
and then modifying the redirect URL to prepend /session/<session-id>/<prefix>
. The
streamer can then use this information for both origin selection and session tracking.
Enabling the Convoy Bridge
Before using the Convoy Bridge integration, a valid configuration must first be applied.
All configuration for the Convoy Bridge is available in confd
under the key
integration.convoy.bridge
. The configuration is divided into three main sections:
The account synchronization feature, the convoy analytics integration, and a list of
additional router instances to synchronize.
By default, the Convoy Bridge will include the current local router instance in the synchronization process. The connection details are hard-wired into the container at startup, and do not need to be specified in the configuration. Because one Convoy Bridge can serve multiple instances of the router, it is not necessary to configure the Convoy Bridge on each node separately. However, if multiple Convoy Bridge instances are used, it is recommended to configure them so that one router is served by multiple instances of the Convoy Bridge. This provides high-availability in a production environment.
As an example, if there are 4 router instances, A, B, C, and D, and 4 Convoy Bridge instances, configuring them such that Bridge 1 synchronizes A & B, 2, synchronizes B & C, 3, synchronizes C & D and 4 synchronizes D & A will provide fault tolerance in the event that one bridge is unavailable.
The account synchronization feature of the Convoy Bridge watches the MariaDB database on the
Convoy management node for changes to the account and distribution configuration, and if
the configuration differs from what is currently known to the router the configuration
will be updated. This feature is required by both the router for use with the
convoy_compatibility_response
response translation function, and within the Convoy
Bridge integration for setting the correct account
, storage
, and distribution
fields
with the analytics integration feature.
The analytics integration feature monitors monitors the router’s Event API for
newly established sessions, and produces session-record
messages over the Kafka
message broker for use by Convoy. This feature requires that Convoy is both licensed
and configured for use with the analytics feature. The integration works by establishing
a persistent connection to each router, and listening for new session events. Due to the
protocol in use by the Event API to send the events, only one instance of the Convoy
Bridge will have the ability to receive each event, and only that instance will produce
the session-record
to the Kafka message brokers.
Synchrnoizing multiple routers with the same instance of the Convoy Bridge is performed
by configuring the otherRouters
section of the Convoy Bridge configuration. In addition
to the local router, each otherRouter
entry will have the same account and distribution
information updated simultaneously, and will be used as an event source for the analytics
integration. The otherRouters
entries require the URL to the router’s Rest API, an
optional API key, and a flag to indicate if SSL certificate validation should be enforced.
Enable the account synchronization feature by running the following command:
> confcli integration.convoy.bridge.accounts -w
Running wizard for resource 'accounts'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
accounts : {
enabled (default: False): true
dbUrl (default: mysql://user:pass@localhost:3306): mysql://convoy:password@convoy-mgmt1:3306
cmsUrl (default: http://localhost:5555): http://convoy-mgmt1:5555
pollInterval (default: 60):
}
Generated config:
{
"accounts": {
"enabled": true,
"dbUrl": "mysql://convoy:password@convoy-mgmt1:3306",
"cmsUrl": "http://convoy-mgmt1:5555",
"pollInterval": 60
}
}
Merge and apply the config? [y/n]:
This will result in the Convoy Bridge continuously polling the Convoy instance running on
convoy-mgmt1
every 60 seconds for changes to the account configuration. Only when the
account configuration differs from the current configuration on the router will it be
updated with the change.
The pollInterval
parameter can be used to control how frequently the Convoy Bridge will
attempt to poll the database for changes. Setting this value too high will result in a longer delay
between changes being made in Convoy and the changes being reflected in the router. Setting this
value too low will result in unnecessary load on the Convoy database. The default value of 60 seconds
should be sufficient for most use cases.
To enable the analytics integration feature, run the following command:
> confcli integration.convoy.bridge.analytics -w
Running wizard for resource 'analytics'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
analytics : {
enabled (default: False): true
brokers : [
broker (default: ): convoy-mgmt1:9092
Add another 'broker' element to array 'brokers'? [y/N]: y
broker (default: ): convoy-mgmt2:9092
Add another 'broker' element to array 'brokers'? [y/N]: y
broker (default: ): convoy-mgmt3:9092
Add another 'broker' element to array 'brokers'? [y/N]: n
]
batchInterval (default: 10):
maxBatchSize (default: 500):
}
Generated config:
{
"analytics": {
"enabled": true,
"brokers": [
"convoy-mgmt1:9092",
"convoy-mgmt2:9092",
"convoy-mgmt3:9092"
],
"batchInterval": 10,
"maxBatchSize": 500
}
}
Merge and apply the config? [y/n]:
This will enable the analytics integration, which will produce session-record
messages
to the configured Kafka
brokers. The brokers
configuration list is used to bootstrap the
initial set of brokers which will be contacted by the Convoy Bridge to then obtain the
current set of active brokers. It is not necessary to include all brokers here, as the
initial connection will automatically negotiate the correct broker list.
The batchInterval
parameter must be set to a value much less than 60 seconds, since the
streamer will send session-sample
messages to Kafka every 60 seconds, and if the
corresponding session-record
message is not received within that time, the sample will
be dropped, resulting in potentially inaccurate bandwidth statistics.
> confcli integration.convoy.bridge.otherRouters -w
Running wizard for resource 'otherRouters'
<Other routers which will be kept in sync (default: [])>
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
otherRouters <Other routers which will be kept in sync (default: [])>: [
otherRouter : {
url (default: ): https://router-2:5001
apiKey (default: ): 1234
validateCerts (default: True): false
}
Add another 'otherRouter' element to array 'otherRouters'? [y/N]: y
otherRouter : {
url (default: ): https://router-3:5001
apiKey (default: ):
validateCerts (default: True):
}
Add another 'otherRouter' element to array 'otherRouters'? [y/N]: n
]
Generated config:
{
"otherRouters": [
{
"url": "https://router-2:5001",
"apiKey": "1234",
"validateCerts": false
},
{
"url": "https://router-3:5001",
"apiKey": "",
"validateCerts": true
}
]
}
Merge and apply the config? [y/n]:
2.4.11 - Use In-Stream Sessions
In-Stream sessions is a routing mode where the router keeps control of the session for the full session lifetime instead of only routing the session to the preferred CDN (or cache node) once. Technically it works by letting the client return to the router for manifest and segments and redirect each segment to the preferred CDN. This enables changing CDN in the middle of a session.
Configure In-Stream Sessions
In-Stream routing for all incoming requests can be enabled by running
$ confcli services.routing.translationFunctions.session "return set_session_type('instream')"
services.routing.translationFunctions.session = "return set_session_type('instream')"
See Session Translation Function for more details on controlling session types.
The following example illustrate the request flow for in-stream session
$ curl -i http://test-acd-router/content/playlist.m3u8
HTTP/1.1 302 Found
Access-Control-Allow-Origin: *
Content-Length: 0
Location: http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/playlist.m3u8
X-Service-Identity:
$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/playlist.m3u8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Length,Content-Range
Connection: keep-alive
Content-Length: 306
Content-Type: application/vnd.apple.mpegurl
Date: Fri, 31 Mar 2023 10:18:42 GMT
ETag: "5d711f08-132"
Last-Modified: Thu, 05 Sep 2019 14:43:20 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Service-Identity:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=320x180
abr_500k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360
abr_1000k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1700000,RESOLUTION=1280x720
abr_1700k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3300000,RESOLUTION=1280x720
abr_3300k.m3u8
$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/abr_500k.m3u8
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Content-Length,Content-Range
Connection: keep-alive
Content-Length: 276
Content-Type: application/vnd.apple.mpegurl
Date: Fri, 31 Mar 2023 12:02:04 GMT
ETag: "6426cbbc-114"
Last-Modified: Fri, 31 Mar 2023 12:02:04 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Service-Identity:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:1
#EXT-X-MEDIA-SEQUENCE:112583846
#EXTINF:0.834444,
abr_500k112583846.ts
#EXTINF:0.834444,
abr_500k112583847.ts
#EXTINF:0.834444,
abr_500k112583848.ts
#EXTINF:0.834444,
abr_500k112583849.ts
#EXTINF:0.834444,
abr_500k112583850.ts
$ curl -i http://test-acd-router/__s/test-acd-router-a4fd86-0000004f_WyIvY2RuL3BsYXlsaXN0Lm0zdTgiLDAsImRldmNkbjEiLCJkZXZjZG4xLnN0cmVhbXBpbG90LnR2Iiw4MCwiL2Nkbi9wbGF5bGlzdC5tM3U4IiwwLDE2ODAyNjQwOTNd_c1e3fc663a47156e0894b30eddf995bb/content/abr_500k112583846.ts
HTTP/1.1 302 Found
Access-Control-Allow-Origin: *
Content-Length: 0
Location: http://testcdn.tv/abr_500k112583846.ts
X-Service-Identity:
A Note on Confcli
Begin with configuring routing, classification and session groups in confcli, for example based on content types.
# Create a classifier for live sessions
$ confcli services.routing.classifiers -w
Running wizard for resource 'classifiers'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
classifiers : [
classifier can be one of
1: anonymousIp
2: asnIds
3: contentUrlPath
4: contentUrlQueryParameters
5: geoip
6: hostName
7: ipranges
8: random
9: regexMatcher
10: stringMatcher
11: subnet
12: userAgent
Choose element index or name: contentUrlPath
Adding a 'contentUrlPath' element
classifier : {
name (default: ): live
type (default: contentUrlPath): ⏎
inverted (default: False): ⏎
patternType (default: stringMatch): ⏎
pattern (default: ): *live*
}
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
Generated config:
{
"classifiers": [
{
"name": "live",
"type": "contentUrlPath",
"inverted": false,
"patternType": "stringMatch",
"pattern": "*live*"
}
]
}
Merge and apply the config? [y/n]: y
# Create a session group called "live" using the classifier
$ confcli services.routing.sessionGroups -w
Running wizard for resource 'sessionGroups'
Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string
sessionGroups : [
sessionGroup : {
name (default: ): live
classifiers : [
classifier (default: ): live
Add another 'classifier' element to array 'classifiers'? [y/N]: ⏎
]
}
Add another 'sessionGroup' element to array 'sessionGroups'? [y/N]: ⏎
]
Generated config:
{
"sessionGroups": [
{
"name": "live",
"classifiers": [
"live"
]
}
]
}
Merge and apply the config? [y/n]: y
# Make all sessions belonging to the session group "live" In-Stream sessions
$ confcli services.routing.translationFunctions.session "return set_session_type_if_in_group('instream', 'live')"
services.routing.translationFunctions.session = "return set_session_type_if_in_group('instream', 'live')"
Monitoring
If Grafana is installed together with the ESB-3024 installer, the number of started In-Stream sessions as well as currently active In-Stream sessions can be seen in a Dashboard.
Notes on Performance
Be aware that In-Stream sessions puts additional load on the request router since all clients continuously comes back to the router to fetch new manifests and to get segment redirects. The necessary router capacity therefore scaled both with number of started sessions and the average session length.
2.5 - Ready for Production?
2.5.1 - Setup for Redundancy
The Agile Director is designed to support the coexistence of multiple independent instances, facilitating either high-availability and/or horizontal scaling based on specific use cases and requirements. Each instance of the Director operates as a complete isolated entity, offering multiple solutions for redundancy. The choice between these solutions depends on the particular use case and requirements of the deployment.
A few select use-cases and example deployments are described in the sections that follow. Note however that this list is not exhaustive, and other approaches not listed here may be more applicable to a specific use-case.
Third-party load balancer
In this first scenario, multiple instances of the router are positioned behind an off-the-shelf load balancer. This could range from a simple
Nginx
proxy to a more sophisticated commercial load balancer, depending on the user’s specific needs and requirements.
DNS Round Robin
A straightforward alternative to deploying multiple instances of the router behind a load balancer is to employ round-robin DNS. In this approach, each router instance is associated with a distinct A record in DNS, all sharing the same domain name. Clients querying this DNS server receive multiple entries in response. Typically, clients utilize a round-robin algorithm to resolve the IP address of the router, although some clients might randomly select an address from the available servers.
While this method effectively distributes the load across multiple instances, it has a few drawbacks. First, clients are not guaranteed to use any specific algorithm for selecting the IP address. Second, due to DNS caching in the network and on the client’s device, modifications to the DNS record (e.g., taking a node out of service or adding additional nodes) will experience higher latency compared to some other techniques. Third, there is a dependency on the client being able to recognize this DNS server as authoritative. And fourth, this approach does not provide any means of high-availability. If a node is offline, requests to that node will fail.
VRRP
If horizontal scaling is not required, employing a shared Virtual IP Address
through the VRRP protocol may suffice. This can be easily configured on one or
more instances of the router by installing and setting up keepalived
. While the
specific details of keepalived
are beyond the scope of this document, it can
establish a Primary/Backup node configuration, where heartbeat packets and
server priority determine each node’s role. Using VRRP, a Virtual IP address
always points to the current primary node, and in the event of a primary node
failure, the remaining nodes elect a new primary node based on the predetermined
priority.
This solution has some drawbacks compared to others; the VIP may only be assigned to a single node at a time, rendering horizontal scaling impossible using this solution alone. Another drawback is that if the primary node fails, there will be a brief period, usually around one second, before the failure is detected and the VIP is reassigned.
This solution can be more effectively utilized as part of a larger combined solution in which several groups of nodes are employed. In each group, there is a Primary and Backup, and selection between the groups is handled via one of the other scaling solutions.
An Example Combined Approach Scenario
The following represents an example scenario where eight independent router nodes are utilized employing all three of the above approaches.
The scenario consists of four pairs of nodes, with each pair using VRRP to designate one node as Master and one as a Backup. In front of two pairs of pairs would sit two load balancers, each configured with the VIP address of each pair below. The two load balancers would then be placed into Round Robin DNS with the same FQDN.
Incoming requests would resolve the DNS record, yielding two servers. They would then send requests to each in turn. The load balancer at the end of those IP addresses would then select among the two VIP addresses below, and the request would be routed to the current Primary node in the group.
In this scenario, if any one of the primary nodes becomes offline, the VRRP protocol will move the VIP to the backup node. While that process is ongoing, the load balancer will detect that the VIP is unreachable, routing all traffic in the meantime to the VIP of the second pair. The DNS round-robin would be used to evenly distribute the traffic between the two load balancers.
2.5.2 - HTTPS Certificates
Configuration of ESB3024 Router is done through a REST API over HTTPS. While the router installer generates a self-signed certificate in order to enable the interface at all, this is not considered safe and secure so a properly generated certificate should be used instead.
For SSL to work, the router needs to have both an x509 certificate and a key in ASCII armored PEM format:
-----BEGIN PRIVATE KEY-----
[...]
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
The files can be either separate .crt
and .key
files or a combined .pem
file.
Simply copy the file(s) generated by your CA service, into the
/opt/edgeware/acd/ssl
folder on the host machine and they will automatically
be used by the router. The filenames must match the associated hostname, and
there’s currently no support for wildcard matching or multiple domains per
certificate. Several key/crt pairs can be placed in the folder in order to
support more than one domain name.