/** * Copyright 2022 Gravwell, Inc. All rights reserved. * * Contact: [legal@gravwell.io](mailto:legal@gravwell.io) * * This software may be modified and distributed under the terms of the MIT * license. See the LICENSE file for details. */ import { DataExplorerEntry } from './data-explorer-entry'; import { RawSearchMessageReceivedRequestEntriesWithinRangeChartRenderer } from './raw-search-message-received/request-entries-within-range/chart-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeFDGRenderer } from './raw-search-message-received/request-entries-within-range/fdg-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeGaugeRenderer } from './raw-search-message-received/request-entries-within-range/gauge-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeHeatmapRenderer } from './raw-search-message-received/request-entries-within-range/heatmap-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeHexRenderer } from './raw-search-message-received/request-entries-within-range/hex-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangePcapRenderer } from './raw-search-message-received/request-entries-within-range/pcap-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangePointToPointRenderer } from './raw-search-message-received/request-entries-within-range/point-to-point-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangePointmapRenderer } from './raw-search-message-received/request-entries-within-range/pointmap-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeRawRenderer } from './raw-search-message-received/request-entries-within-range/raw-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeStackGraphRenderer } from './raw-search-message-received/request-entries-within-range/stack-graph-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeTableRenderer } from './raw-search-message-received/request-entries-within-range/table-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeTextRenderer } from './raw-search-message-received/request-entries-within-range/text-renderer'; import { RawSearchMessageReceivedRequestEntriesWithinRangeWordcloudRenderer } from './raw-search-message-received/request-entries-within-range/wordcloud-renderer'; import { SearchEntry } from './search-entry'; import { SearchFilter } from './search-filter'; import { toSearchEntry } from './to-search-entry'; export type SearchEntries = | ChartSearchEntries | FDGSearchEntries | GaugeSearchEntries | NumberCardEntries | HeatmapSearchEntries | PointToPointSearchEntries | PointmapSearchEntries | RawSearchEntries | TextSearchEntries | StackGraphSearchEntries | TableSearchEntries | HexSearchEntries | PcapSearchEntries | WordcloudSearchEntries; export type ExplorerSearchEntries = SearchEntries & { explorerEntries: Array }; // TODO: Add render module to entries observable export interface BaseSearchEntries { filter?: SearchFilter; start: Date; end: Date; finished: boolean; additionalEntries: boolean; } export interface ChartSearchEntries extends BaseSearchEntries { type: 'chart'; // TODO names: Array; data: Array<{ timestamp: Date; values: Array; }>; } export const normalizeToChartSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeChartRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'chart', names: v.Entries?.Categories ?? [], data: (v.Entries?.Values ?? []).map(rawV => ({ timestamp: new Date(rawV.TS), values: rawV.Data, })), additionalEntries: v.AdditionalEntries, }); export interface FDGSearchEntries extends BaseSearchEntries { type: 'fdg'; // TODO nodes: Array; edges: Array; groups: Array; } export const normalizeToFDGSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeFDGRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'fdg', nodes: (v.Entries?.nodes ?? []).map(rawNode => ({ name: rawNode.name, groupIndex: rawNode.group, })), edges: (v.Entries?.links ?? []).map(rawEdge => ({ value: rawEdge.value, sourceNodeIndex: rawEdge.source, targetNodeIndex: rawEdge.target, })), groups: v.Entries?.groups ?? [], additionalEntries: v.AdditionalEntries, }); export interface FDGNode { name: string; groupIndex: number; } /** * Source and target nodes for an edge are represented by an index into the * parent node set */ export interface FDGEdge { value: number; /** Source index into the nodes list */ sourceNodeIndex: number; /** Target index into the nodes list */ targetNodeIndex: number; } export interface GaugeSearchEntries extends BaseSearchEntries { type: 'gauge'; data: Array<{ name: string; magnitude: number; min: number; max: number; }>; } /** Numbercard renderer is an alias of gauge */ export interface NumberCardEntries extends BaseSearchEntries { type: 'numbercard'; data: Array<{ name: string; magnitude: number; min: number; max: number; }>; } export const normalizeToGaugeSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeGaugeRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'gauge', data: (v.Entries ?? []).map(rawEntry => ({ name: rawEntry.Name, magnitude: rawEntry.Magnitude, min: rawEntry.Min, max: rawEntry.Max, })), additionalEntries: v.AdditionalEntries, }); export interface HeatmapSearchEntries extends BaseSearchEntries { type: 'heatmap'; // TODO data: Array; } export const normalizeToHeatmapSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeHeatmapRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'heatmap', data: (v.Entries ?? []).map(rawEntry => ({ latitude: rawEntry.Lat, longitude: rawEntry.Long, magnitude: rawEntry.Magnitude ?? null, })), additionalEntries: v.AdditionalEntries, }); export interface PointToPointSearchEntries extends BaseSearchEntries { type: 'point2point'; // TODO names: Array; data: Array<{ source: MapLocation; target: MapLocation; magnitude: number | null; values: Array; }>; } export const normalizeToPointToPointSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangePointToPointRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'point2point', names: v.ValueNames, data: (v.Entries ?? []).map(rawEntry => ({ source: { latitude: rawEntry.Src.Lat, longitude: rawEntry.Src.Long, }, target: { latitude: rawEntry.Dst.Lat, longitude: rawEntry.Dst.Long, }, magnitude: rawEntry.Magnitude ?? null, values: rawEntry.Values ?? [], })), additionalEntries: v.AdditionalEntries, }); export interface PointmapSearchEntries extends BaseSearchEntries { type: 'pointmap'; // TODO data: Array<{ location: MapLocation; metadata: Array<{ key: string; value: string; }>; }>; } export const normalizeToPointmapSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangePointmapRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'pointmap', data: (v.Entries ?? []).map(rawEntry => ({ location: { latitude: rawEntry.Loc.Lat, longitude: rawEntry.Loc.Long, }, metadata: (rawEntry.Metadata ?? []).map(rawMeta => ({ key: rawMeta.Key, value: rawMeta.Value, })), })), additionalEntries: v.AdditionalEntries, }); export interface MapLocation { latitude: number; longitude: number; } export interface RawSearchEntries extends BaseSearchEntries { type: 'raw'; // TODO names: Array; data: Array; /** Maps tag names to numeric IDs */ tags: { [tagname: string]: number }; } export const normalizeToRawSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeRawRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'raw', names: ['RAW'], data: (v.Entries ?? []).map(toSearchEntry), tags: v.Tags, additionalEntries: v.AdditionalEntries, }); export interface HexSearchEntries extends BaseSearchEntries { // hex entries are like raw entries type: 'hex'; // TODO names: Array; data: Array; } export const normalizeToHexSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeHexRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'hex', names: ['HEX'], data: (v.Entries ?? []).map(toSearchEntry), additionalEntries: v.AdditionalEntries, }); export interface TextSearchEntries extends BaseSearchEntries { type: 'text'; // TODO names: Array; data: Array; /** Maps tag names to numeric IDs */ tags: { [tagname: string]: number }; } export const normalizeToTextSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeTextRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'text', names: ['DATA'], data: (v.Entries ?? []).map(toSearchEntry), tags: v.Tags, additionalEntries: v.AdditionalEntries, }); export interface PcapSearchEntries extends BaseSearchEntries { // pcap entries are like text entries type: 'pcap'; // TODO names: Array; data: Array; } export const normalizeToPcapSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangePcapRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'pcap', names: ['PCAP'], data: (v.Entries ?? []).map(toSearchEntry), additionalEntries: v.AdditionalEntries, }); export interface StackGraphSearchEntries extends BaseSearchEntries { type: 'stackgraph'; // TODO data: Array<{ key: string; values: Array<{ label: string; value: number; }>; }>; } export const normalizeToStackGraphSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeStackGraphRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'stackgraph', data: (v.Entries ?? []).map(rawEntry => ({ key: rawEntry.Key, values: rawEntry.Values.map(rawValue => ({ label: rawValue.Label, value: rawValue.Value, })), })), additionalEntries: v.AdditionalEntries, }); export interface TableSearchEntries extends BaseSearchEntries { type: 'table'; // TODO columns: Array; rows: Array<{ timestamp: Date; values: Array; }>; } export const normalizeToTableSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeTableRenderer, ): Omit => ({ start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, type: 'table', columns: v.Entries?.Columns ?? [], rows: (v.Entries?.Rows ?? []).map(rawRow => ({ timestamp: new Date(rawRow.TS), values: rawRow.Row, })), additionalEntries: v.AdditionalEntries, }); export interface WordcloudSearchEntries extends BaseSearchEntries { type: 'wordcloud'; data: Array<{ name: string; magnitude: number; min: number; max: number; }>; } export const normalizeToWordcloudSearchEntries = ( v: RawSearchMessageReceivedRequestEntriesWithinRangeWordcloudRenderer, ): Omit => ({ type: 'wordcloud', start: new Date(v.EntryRange.StartTS), end: new Date(v.EntryRange.EndTS), finished: v.Finished, data: (v.Entries ?? []).map(value => ({ name: value.Name, magnitude: value.Magnitude, min: value.Min, max: value.Max, })), additionalEntries: v.AdditionalEntries, });