/
AbstractDAO.ts
156 lines (137 loc) · 4.38 KB
/
AbstractDAO.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import {IFilterProcessor} from '../api/IFilterProcessor';
import {IHasHTTP} from '../api/IHasHTTP';
import {IOnmsHTTP} from '../api/IOnmsHTTP';
import {OnmsError} from '../api/OnmsError';
import {Filter} from '../api/Filter';
import {OnmsHTTPOptions} from '../api/OnmsHTTPOptions';
import {log, catDao} from '../api/Log';
import {V1FilterProcessor} from './V1FilterProcessor';
import {V2FilterProcessor} from './V2FilterProcessor';
/** @hidden */
// tslint:disable-next-line
const moment = require('moment');
/** @hidden */
// tslint:disable-next-line
import {Moment} from 'moment';
/**
* An abstract data access layer API, meant to (somewhat) mirror the DAO interfaces
* inside OpenNMS. Used to retrieve model data like alarms, events, etc. from the
* OpenNMS ReST API in a consistent way.
*
* @module AbstractDAO
* @param K the ID/key type (number, string, etc.)
* @param T the model type (OnmsAlarm, OnmsEvent, etc.)
*/
export abstract class AbstractDAO<K, T> {
/**
* The [[IOnmsHTTP]] implementation to use internally when making DAO requests.
* @hidden
*/
private httpImpl: IOnmsHTTP;
/**
* The [[IFilterProcessor]] to use internally when making DAO requests.
* @hidden
*/
private filterProcessorImpl;
/**
* Construct a DAO instance.
*
* @param impl - The HTTP implementation to use. It is also legal to pass any object
* conforming to the [[IHasHTTP]] interface (like a [[Client]]).
*/
constructor(impl: IOnmsHTTP | IHasHTTP) {
if ((impl as IHasHTTP).http) {
impl = (impl as IHasHTTP).http;
}
this.httpImpl = impl as IOnmsHTTP;
}
/**
* The HTTP implementation to use internally when making DAO requests.
*/
public get http() {
return this.httpImpl;
}
public set http(impl: IOnmsHTTP) {
this.httpImpl = impl;
}
public get filterProcessor() {
if (!this.filterProcessorImpl) {
switch (this.getApiVersion()) {
case 2:
this.filterProcessorImpl = new V2FilterProcessor();
break;
default:
this.filterProcessorImpl = new V1FilterProcessor();
}
}
return this.filterProcessorImpl;
}
public set filterProcessor(impl: IFilterProcessor) {
this.filterProcessorImpl = impl;
}
/**
* Retrieve a model object.
* @param id - the ID of the object
*/
public abstract async get(id: K): Promise<T>;
/**
* Find all model objects given an optional filter.
* @param filter - the filter to use when retrieving a list of model objects
*/
public abstract async find(filter?: Filter): Promise<T[]>;
/**
* A convenience method to make it easy for implementers to extract the count
* (or totalCount) values from response data.
*/
protected getCount(data: any): number {
let count = 0;
if (typeof(data) === 'number') {
count = data;
} else if (data.count !== undefined) {
count = parseInt(data.count, 10);
} else if (data.totalCount !== undefined) {
count = parseInt(data.totalCount, 10);
} else {
log.debug('data is missing count and totalCount properties', catDao);
}
return count;
}
/**
* Create an [[OnmsHTTPOptions]] object for DAO calls given an optional filter.
* @param filter - the filter to use
*/
protected getOptions(filter?: Filter): OnmsHTTPOptions {
const ret = new OnmsHTTPOptions();
// always use application/xml for now in DAO calls
ret.headers.accept = 'application/xml';
if (filter) {
ret.parameters = this.filterProcessor.getParameters(filter);
}
return ret;
}
/**
* Convert the given value to a date, or undefined if it cannot be converted.
*/
protected toDate(from: any): Moment|undefined {
if (from === undefined || from === null || from === '') {
return undefined;
}
return moment(from);
}
/**
* Convert the given value to a number, or undefined if it cannot be converted.
*/
protected toNumber(from: any): number|undefined {
const ret = parseInt(from, 10);
return isNaN(ret) ? undefined : ret;
}
/**
* Retrieve the API version from the currently configured server.
*/
protected getApiVersion(): number {
if (this.http === undefined || this.http.server === undefined || this.http.server.metadata === undefined) {
throw new OnmsError('Server meta-data must be populated prior to making DAO calls.');
}
return this.http.server.metadata.apiVersion();
}
}