Permalink
Browse files

feat(dao): implement querying ReSTv2 search properties

  • Loading branch information...
RangerRick committed Jul 31, 2017
1 parent c524493 commit a588325934087bbca48a4561893942ad96c8513c
View
@@ -0,0 +1,19 @@
import {SearchPropertyType} from './SearchPropertyType';
/**
* Represents a query search property.
* @module SearchProperty
*/
export class SearchProperty {
/** the search property ID */
public id: string;
/** a descriptive name for the property */
public name: string;
/** whether the property is sortable */
public orderBy: boolean;
/** the property type */
public type: SearchPropertyType;
}
@@ -0,0 +1,25 @@
import {OnmsEnum, forId, forLabel} from '../internal/OnmsEnum';
/**
* Represents a search property type.
* @module SearchPropertyType
*/
export class SearchPropertyType extends OnmsEnum<string> {
/** given an ID, return the matching search property type object */
public static forId(id: string) {
return forId(SearchPropertyTypes, id);
}
}
const SearchPropertyTypes = {
FLOAT: new SearchPropertyType('FLOAT', 'floating-point number'),
INTEGER: new SearchPropertyType('INTEGER', 'integer'),
IP_ADDRESS: new SearchPropertyType('IP_ADDRESS', 'IP address'),
LONG: new SearchPropertyType('LONG', 'long integer'),
STRING: new SearchPropertyType('STRING', 'string'),
TIMESTAMP: new SearchPropertyType('TIMESTAMP', 'date and time'),
};
/** @hidden */
const frozen = Object.freeze(SearchPropertyTypes);
export {frozen as SearchPropertyTypes};
View
@@ -5,6 +5,8 @@ import {OnmsError} from '../api/OnmsError';
import {Filter} from '../api/Filter';
import {OnmsHTTPOptions} from '../api/OnmsHTTPOptions';
import {SearchProperty} from '../api/SearchProperty';
import {SearchPropertyType} from '../api/SearchPropertyType';
import {log, catDao} from '../api/Log';
@@ -94,6 +96,42 @@ export abstract class AbstractDAO<K, T> {
*/
public abstract async find(filter?: Filter): Promise<T[]>;
/**
* Get the list properties that can be used in queries.
* @version ReST v2
*/
public async searchProperties(): Promise<SearchProperty[]> {
if (this.getApiVersion() === 1) {
throw new OnmsError('Search property metadata is only available in OpenNMS ' +
'versions that support the ReSTv2 API.');
}
const opts = this.getOptions();
opts.headers.accept = 'application/json';
return this.http.get(this.searchPropertyPath(), opts).then((result) => {
let data = result.data;
if (this.getCount(data) > 0 && data.searchProperty) {
data = data.searchProperty;
} else {
data = [];
}
if (!Array.isArray(data)) {
throw new OnmsError('Expected an array of search properties but got "' +
(typeof data) + '" instead: ' + this.searchPropertyPath());
}
return data.map((prop) => {
return this.toSearchProperty(prop);
});
});
}
/**
* The path to retrieve search properties for this DAO.
*/
protected abstract searchPropertyPath(): string;
/**
* A convenience method to make it easy for implementers to extract the count
* (or totalCount) values from response data.
@@ -144,6 +182,23 @@ export abstract class AbstractDAO<K, T> {
return isNaN(ret) ? undefined : ret;
}
/**
* Generate a [[SearchProperty]] from the given dictionary.
* @hidden
*/
protected toSearchProperty(data: any): SearchProperty {
if (!data) {
return null;
}
const prop = new SearchProperty();
prop.id = data.id;
prop.name = data.name;
prop.orderBy = !!data.orderBy;
prop.type = SearchPropertyType.forId(data.type);
return prop;
}
/**
* Retrieve the API version from the currently configured server.
*/
View
@@ -8,6 +8,7 @@ import {IOnmsHTTP} from '../api/IOnmsHTTP';
import {OnmsError} from '../api/OnmsError';
import {OnmsHTTPOptions} from '../api/OnmsHTTPOptions';
import {OnmsResult} from '../api/OnmsResult';
import {SearchProperty} from '../api/SearchProperty';
import {OnmsAlarm} from '../model/OnmsAlarm';
import {AlarmTypes} from '../model/OnmsAlarmType';
@@ -385,6 +386,13 @@ export class AlarmDAO extends AbstractDAO<number, OnmsAlarm> {
return memo;
}
/**
* The path to the alarm search properties endpoint.
*/
protected searchPropertyPath() {
return this.pathToAlarmsEndpoint() + '/properties';
}
/**
* Given an optional filter, generate an [[OnmsHTTPOptions]] object for DAO calls.
* @hidden
View
@@ -110,6 +110,13 @@ export class EventDAO extends AbstractDAO<number, OnmsEvent> {
return event;
}
/**
* The path to the event search properties endpoint.
*/
protected searchPropertyPath() {
return this.pathToEventsEndpoint() + '/properties';
}
/**
* Get the path to the events endpoint for the appropriate API version.
* @hidden
View
@@ -318,6 +318,14 @@ export class NodeDAO extends AbstractDAO<number, OnmsNode> {
return service;
}
/**
* The path to the node search properties endpoint.
*/
protected searchPropertyPath(): string {
throw new OnmsError('Search properties are not supported in Node ReSTv2 yet.');
// return this.pathToNodesEndpoint() + '/properties';
}
/**
* Get the path to the nodes endpoint for the appropriate API version.
* @hidden
View
@@ -12,6 +12,7 @@ import {OnmsResult} from '../../src/api/OnmsResult';
import {Comparators} from '../../src/api/Comparator';
import {Filter} from '../../src/api/Filter';
import {Restriction} from '../../src/api/Restriction';
import {SearchPropertyTypes} from '../../src/api/SearchPropertyType';
import {AlarmDAO} from '../../src/dao/AlarmDAO';
@@ -52,6 +53,9 @@ describe('AlarmDAO with v1 API', () => {
expect(alarms.length).toEqual(1);
});
});
it('AlarmDAO.searchProperties() should reject', () => {
return expect(dao.searchProperties()).rejects.toBeDefined();
});
for (const method of ['acknowledge', 'unacknowledge', 'escalate', 'clear']) {
it('AlarmDAO.' + method + '(id=404725)', () => {
@@ -144,6 +148,14 @@ describe('AlarmDAO with v2 API', () => {
expect(alarm.journal.body).toEqual('journal');
});
});
it('AlarmDAO.searchProperties() should return a list of SearchProperty objects', () => {
return dao.searchProperties().then((props) => {
expect(props).toBeDefined();
expect(props).toHaveLength(165);
expect(props[0].id).toEqual('alarmAckTime');
expect(props[0].type).toEqual(SearchPropertyTypes.TIMESTAMP);
});
});
for (const method of ['acknowledge', 'unacknowledge', 'escalate', 'clear']) {
it('AlarmDAO.' + method + '(id=404725)', () => {
View
@@ -91,6 +91,9 @@ describe('NodeDAO with v1 API', () => {
expect(nodes.length).toEqual(1);
});
});
it('NodeDAO.properties() should reject', () => {
return expect(dao.searchProperties()).rejects.toBeDefined();
});
});
describe('NodeDAO with v2 API', () => {
@@ -152,4 +155,7 @@ describe('NodeDAO with v2 API', () => {
});
});
*/
it('NodeDAO.properties() should reject until it is implemented', () => {
return expect(dao.searchProperties()).rejects.toBeDefined();
});
});
Oops, something went wrong.

0 comments on commit a588325

Please sign in to comment.