From 9612c567d52397d1cb0eaa4c61a222eab8e6c4a7 Mon Sep 17 00:00:00 2001 From: Evgeny Smyshlyaev Date: Thu, 8 Aug 2019 19:19:50 +0300 Subject: [PATCH] Error cannot read property data of null #739 (#740) --- .../src/controllers/analytics_controller.ts | 11 ++------- .../src/models/analytic_unit_cache_model.ts | 13 ++++++++-- .../analytic_units/analytic_unit_model.ts | 5 +++- .../anomaly_analytic_unit_model.ts | 24 ++++++++++--------- server/src/models/analytic_units/index.ts | 8 +++---- .../threshold_analytic_unit_model.ts | 13 ++++++---- 6 files changed, 43 insertions(+), 31 deletions(-) diff --git a/server/src/controllers/analytics_controller.ts b/server/src/controllers/analytics_controller.ts index d565984..746f450 100644 --- a/server/src/controllers/analytics_controller.ts +++ b/server/src/controllers/analytics_controller.ts @@ -3,8 +3,8 @@ import { AnalyticsTask, AnalyticsTaskType, AnalyticsTaskId } from '../models/ana import * as AnalyticUnitCache from '../models/analytic_unit_cache_model'; import * as Segment from '../models/segment_model'; import * as AnalyticUnit from '../models/analytic_units'; +import { ThresholdAnalyticUnit, AnomalyAnalyticUnit} from '../models/analytic_units'; import * as Detection from '../models/detection_model'; -import { ThresholdAnalyticUnit } from '../models/analytic_units/threshold_analytic_unit_model'; import { AnalyticsService } from '../services/analytics_service'; import { AlertService } from '../services/alert_service'; import { HASTIC_API_KEY } from '../config'; @@ -14,10 +14,7 @@ import { getNonIntersectedSpans } from '../utils/spans'; import { queryByMetric, GrafanaUnavailable, DatasourceUnavailable } from 'grafana-datasource-kit'; - import * as _ from 'lodash'; -import { WebhookType } from '../services/notification_service'; -import { AnomalyAnalyticUnit } from '../models/analytic_units/anomaly_analytic_unit_model'; const SECONDS_IN_MINUTE = 60; @@ -658,11 +655,7 @@ export async function getHSR( } let cache = await AnalyticUnitCache.findById(analyticUnit.id); - if( - cache === null || - cache.data.alpha !== (analyticUnit as AnalyticUnit.AnomalyAnalyticUnit).alpha || - cache.data.confidence !== (analyticUnit as AnalyticUnit.AnomalyAnalyticUnit).confidence - ) { + if(cache === null || cache.isCacheOutdated(analyticUnit)) { await runLearning(analyticUnit.id, from, to); cache = await AnalyticUnitCache.findById(analyticUnit.id); } diff --git a/server/src/models/analytic_unit_cache_model.ts b/server/src/models/analytic_unit_cache_model.ts index 771d8e1..0b2bd7c 100644 --- a/server/src/models/analytic_unit_cache_model.ts +++ b/server/src/models/analytic_unit_cache_model.ts @@ -1,4 +1,4 @@ -import { AnalyticUnitId } from './analytic_units'; +import { AnalyticUnitId, AnalyticUnit } from './analytic_units'; import { Collection, makeDBQ } from '../services/data_service'; import * as _ from 'lodash'; @@ -33,7 +33,11 @@ export class AnalyticUnitCache { } public getIntersection(): number { - if(this.data.windowSize !== undefined) { + if( + this.data !== undefined && + this.data !== null && + this.data.windowSize !== undefined + ) { //TODO: return one window size after resolving https://github.com/hastic/hastic-server/issues/508 if(this.data.timeStep !== undefined) { return this.data.windowSize * 2 * this.data.timeStep; @@ -45,6 +49,11 @@ export class AnalyticUnitCache { return 3 * MILLISECONDS_IN_INDEX; } + public isCacheOutdated(analyticUnit: AnalyticUnit) { + return !_.every( + _.keys(analyticUnit.analyticProps).map(k => _.isEqual(analyticUnit.analyticProps[k], this.data[k])) + ); + } } export async function findById(id: AnalyticUnitId): Promise { diff --git a/server/src/models/analytic_units/analytic_unit_model.ts b/server/src/models/analytic_units/analytic_unit_model.ts index c6fca38..78e7d4d 100644 --- a/server/src/models/analytic_units/analytic_unit_model.ts +++ b/server/src/models/analytic_units/analytic_unit_model.ts @@ -2,7 +2,6 @@ import { AnalyticUnitId, AnalyticUnitStatus, DetectorType } from './types'; import { Metric } from 'grafana-datasource-kit'; - export abstract class AnalyticUnit { public learningAfterUpdateRequired = false; @@ -78,4 +77,8 @@ export abstract class AnalyticUnit { }; } + get analyticProps () { + return {}; + } + } diff --git a/server/src/models/analytic_units/anomaly_analytic_unit_model.ts b/server/src/models/analytic_units/anomaly_analytic_unit_model.ts index 107b78f..4f4d3be 100644 --- a/server/src/models/analytic_units/anomaly_analytic_unit_model.ts +++ b/server/src/models/analytic_units/anomaly_analytic_unit_model.ts @@ -8,7 +8,7 @@ type SeasonalityPeriod = { value: number } -enum Bound { +export enum Bound { ALL = 'ALL', UPPER = 'UPPER', LOWER = 'LOWER' @@ -61,11 +61,7 @@ export class AnomalyAnalyticUnit extends AnalyticUnit { const baseObject = super.toObject(); return { ...baseObject, - alpha: this.alpha, - confidence: this.confidence, - seasonality: this.seasonality, - seasonalityPeriod: this.seasonalityPeriod, - enableBounds: this.enableBounds + ...this.analyticProps }; } @@ -73,11 +69,7 @@ export class AnomalyAnalyticUnit extends AnalyticUnit { const baseObject = super.toPanelObject(); return { ...baseObject, - alpha: this.alpha, - confidence: this.confidence, - seasonality: this.seasonality, - seasonalityPeriod: this.seasonalityPeriod, - enableBounds: this.enableBounds + ...this.analyticProps }; } @@ -110,4 +102,14 @@ export class AnomalyAnalyticUnit extends AnalyticUnit { obj.collapsed ); } + + get analyticProps() { + return { + alpha: this.alpha, + confidence: this.confidence, + seasonality: this.seasonality, + seasonalityPeriod: this.seasonalityPeriod, + enableBounds: this.enableBounds + }; + } } diff --git a/server/src/models/analytic_units/index.ts b/server/src/models/analytic_units/index.ts index cab3cd0..1381735 100644 --- a/server/src/models/analytic_units/index.ts +++ b/server/src/models/analytic_units/index.ts @@ -2,8 +2,8 @@ import { createAnalyticUnitFromObject } from './utils'; import { AnalyticUnitId, AnalyticUnitStatus, DetectorType, ANALYTIC_UNIT_TYPES } from './types'; import { AnalyticUnit } from './analytic_unit_model'; import { PatternAnalyticUnit } from './pattern_analytic_unit_model'; -import { ThresholdAnalyticUnit } from './threshold_analytic_unit_model'; -import { AnomalyAnalyticUnit } from './anomaly_analytic_unit_model'; +import { ThresholdAnalyticUnit, Condition } from './threshold_analytic_unit_model'; +import { AnomalyAnalyticUnit, Bound } from './anomaly_analytic_unit_model'; import { findById, findMany, @@ -19,8 +19,8 @@ import { export { AnalyticUnit, PatternAnalyticUnit, ThresholdAnalyticUnit, AnomalyAnalyticUnit, - AnalyticUnitId, AnalyticUnitStatus, DetectorType, ANALYTIC_UNIT_TYPES, - createAnalyticUnitFromObject, + AnalyticUnitId, AnalyticUnitStatus, Bound, DetectorType, ANALYTIC_UNIT_TYPES, + createAnalyticUnitFromObject, Condition, findById, findMany, create, remove, update, setStatus, setDetectionTime, setAlert, setMetric diff --git a/server/src/models/analytic_units/threshold_analytic_unit_model.ts b/server/src/models/analytic_units/threshold_analytic_unit_model.ts index 0a15c27..e241668 100644 --- a/server/src/models/analytic_units/threshold_analytic_unit_model.ts +++ b/server/src/models/analytic_units/threshold_analytic_unit_model.ts @@ -58,8 +58,7 @@ export class ThresholdAnalyticUnit extends AnalyticUnit { const baseObject = super.toObject(); return { ...baseObject, - value: this.value, - condition: this.condition + ...this.analyticProps }; } @@ -67,8 +66,7 @@ export class ThresholdAnalyticUnit extends AnalyticUnit { const baseObject = super.toPanelObject(); return { ...baseObject, - value: this.value, - condition: this.condition + ...this.analyticProps }; } @@ -98,4 +96,11 @@ export class ThresholdAnalyticUnit extends AnalyticUnit { obj.collapsed ); } + + get analyticProps() { + return { + value: this.value, + condition: this.condition + } + } }