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.

  1. ID of the target report
  2. 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.

  1. Known Variables
  2. Unknown Variables
Important: The structure and resource schemas are subject to change. Please make sure you are referring to the correct documentation for your SevOne Data Insight version.
Note: The sole purpose of Report Linking is to link from Report A to Report B within SevOne Data Insight. It is not intended to link to any sources outside of SevOne Data Insight.

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.

  1. Create a JSON string for your desired facets with a valid schema.
  2. Use zlib deflate() to compress the string. https://zlib.net/feldspar.html
  3. Base64 encode the bytes returned from zlib deflate().
  4. Percent-encode the Base64 string.
  5. 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
Important: When using THIS, no number is required, so your timespan would be This week or This month.

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.

  1. 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.
  2. 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.