SevOne Data Insight Report Linking URL Specification Guide
About
SevOne Data Insight reports can link to one another via a concept called Report Linking. A report link is made of two parts.
- ID of the target report
- A data payload to send to the target report
The payload is an array of facets. Reports read the payload and inject it into the underlying report runtime.
`id`: `Number`
`payload`: `Array<Facet>`
Once in the report runtime, the payload interacts with report Variables and widgets as part of the facet system. Its effect on report variables is in two forms.
- Known Variables
- Unknown Variables
URL Structure
The URL structure is in the following format.
http://<SevOne Data Insight host>/reports/<report id>/<tab number>?variables=<facet encoding>
Known Variables
Any data in a report link that matches a known report variable only takes affect if there is a pre-existing report variable of that type in the target report. For example, a report link with a device in it is only seen by the widgets if there is already a device variable. Known variables include those that are available to a user to add to a report, such as device, object, etc.
Unknown Variables
Any custom data in a report link that does not match a known report variable, always take affect. It is available to all widgets, but the same facet restrictions apply. A widget only receives a facet that it has registered as consumable. This is useful for custom facets that a widget might want to implement as part of a larger solution package. This data though is not available for display from report variables.
Process to Generate a URL
Because a report link contains an array of facets, these links can get very long. In order to cut down on this length so as to not hit general URL character length restrictions, run a variety of transformations before generating the final URL as part of an encoding step, and then decode them in the target report.
- Create a JSON string for your desired facets with a valid schema.
- Use zlib deflate() to compress the string. https://zlib.net/feldspar.html
- Base64 encode the bytes returned from zlib deflate().
- Percent-encode the Base64 string.
- Use the percent-encoded string in the variables parameter of SevOne Data Insight URL.
Note: For additional details on percent-encoding, please refer to https://en.wikipedia.org/wiki/Percent-encoding.
Anatomy of the JSON Schema
Bare Facet Structure
Basic top-level structure of a facet is in two parts. First part describes the structure of the data using JSON-schema, and the second part is the data itself.
{
"schema": <FACET SCHEMA>,
"data": <JSON DATA USING SCHEMA>
}
Resource Facet
The resource facet is the main type of facet that is typically used. This facet can describe any type of SevOne metadata you would like to specify.
{
"$id": "insight-resources",
"definitions": {
"RESOURCE_TYPES": {
"type": 'object',
"properties": {
"type": {
"const": "<RESOURCE_TYPE>"
},
"resources": {
"type": "array",
"items": {
<RESOURCE SCHEMA>
}
}
},
"required": [ 'type', 'resources' ]
}
},
"anyOf": [
{
"$ref": "<string referencing path to definition>"
}
]
}
Timespan Facet
The timespan facet describes either a relative timeframe for the report or a specific timespan.
{
"schema": {
"$id": "insight-timespan",
"oneOf": [
{
"type": "object",
"properties": {
"startTime": {
"type": "number",
"description": "Start time."
},
"endTime": {
"type": "number",
"description": "End time."
},
"timezone": {
"type": "string"
}
},
"required": [
"startTime",
"endTime"
]
},
{
"type": "object",
"properties": {
"label": {
"type": "string"
},
"timespan": {
"type": "string"
},
"timezone": {
"type": "string"
}
},
"required": [
"label",
"timespan"
]
}
]
},
"data": {
"timespan": <RELATIVE TIMESPAN>>,
"label": ""
}
}
For a specific time range, your data section would include startTime and endTime in Unix epochs instead of timespan and label. Units are in milliseconds epoch when specifying the start/end times.
Valid Relative Timespans
The relative timespans are structured in 3 parts.
Reference Period
- THIS, PAST, LAST, and NEXT
Number of <Time Unit>
- An Integer, 1 is implied if omitted
Time Unit (singular and plural supported)
- second(s), minute(s), hour(s), day(s), week(s), month(s), quarter(s), year(s)
Examples
- Past 4 Hours
- Past 2 Weeks
- Next Month
- Last 6 Weeks
Also, notice that oneOf is specified instead of anyOf, meaning that exactly one of these specifications is required, effectively giving you two options for you to specify time with here.
Datasource Facet
When your instance is connected to many datasources, you typically have to specify which data source you would like the link to be using. The first datasource is implied if this facet is omitted from the link variable.
{
"schema": {
"$id": "insight-datasource",
"type": "object",
"properties": {
"datasource": {
"type": "number"
}
},
"required": [
"datasource"
]
},
"data": {
"datasource": 2
}
}
Facet Resource Schemas
Facets are a core data structure in SevOne Data Insight based on the WDK's concept of the same name. Facets consist of two parts.
- A JSON Schema (https://json-schema.org) - JSON Schema is used to describe and validate the facet structures sent to and from SevOne Data Insight.
- A payload that satisfies the schema.
The goal of a facet is to facilitate data flow and transfer using a typed system at runtime. Facets are the foundation in systems such as widget linking, report linking, and report variables. As that list implies, facets are most heavily used as a contract mechanism between a SevOne Data Insight report and WDK widgets.
Standard Resource Facet Definitions
The following examples are showcased using Javascript/TypeScript (https://www.typescriptlang.org/).
deviceGroupSchema
const deviceGroupSchema = {
type: 'object',
properties: {
value: {
type: 'array',
items: {
type: 'string'
}
}
},
required: [ 'value' ]
} as const;
deviceSchema
const deviceSchema = {
type: 'object',
properties: {
value: {
type: 'string'
}
},
required: [ 'value' ]
} as const;
flowDeviceSchema
const flowDeviceSchema = {
type: 'object',
properties: {
value: {
type: 'string'
}
},
required: [ 'value' ]
} as const;
flowInterfaceSchema
const flowInterfaceSchema = {
type: 'object',
properties: {
value: {
type: 'number'
},
flowDevice: flowDeviceSchema
},
required: [ 'value', 'flowDevice' ]
} as const;
indicatorSchema
const indicatorSchema = {
type: 'object',
properties: {
deviceName: {
type: 'string'
},
objectName: {
type: 'string'
},
indicatorType: indicatorTypeSchema
},
required: [ 'deviceName', 'objectName', 'indicatorType' ]
} as const;
indicatorTypeSchema
const indicatorTypeSchema = {
type: 'object',
properties: {
value: {
type: 'string'
},
objectType: objectTypeSchema
},
required: [ 'value', 'objectType' ]
} as const;
metadataSchema
const metadataSchema = {
$id: 'insight-metadata',
type: 'object',
properties: {
entityType: {
type: 'string',
enum: [ 'OBJECT' ]
},
metadataFilter: {
type: 'array',
items: {
type: 'object',
properties: {
attributeName: {
type: 'object',
properties: {
attribute: {
type: 'string'
},
namespace: {
type: 'string'
}
},
required: [ 'attribute', 'namespace' ]
},
attributeValue: {
type: 'string'
}
},
required: [ 'attributeName', 'attributeValue' ]
}
}
},
required: [ 'entityType', 'metadataFilter' ]
} as const;
objectGroupSchema
const objectGroupSchema = {
type: 'object',
properties: {
value: {
type: 'string'
},
objectClass: {
type: 'object',
properties: {
value: {
type: 'string'
}
},
required: [ 'value' ]
}
},
required: [ 'value', 'objectClass' ]
} as const;
objectSchema
const objectSchema = {
type: 'object',
properties: {
value: {
type: 'string'
},
device: deviceSchema,
plugin: pluginSchema
},
required: [ 'value', 'device', 'plugin' ]
} as const;
objectTypeSchema
const objectTypeSchema = {
type: 'object',
properties: {
value: {
type: 'array',
items: {
type: 'string'
}
},
plugin: pluginSchema
},
required: [ 'value', 'plugin' ]
} as const;
pluginSchema
const pluginSchema = {
type: 'object',
properties: {
value: {
type: 'string'
}
},
required: [ 'value' ]
} as const;
Schema Names
const indicatorSchema = {
type: 'object',
properties: {
deviceName: {
type: 'string'
},
objectName: {
type: 'string'
},
indicatorType: indicatorTypeSchema
},
required: [ 'deviceName', 'objectName', 'indicatorType' ]
} as const;
Examples
While creating these structures is best done programmatically, here are a few examples of the structures created manually for demonstration of the core concepts.
Create a Device Facet
A device facet is one of the simplest facets. It does not reference any of the other facets and serves as a good introduction to reading JSON schema definitions. The following example shows the end-product and its line-by-line description.
Example: Device Facet
1 [{
2 "schema": {
3 "$id": "insight-resources",
4 "definitions": {
5 "DEVICE": {
6 "type": "object",
7 "properties": {
8 "type": {
9 "const": "DEVICE"
10 },
11 "resources": {
12 "type": "array",
13 "items": {
14 "type": "object",
15 "properties": {
16 "value": {
17 "type": "string"
18 }
19 },
20 "required": [
21 "value"
22 ]
23 }
24 }
25 },
26 "required": [
27 "type",
28 "resources"
29 ]
30 }
31 },
32 "anyOf": [
33 {
34 "$ref": "#/definitions/DEVICE"
35 }
36 ]
37 },
38 "data": {
39 "type": "DEVICE",
40 "resources": [
41 {
42 "value": "NYC-EdgeRouter"
43 }
44 ]
45 }
46 }]
- Line 1 - opens a JSON object which holds the schema and the data. The JSON array surrounds the object. It allows you to combine multiple facets, such as timespan or datasource facets. These are showcased later.
- Line 2-4 - starts the schema object, defines it as resource schema by setting $id to insight-resources, and opens the definitions section.
- Line 5 - starts the DEVICE JSON object. This DEVICE keyword is referenced later in $ref. This object is also used to describe the device resource structure.
- Line 6-10 - type and properties, reserved words for JSON-Schema. Type explains that the section needs to be a JSON object in this case. Properties outlines the fields/properties available within the object along with another field called type with const DEVICE.
- Line 11-19 - defines the need for a resources object which needs to be a JSON array containing JSON objects that contain the property, value with a type of string.
- Line 20-22 - sets value to be a required property of these object items within the resources array.
- Line 26-29 - sets type and resources to be required properties of the DEVICE object.
- Line 32-36 - anyOf reference to the definition. For additional details, please refer to https://json-schema.org/understanding-json-schema/reference/combining.html.
- Line 38- data object conforming to the schema defined in definitions.
Create an Indicator Facet
The indicator facet includes the most references to other facet types so it is the most verbose in many cases. In this facet, you send a device name, object name, and indicator type – however, some of these facets also depend on other facets. The following example shows the end-product and its line-by-line description.
- Device Name: NYC-EdgeRouter
- Object Name: Eth0
- IndicatorType: s1_totalHCOctets
Example: Indicator Facet
1 [
2 {
3 "schema": {
4 "$id": "insight-resources",
5 "definitions": {
6 "INDICATOR": {
7 "type": "object",
8 "properties": {
9 "type": {
10 "const": "INDICATOR"
11 },
12 "resources": {
13 "type": "array",
14 "items": {
15 "type": "object",
16 "properties": {
17 "deviceName": {
18 "type": "string"
19 },
20 "objectName": {
21 "type": "string"
22 },
23 "indicatorType": {
24 "type": "object",
25 "properties": {
26 "value": {
27 "type": "string"
28 },
29 "objectType": {
30 "type": "object",
31 "properties": {
32 "value": {
33 "type": "array",
34 "items": {
35 "type": "string"
36 }
37 },
38 "plugin": {
39 "type": "object",
40 "properties": {
41 "value": {
42 "type": "string"
43 }
44 },
45 "required": [
46 "value"
47 ]
48 }
49 },
50 "required": [
51 "value",
52 "plugin"
53 ]
54 }
55 },
56 "required": [
57 "value",
58 "objectType"
59 ]
60 }
61 },
62 "required": [
63 "deviceName",
64 "objectName",
65 "indicatorType"
66 ]
67 }
68 }
69 },
70 "required": [
71 "type",
72 "resources"
73 ]
74 }
75 },
76 "anyOf": [
77 {
78 "$ref": "#/definitions/INDICATOR"
79 }
80 ]
81 },
82 "data": {
83 "type": "INDICATOR",
84 "resources": [
85 {
86 "deviceName": "NYC-EdgeRouter",
87 "objectName": "Eth0",
88 "indicatorType": {
89 "value": "s1_totalHCOctets",
90 "objectType": {
91 "value": [
92 "Interface"
93 ],
94 "plugin": {
95 "value": "SNMP"
96 }
97 }
98 }
99 }
100 ]
101 }
102 }
103 ]
- Line 1-22 – similar to Device Facet example above, this starts a new insight-resource schema and defines the first few properties of the objects in the resources array. deviceName and objectName are just straightforward strings.
- Line 23-61 – defines the indicator type structure. This structure becomes more verbose than previous example because it references other types of schemas within. First schema referenced is the objectType schema, which then in turn, references the indicatorType schema that finally references the plugin schema. Please refer to the schema definitions in the section above to see how they fit in here. This is a good example why generating these schemas is best done programmatically, using the schema definitions.
- Line 62-66 – defines the required fields for each object in the resources array defined in line 14. In this case, each object in the array needs to have deviceName, objectName, and indicatorType properties.
- Line 70-73 – defines type and resources to be required fields for the INDICATOR object defined (starting on line 6).
- Line 76-80 – sets the anyOf definition for the schema referencing #/definitions/INDICATOR above.
- Line 81 – closes the schema object.
- Line 82-101 – second part of the facet structure, an object with the name data. type is defined as INDICATOR referencing the schema above. It defines the resources array with an object that includes the fields required by the schema definition above.
Combine Facets
Combine Facets create a payload that contains both a device resource facet and a timespan facet. The process remains the same, except this time you are including two objects in the main array instead of a single object like the examples above.
Example: Combined Facets - Device Resource facet & Timespan facet
[
{
"schema": {
"$id": "insight-resources",
"definitions": {
"DEVICE": {
"type": "object",
"properties": {
"type": {
"const": "DEVICE"
},
"resources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
}
},
"required": [
"value"
]
}
}
},
"required": [
"type",
"resources"
]
}
},
"anyOf": [
{
"$ref": "#/definitions/DEVICE"
}
]
},
"data": {
"type": "DEVICE",
"resources": [
{
"value": "NYC-EdgeRouter"
}
]
}
},
{
"schema": {
"$id": "insight-timespan",
"oneOf": [
{
"type": "object",
"properties": {
"startTime": {
"type": "number",
"description": "Start time."
},
"endTime": {
"type": "number",
"description": "End time."
},
"timezone": {
"type": "string"
}
},
"required": [
"startTime",
"endTime"
]
},
{
"type": "object",
"properties": {
"label": {
"type": "string"
},
"timespan": {
"type": "string"
},
"timezone": {
"type": "string"
}
},
"required": [
"label",
"timespan"
]
}
]
},
"data": {
"label": "Past 8 hours",
"timespan": "PAST_8HOURS",
"timezone": "America/New_York"
}
}
]
This example includes two objects in the top-level array. Each object has a schema describing itself, and a data section with the actual information requested.
Terms
- JSON Schema
- Used to describe and validate the facet structures sent to and from SevOne Data Insight. JSON Schema (https://json-schema.org)
- Facets
- A JSON parcel of information used to send data to and from SevOne Data Insight reports and widgets.