You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
5.1 KiB
237 lines
5.1 KiB
import { Collection, makeDBQ } from '../services/data_service'; |
|
|
|
import { Metric } from 'grafana-datasource-kit'; |
|
|
|
import * as _ from 'lodash'; |
|
|
|
let db = makeDBQ(Collection.ANALYTIC_UNITS); |
|
|
|
|
|
export const ANALYTIC_UNIT_TYPES = { |
|
pattern: [ |
|
{ |
|
name: 'General', |
|
value: 'GENERAL' |
|
}, |
|
{ |
|
name: 'Peaks', |
|
value: 'PEAK' |
|
}, |
|
{ |
|
name: 'Troughs', |
|
value: 'TROUGH' |
|
}, |
|
{ |
|
name: 'Jumps', |
|
value: 'JUMP' |
|
}, |
|
{ |
|
name: 'Drops', |
|
value: 'DROP' |
|
} |
|
], |
|
threshold: [ |
|
{ |
|
name: 'Threshold', |
|
value: 'THRESHOLD' |
|
} |
|
] |
|
}; |
|
|
|
export enum DetectorType { |
|
PATTERN = 'pattern', |
|
THRESHOLD = 'threshold' |
|
}; |
|
|
|
export type AnalyticUnitId = string; |
|
export enum AnalyticUnitStatus { |
|
READY = 'READY', |
|
PENDING = 'PENDING', |
|
LEARNING = 'LEARNING', |
|
SUCCESS = 'SUCCESS', |
|
FAILED = 'FAILED' |
|
} |
|
|
|
export type FindManyQuery = { |
|
name?: string, |
|
grafanaUrl?: string, |
|
panelId?: string, |
|
type?: string, |
|
metric?: Metric, |
|
alert?: boolean, |
|
id?: AnalyticUnitId, |
|
lastDetectionTime?: number, |
|
status?: AnalyticUnitStatus, |
|
error?: string, |
|
labeledColor?: string, |
|
deletedColor?: string, |
|
detectorType?: DetectorType, |
|
visible?: boolean |
|
}; |
|
|
|
|
|
export class AnalyticUnit { |
|
constructor( |
|
public name: string, |
|
public grafanaUrl: string, |
|
public panelId: string, |
|
public type: string, |
|
public metric?: Metric, |
|
public alert?: boolean, |
|
public id?: AnalyticUnitId, |
|
public lastDetectionTime?: number, |
|
public status?: AnalyticUnitStatus, |
|
public error?: string, |
|
public labeledColor?: string, |
|
public deletedColor?: string, |
|
public detectorType?: DetectorType, |
|
public visible?: boolean |
|
) { |
|
|
|
if(name === undefined) { |
|
throw new Error(`Missing field "name"`); |
|
} |
|
if(grafanaUrl === undefined) { |
|
throw new Error(`Missing field "grafanaUrl"`); |
|
} |
|
if(type === undefined) { |
|
throw new Error(`Missing field "type"`); |
|
} |
|
} |
|
|
|
public toObject() { |
|
let metric; |
|
if(this.metric !== undefined) { |
|
metric = this.metric.toObject(); |
|
} |
|
|
|
return { |
|
_id: this.id, |
|
name: this.name, |
|
grafanaUrl: this.grafanaUrl, |
|
panelId: this.panelId, |
|
type: this.type, |
|
metric, |
|
alert: this.alert, |
|
lastDetectionTime: this.lastDetectionTime, |
|
status: this.status, |
|
error: this.error |
|
}; |
|
} |
|
|
|
public toPanelObject() { |
|
return { |
|
id: this.id, |
|
name: this.name, |
|
type: this.type, |
|
alert: this.alert, |
|
labeledColor: this.labeledColor, |
|
deletedColor: this.deletedColor, |
|
detectorType: this.detectorType, |
|
visible: this.visible |
|
}; |
|
} |
|
|
|
static fromObject(obj: any): AnalyticUnit { |
|
if(obj === undefined) { |
|
throw new Error('obj is undefined'); |
|
} |
|
let metric: Metric; |
|
if(obj.metric !== undefined) { |
|
metric = Metric.fromObject(obj.metric); |
|
} |
|
return new AnalyticUnit( |
|
obj.name, |
|
obj.grafanaUrl, |
|
obj.panelId, |
|
obj.type, |
|
metric, |
|
obj.alert, |
|
obj._id, |
|
obj.lastDetectionTime, |
|
obj.status as AnalyticUnitStatus, |
|
obj.error, |
|
obj.labeledColor, |
|
obj.deletedColor, |
|
obj.detectorType, |
|
obj.visible |
|
); |
|
} |
|
|
|
} |
|
|
|
|
|
export async function findById(id: AnalyticUnitId): Promise<AnalyticUnit> { |
|
let obj = await db.findOne(id); |
|
if(obj === null) { |
|
return null; |
|
} |
|
return AnalyticUnit.fromObject(obj); |
|
} |
|
|
|
export async function findMany(query: FindManyQuery): Promise<AnalyticUnit[]> { |
|
let analyticUnits = await db.findMany(query); |
|
if(analyticUnits === null) { |
|
return []; |
|
} |
|
return analyticUnits.map(AnalyticUnit.fromObject); |
|
} |
|
|
|
|
|
/** |
|
* Creates and updates new unit.id |
|
* |
|
* @param unit to create |
|
* @returns unit.id |
|
*/ |
|
export async function create(unit: AnalyticUnit): Promise<AnalyticUnitId> { |
|
let obj = unit.toObject(); |
|
return db.insertOne(obj); |
|
} |
|
|
|
export async function remove(id: AnalyticUnitId): Promise<void> { |
|
// TODO: remove it`s segments |
|
// TODO: remove it`s cache |
|
await db.removeOne(id); |
|
} |
|
|
|
export async function update(id: AnalyticUnitId, unit: AnalyticUnit) { |
|
const updateObj = { |
|
name: unit.name, |
|
labeledColor: unit.labeledColor, |
|
deletedColor: unit.deletedColor, |
|
visible: unit.visible |
|
}; |
|
|
|
return db.updateOne(id, updateObj); |
|
} |
|
|
|
export async function setStatus(id: AnalyticUnitId, status: string, error?: string) { |
|
return db.updateOne(id, { status, error }); |
|
} |
|
|
|
export async function setDetectionTime(id: AnalyticUnitId, lastDetectionTime: number) { |
|
return db.updateOne(id, { lastDetectionTime }); |
|
} |
|
|
|
export async function setAlert(id: AnalyticUnitId, alert: boolean) { |
|
return db.updateOne(id, { alert }); |
|
} |
|
|
|
export async function setMetric(id: AnalyticUnitId, metric: Metric) { |
|
return db.updateOne(id, { metric }); |
|
} |
|
|
|
export function getDetectorByType(analyticUnitType: string): DetectorType { |
|
let detector; |
|
_.forOwn(ANALYTIC_UNIT_TYPES, (types, detectorType) => { |
|
if(_.find(types, { value: analyticUnitType }) !== undefined) { |
|
detector = detectorType; |
|
} |
|
}); |
|
|
|
if(detector === undefined) { |
|
throw new Error(`Can't find detector for analytic unit of type "${analyticUnitType}"`); |
|
} |
|
return detector; |
|
}
|
|
|