Alexey Velikiy
6 years ago
committed by
GitHub
19 changed files with 846 additions and 753 deletions
@ -1,30 +0,0 @@ |
|||||||
import { getJsonDataSync, writeJsonDataSync } from '../services/json_service'; |
|
||||||
import { METRICS_PATH } from '../config'; |
|
||||||
|
|
||||||
import * as crypto from 'crypto'; |
|
||||||
|
|
||||||
import * as path from 'path'; |
|
||||||
|
|
||||||
|
|
||||||
function saveTargets(targets) { |
|
||||||
let metrics = []; |
|
||||||
for (let target of targets) { |
|
||||||
metrics.push(saveTarget(target)); |
|
||||||
} |
|
||||||
return metrics; |
|
||||||
} |
|
||||||
|
|
||||||
function saveTarget(target) { |
|
||||||
//const md5 = crypto.createHash('md5')
|
|
||||||
const targetId = crypto.createHash('md5').update(JSON.stringify(target)).digest('hex'); |
|
||||||
let filename = path.join(METRICS_PATH, `${targetId}.json`); |
|
||||||
writeJsonDataSync(filename, target); |
|
||||||
return targetId; |
|
||||||
} |
|
||||||
|
|
||||||
function getTarget(targetId) { |
|
||||||
let filename = path.join(METRICS_PATH, `${targetId}.json`); |
|
||||||
return getJsonDataSync(filename); |
|
||||||
} |
|
||||||
|
|
||||||
export { saveTargets, getTarget } |
|
@ -1,77 +0,0 @@ |
|||||||
import { getJsonDataSync, writeJsonDataSync } from '../services/json_service'; |
|
||||||
import { AnalyticUnitId, findById, save } from '../models/analytic_unit'; |
|
||||||
import { SEGMENTS_PATH } from '../config'; |
|
||||||
|
|
||||||
import * as _ from 'lodash'; |
|
||||||
|
|
||||||
import * as path from 'path'; |
|
||||||
import * as fs from 'fs'; |
|
||||||
|
|
||||||
|
|
||||||
export function getLabeledSegments(id: AnalyticUnitId) { |
|
||||||
let filename = path.join(SEGMENTS_PATH, `${id}_labeled.json`); |
|
||||||
|
|
||||||
if(!fs.existsSync(filename)) { |
|
||||||
return []; |
|
||||||
} else { |
|
||||||
let segments = getJsonDataSync(filename); |
|
||||||
for(let segment of segments) { |
|
||||||
if(segment.labeled === undefined) { |
|
||||||
segment.labeled = false; |
|
||||||
} |
|
||||||
} |
|
||||||
return segments; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export function getPredictedSegments(id: AnalyticUnitId) { |
|
||||||
let filename = path.join(SEGMENTS_PATH, `${id}_segments.json`); |
|
||||||
|
|
||||||
let jsonData; |
|
||||||
try { |
|
||||||
jsonData = getJsonDataSync(filename); |
|
||||||
} catch(e) { |
|
||||||
console.error(e.message); |
|
||||||
jsonData = []; |
|
||||||
} |
|
||||||
return jsonData; |
|
||||||
} |
|
||||||
|
|
||||||
export function saveSegments(id: AnalyticUnitId, segments) { |
|
||||||
let filename = path.join(SEGMENTS_PATH, `${id}_labeled.json`); |
|
||||||
|
|
||||||
try { |
|
||||||
return writeJsonDataSync(filename, _.uniqBy(segments, 'start')); |
|
||||||
} catch(e) { |
|
||||||
console.error(e.message); |
|
||||||
throw new Error('Can`t write to db'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export function insertSegments(id: AnalyticUnitId, addedSegments, labeled: boolean) { |
|
||||||
// Set status
|
|
||||||
let info = findById(id); |
|
||||||
let segments = getLabeledSegments(id); |
|
||||||
|
|
||||||
let nextId = info.nextId; |
|
||||||
let addedIds = [] |
|
||||||
for (let segment of addedSegments) { |
|
||||||
segment.id = nextId; |
|
||||||
segment.labeled = labeled; |
|
||||||
addedIds.push(nextId); |
|
||||||
nextId++; |
|
||||||
segments.push(segment); |
|
||||||
} |
|
||||||
info.nextId = nextId; |
|
||||||
saveSegments(id, segments); |
|
||||||
save(id, info); |
|
||||||
return addedIds; |
|
||||||
} |
|
||||||
|
|
||||||
export function removeSegments(id: AnalyticUnitId, removedSegments) { |
|
||||||
let segments = getLabeledSegments(id); |
|
||||||
for (let segmentId of removedSegments) { |
|
||||||
segments = segments.filter(el => el.id !== segmentId); |
|
||||||
} |
|
||||||
saveSegments(id, segments); |
|
||||||
} |
|
@ -1,84 +0,0 @@ |
|||||||
import { getJsonDataSync, writeJsonDataSync } from '../services/json_service' |
|
||||||
import { ANALYTIC_UNITS_PATH } from '../config' |
|
||||||
|
|
||||||
import * as crypto from 'crypto'; |
|
||||||
|
|
||||||
import * as path from 'path' |
|
||||||
import * as fs from 'fs' |
|
||||||
|
|
||||||
|
|
||||||
export type Datasource = { |
|
||||||
method: string, |
|
||||||
data: Object, |
|
||||||
params: Object, |
|
||||||
type: string, |
|
||||||
url: string |
|
||||||
} |
|
||||||
|
|
||||||
export type Metric = { |
|
||||||
datasource: string, |
|
||||||
targets: string[] |
|
||||||
} |
|
||||||
|
|
||||||
export type AnalyticUnitId = string; |
|
||||||
|
|
||||||
export type AnalyticUnit = { |
|
||||||
id?: AnalyticUnitId, |
|
||||||
name: string, |
|
||||||
panelUrl: string, |
|
||||||
type: string, |
|
||||||
metric: Metric, |
|
||||||
datasource: Datasource |
|
||||||
status: string, |
|
||||||
error?: string, |
|
||||||
lastPredictionTime: number, |
|
||||||
nextId: number |
|
||||||
} |
|
||||||
|
|
||||||
export function createItem(item: AnalyticUnit): AnalyticUnitId { |
|
||||||
const hashString = item.name + (new Date()).toString(); |
|
||||||
const newId: AnalyticUnitId = crypto.createHash('md5').update(hashString).digest('hex'); |
|
||||||
let filename = path.join(ANALYTIC_UNITS_PATH, `${newId}.json`); |
|
||||||
if(fs.existsSync(filename)) { |
|
||||||
throw new Error(`Can't create item with id ${newId}`); |
|
||||||
} |
|
||||||
save(newId, item); |
|
||||||
item.id = newId; |
|
||||||
return newId; |
|
||||||
} |
|
||||||
|
|
||||||
export function remove(id: AnalyticUnitId) { |
|
||||||
let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`); |
|
||||||
fs.unlinkSync(filename); |
|
||||||
} |
|
||||||
|
|
||||||
export function save(id: AnalyticUnitId, unit: AnalyticUnit) { |
|
||||||
let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`); |
|
||||||
return writeJsonDataSync(filename, unit); |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: make async
|
|
||||||
export function findById(id: AnalyticUnitId): AnalyticUnit { |
|
||||||
let filename = path.join(ANALYTIC_UNITS_PATH, `${id}.json`); |
|
||||||
if(!fs.existsSync(filename)) { |
|
||||||
throw new Error(`Can't find Analytic Unit with id ${id}`); |
|
||||||
} |
|
||||||
return getJsonDataSync(filename); |
|
||||||
} |
|
||||||
|
|
||||||
export function setStatus(predictorId: AnalyticUnitId, status: string, error?: string) { |
|
||||||
let info = findById(predictorId); |
|
||||||
info.status = status; |
|
||||||
if(error !== undefined) { |
|
||||||
info.error = error; |
|
||||||
} else { |
|
||||||
info.error = ''; |
|
||||||
} |
|
||||||
save(predictorId, info); |
|
||||||
} |
|
||||||
|
|
||||||
export function setPredictionTime(id: AnalyticUnitId, time: number) { |
|
||||||
let info = findById(id); |
|
||||||
info.lastPredictionTime = time; |
|
||||||
save(id, info); |
|
||||||
} |
|
@ -0,0 +1,98 @@ |
|||||||
|
import { Metric } from './metric_model'; |
||||||
|
import { Collection, makeDBQ } from '../services/data_service'; |
||||||
|
|
||||||
|
|
||||||
|
let db = makeDBQ(Collection.ANALYTIC_UNITS); |
||||||
|
|
||||||
|
|
||||||
|
export type AnalyticUnitId = string; |
||||||
|
|
||||||
|
export class AnalyticUnit { |
||||||
|
constructor( |
||||||
|
public name: string, |
||||||
|
public panelUrl: string, |
||||||
|
public type: string, |
||||||
|
public metric: Metric, |
||||||
|
public id?: AnalyticUnitId, |
||||||
|
public lastPredictionTime?: number, |
||||||
|
public status?: string, |
||||||
|
public error?: string, |
||||||
|
) { |
||||||
|
if(name === undefined) { |
||||||
|
throw new Error(`Missing field "name"`); |
||||||
|
} |
||||||
|
if(panelUrl === undefined) { |
||||||
|
throw new Error(`Missing field "panelUrl"`); |
||||||
|
} |
||||||
|
if(type === undefined) { |
||||||
|
throw new Error(`Missing field "type"`); |
||||||
|
} |
||||||
|
if(metric === undefined) { |
||||||
|
throw new Error(`Missing field "metric"`); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public toObject() { |
||||||
|
return { |
||||||
|
_id: this.id, |
||||||
|
name: this.name, |
||||||
|
panelUrl: this.panelUrl, |
||||||
|
type: this.type, |
||||||
|
metric: this.metric.toObject(), |
||||||
|
lastPredictionTime: this.lastPredictionTime, |
||||||
|
status: this.status, |
||||||
|
error: this.error |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
static fromObject(obj: any): AnalyticUnit { |
||||||
|
if(obj === undefined) { |
||||||
|
throw new Error('obj is undefined'); |
||||||
|
} |
||||||
|
return new AnalyticUnit( |
||||||
|
obj.name, |
||||||
|
obj.panelUrl, |
||||||
|
obj.type, |
||||||
|
Metric.fromObject(obj.metric), |
||||||
|
obj.status, |
||||||
|
obj.lastPredictionTime, |
||||||
|
obj._id, |
||||||
|
obj.error, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
export async function findById(id: AnalyticUnitId): Promise<AnalyticUnit> { |
||||||
|
return AnalyticUnit.fromObject(await db.findOne(id)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates and updates new unit.id |
||||||
|
* |
||||||
|
* @param unit to create |
||||||
|
* @returns unit.id |
||||||
|
*/ |
||||||
|
export async function create(unit: AnalyticUnit): Promise<AnalyticUnitId> { |
||||||
|
var obj = unit.toObject(); |
||||||
|
var r = await db.insertOne(obj); |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
export async function remove(id: AnalyticUnitId): Promise<void> { |
||||||
|
await db.removeOne(id); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
export async function update(id: AnalyticUnitId, unit: AnalyticUnit) { |
||||||
|
return db.updateOne(id, unit); |
||||||
|
} |
||||||
|
|
||||||
|
export async function setStatus(id: AnalyticUnitId, status: string, error?: string) { |
||||||
|
return db.updateOne(id, { status, error }); |
||||||
|
} |
||||||
|
|
||||||
|
export async function setPredictionTime(id: AnalyticUnitId, lastPredictionTime: number) { |
||||||
|
return db.updateOne(id, { lastPredictionTime }); |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
export class Metric { |
||||||
|
constructor(public datasource: string, public targets: any[]) { |
||||||
|
if(datasource === undefined) { |
||||||
|
throw new Error('datasource is undefined'); |
||||||
|
} |
||||||
|
if(targets === undefined) { |
||||||
|
throw new Error('targets is undefined'); |
||||||
|
} |
||||||
|
if(targets.length === 0) { |
||||||
|
throw new Error('targets is empty'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public toObject() { |
||||||
|
return { |
||||||
|
datasource: this.datasource, |
||||||
|
targets: this.targets |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
static fromObject(obj: any): Metric { |
||||||
|
if(obj === undefined) { |
||||||
|
throw new Error('obj is undefined'); |
||||||
|
} |
||||||
|
return new Metric( |
||||||
|
obj.datasource, |
||||||
|
obj.targets |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
@ -0,0 +1,87 @@ |
|||||||
|
import { AnalyticUnitId } from './analytic_unit_model'; |
||||||
|
|
||||||
|
import { Collection, makeDBQ } from '../services/data_service'; |
||||||
|
|
||||||
|
let db = makeDBQ(Collection.SEGMENTS); |
||||||
|
|
||||||
|
|
||||||
|
export type SegmentId = string; |
||||||
|
|
||||||
|
export class Segment { |
||||||
|
constructor( |
||||||
|
public analyticUnitId: AnalyticUnitId, |
||||||
|
public from: number, |
||||||
|
public to: number, |
||||||
|
public labeled: boolean, |
||||||
|
public id?: SegmentId |
||||||
|
) { |
||||||
|
if(analyticUnitId === undefined) { |
||||||
|
throw new Error('AnalyticUnitId is undefined'); |
||||||
|
} |
||||||
|
if(from === undefined) { |
||||||
|
throw new Error('from is undefined'); |
||||||
|
} |
||||||
|
if(isNaN(from)) { |
||||||
|
throw new Error('from is NaN'); |
||||||
|
} |
||||||
|
if(to === undefined) { |
||||||
|
throw new Error('to is undefined'); |
||||||
|
} |
||||||
|
if(isNaN(to)) { |
||||||
|
throw new Error('to is NaN'); |
||||||
|
} |
||||||
|
if(labeled === undefined) { |
||||||
|
throw new Error('labeled is undefined'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public toObject() { |
||||||
|
return { |
||||||
|
_id: this.id, |
||||||
|
analyticUnitId: this.analyticUnitId, |
||||||
|
from: this.from, |
||||||
|
to: this.to, |
||||||
|
labeled: this.labeled |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
static fromObject(obj: any): Segment { |
||||||
|
if(obj === undefined) { |
||||||
|
throw new Error('obj is undefined'); |
||||||
|
} |
||||||
|
return new Segment( |
||||||
|
obj.analyticUnitId,
|
||||||
|
+obj.from, +obj.to, |
||||||
|
obj.labeled, obj._id |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export type FindManyQuery = { |
||||||
|
timeFromGTE?: number, |
||||||
|
timeToLTE?: number, |
||||||
|
intexGT?: number |
||||||
|
} |
||||||
|
|
||||||
|
export async function findMany(id: AnalyticUnitId, query: FindManyQuery): Promise<Segment[]> { |
||||||
|
var dbQuery: any = { analyticUnitId: id }; |
||||||
|
if(query.timeFromGTE !== undefined) { |
||||||
|
dbQuery.from = { $gte: query.timeFromGTE }; |
||||||
|
} |
||||||
|
if(query.timeToLTE !== undefined) { |
||||||
|
dbQuery.to = { $lte: query.timeToLTE }; |
||||||
|
} |
||||||
|
let segs = await db.findMany(dbQuery); |
||||||
|
if(segs === null) { |
||||||
|
return []; |
||||||
|
} |
||||||
|
return segs.map(Segment.fromObject); |
||||||
|
} |
||||||
|
|
||||||
|
export async function insertSegments(segments: Segment[]) { |
||||||
|
return db.insertMany(segments.map(s => s.toObject())); |
||||||
|
} |
||||||
|
|
||||||
|
export function removeSegments(idsToRemove: SegmentId[]) { |
||||||
|
return db.removeMany(idsToRemove); |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
import { AnalyticUnitId } from "./analytic_unit_model"; |
||||||
|
|
||||||
|
|
||||||
|
export type TaskId = string; |
||||||
|
|
||||||
|
export class Task { |
||||||
|
constructor( |
||||||
|
public analyticUnitId: AnalyticUnitId, |
||||||
|
public id?: TaskId |
||||||
|
) { |
||||||
|
if(analyticUnitId === undefined) { |
||||||
|
throw new Error('analyticUnitId is undefined'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public toObject() { |
||||||
|
return { |
||||||
|
_id: this.id, |
||||||
|
analyticUnitId: this.analyticUnitId |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
static fromObject(obj: any): Task { |
||||||
|
if(obj === undefined) { |
||||||
|
throw new Error('obj is undefined'); |
||||||
|
} |
||||||
|
return new Task( |
||||||
|
obj.analyticUnitId, |
||||||
|
obj._id, |
||||||
|
); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue