-
Notifications
You must be signed in to change notification settings - Fork 8
/
Client.ts
216 lines (185 loc) · 7.3 KB
/
Client.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import {IHasHTTP} from './api/IHasHTTP';
import {IOnmsHTTP} from './api/IOnmsHTTP';
import {OnmsError} from './api/OnmsError';
import {OnmsHTTPOptions} from './api/OnmsHTTPOptions';
import {OnmsVersion} from './api/OnmsVersion';
import {ServerTypes} from './api/ServerType';
import {TicketerConfig} from './api/TicketerConfig';
import {OnmsServer} from './api/OnmsServer';
import {ServerMetadata} from './api/ServerMetadata';
import {BaseDAO} from './dao/BaseDAO';
import {AlarmDAO} from './dao/AlarmDAO';
import {EventDAO} from './dao/EventDAO';
import {FlowDAO} from './dao/FlowDAO';
import {IpInterfaceDAO} from './dao/IpInterfaceDAO';
import {MonitoredServiceDAO} from './dao/MonitoredServiceDAO';
import {NodeDAO} from './dao/NodeDAO';
import {OutageDAO} from './dao/OutageDAO';
import {SituationFeedbackDAO} from './dao/SituationFeedbackDAO';
import {SnmpInterfaceDAO} from './dao/SnmpInterfaceDAO';
import {AxiosHTTP} from './rest/AxiosHTTP';
import { OnmsAuthConfig } from './api/OnmsAuthConfig';
/**
* The OpenNMS client. This is the primary interface to OpenNMS servers.
* @category Rest
*/
export class Client implements IHasHTTP {
/**
* Given an OnmsServer object, check that it can be connected to.
*
* @param server - the server to check
* @param httpImpl - the [[IOnmsHTTP]] implementation to use
* @param timeout - how long to wait before giving up when making ReST calls
*/
public static async checkServer(server: OnmsServer, httpImpl?: IOnmsHTTP, timeout?: number): Promise<boolean> {
if (!httpImpl) {
if (!Client.defaultHttp) {
throw new OnmsError('No HTTP implementation is configured!');
}
httpImpl = new Client.defaultHttp();
}
const infoUrl = server.resolveURL('rest/alarms/count');
const builder = OnmsHTTPOptions.newBuilder()
.setTimeout(timeout)
.setServer(server)
.setHeader('Accept', 'text/plain');
await httpImpl.get(infoUrl, builder.build());
return true;
}
/**
* Given an OnmsServer object, query what capabilities it has, and return the capabilities
* associated with that server.
*
* @param server - the server to check
* @param httpImpl - the [[IOnmsHTTP]] implementation to use
* @param timeout - how long to wait before giving up when making ReST calls
*/
public static async getMetadata(server: OnmsServer, httpImpl?: IOnmsHTTP, timeout?: number): Promise<ServerMetadata> {
if (!httpImpl) {
if (!Client.defaultHttp) {
throw new OnmsError('No HTTP implementation is configured!');
}
httpImpl = new Client.defaultHttp();
}
const infoUrl = server.resolveURL('rest/info');
const builder = OnmsHTTPOptions.newBuilder()
.setServer(server)
.setTimeout(timeout)
.setHeader('Accept', 'application/json');
if (!timeout && httpImpl && httpImpl.options && httpImpl.options.timeout) {
builder.setTimeout(httpImpl.options.timeout);
}
const response = await httpImpl.get(infoUrl, builder.build());
const version = new OnmsVersion(response.data.version, response.data.displayVersion);
let type = ServerTypes.HORIZON;
if (response.data.packageName) {
if (response.data.packageName.toLowerCase() === 'meridian') {
type = ServerTypes.MERIDIAN;
}
}
if (response.data.ticketerConfig) {
const config = response.data.ticketerConfig;
return new ServerMetadata(version, type, new TicketerConfig(config.plugin, config.enabled));
}
return new ServerMetadata(version, type);
}
/** The default OnmsHTTP implementation to be used when making requests */
private static readonly defaultHttp = AxiosHTTP;
/** the OnmsHTTP implementation that will be used when making requests */
public http: IOnmsHTTP;
/**
* A cache of initialized DAOs, kept until server configuration changes
* @hidden
*/
private daos = new Map() as Map<string, BaseDAO>;
/**
* Construct a new OpenNMS client.
*
* If no `httpImpl` parameter is provided, the class in [[Client.defaultHttp]] will be used by default.
* Unless overridden, this defaults to [[AxiosHTTP]].
*
* @constructor
* @param httpImpl - The IOnmsHTTP implementation to use.
*/
constructor(httpImpl?: IOnmsHTTP) {
this.http = httpImpl || new Client.defaultHttp();
}
/**
* Connect to an OpenNMS server.
*
* NOTE: This method will connect to the server using the provided
* information, get the server metadata, and then _assign_ that
* server to the _existing_ [[IOnmsHTTP]] implementation associated
* with this client (or the default impl, if one has not yet been provided).
*/
public async connect(name: string, url: string, username: string, password: string, timeout?: number) {
const builder = OnmsServer.newBuilder()
.setName(name)
.setUrl(url)
.setAuth(new OnmsAuthConfig(username, password));
const testServer = builder.build();
// first check the server; throws if it can't connect
await Client.checkServer(testServer, this.http, timeout);
// then retrieve the server metadata and update to the hydrated version of the server
const metadata = await Client.getMetadata(testServer, this.http, timeout);
this.http.server = builder.setMetadata(metadata).build();
return this;
}
/** Get an alarm DAO for querying alarms. */
public alarms(): AlarmDAO {
return this.getDao('alarms', AlarmDAO) as AlarmDAO;
}
/** Get an event DAO for querying events. */
public events() {
return this.getDao('events', EventDAO) as EventDAO;
}
/** Get a node DAO for querying nodes. */
public nodes() {
return this.getDao('nodes', NodeDAO) as NodeDAO;
}
/** Get an IP interface DAO for querying interfaces. */
public ipInterfaces() {
return this.getDao('ipInterfaces', IpInterfaceDAO) as IpInterfaceDAO;
}
/** Get an SNMP interface DAO for querying interfaces. */
public snmpInterfaces() {
return this.getDao('snmpInterfaces', SnmpInterfaceDAO) as SnmpInterfaceDAO;
}
/** Get a monitored service DAO for querying services. */
public monitoredServices() {
return this.getDao('monitoredServices', MonitoredServiceDAO) as MonitoredServiceDAO;
}
/** Get an outage DAO for querying outages. */
public outages() {
return this.getDao('outages', OutageDAO) as OutageDAO;
}
/** Get a flow DAO for querying flows. */
public flows() {
return this.getDao('flows', FlowDAO) as FlowDAO;
}
/** Get a situationFeedback DAO for submitting and querying correlation feedback. */
public situationfeedback() {
return this.getDao('situationfeedback', SituationFeedbackDAO) as SituationFeedbackDAO;
}
/**
* A convenience method to validate cached DAOs and create them if they don't exist
* @hidden
* @param key a unique key used for caching the DAO
* @param daoClass the DAO class to retrieve or create
*/
private getDao(
key: string,
daoClass: typeof AlarmDAO | typeof EventDAO | typeof FlowDAO | typeof IpInterfaceDAO | typeof NodeDAO | typeof OutageDAO | typeof MonitoredServiceDAO | typeof SituationFeedbackDAO | typeof SnmpInterfaceDAO,
) {
const existing = this.daos.get(key);
if (existing) {
if (existing.server && existing.server.equals(this.http.server)) {
return existing;
}
}
const dao = new daoClass(this);
dao.http = this.http;
this.daos.set(key, dao);
return dao;
}
}