Skip to content

Commit

Permalink
fix(js-10): Handle single alarm (xml) result properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus von Rüden committed Aug 1, 2017
1 parent 5806aa6 commit 544c174
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 42 deletions.
21 changes: 16 additions & 5 deletions src/dao/AlarmDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ export class AlarmDAO extends AbstractDAO<number, OnmsAlarm> {
public async find(filter?: Filter): Promise<OnmsAlarm[]> {
const opts = this.getOptions(filter);
return this.http.get(this.pathToAlarmsEndpoint(), opts).then((result) => {
const data = this.getData(result);
return data.map((alarmData) => {
return this.fromData(alarmData);
});
});
}

/**
* Extracts the data from an HTTP Request result.
*
* @param result the HTTP Request result.
* @returns An array of [[OnmsAlarm]] objects.
*/
public getData(result: any): OnmsAlarm[] {
let data = result.data;

if (this.getCount(data) > 0 && data.alarm) {
Expand All @@ -72,16 +86,13 @@ export class AlarmDAO extends AbstractDAO<number, OnmsAlarm> {
}

if (!Array.isArray(data)) {
if (data.nodeId) {
if (data.id) {
data = [data];
} else {
throw new OnmsError('Expected an array of alarms but got "' + (typeof data) + '" instead.');
}
}
return data.map((alarmData) => {
return this.fromData(alarmData);
});
});
return data;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/dao/EventDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class EventDAO extends AbstractDAO<number, OnmsEvent> {
}

if (!Array.isArray(data)) {
if (data.nodeId) {
if (data.id) {
data = [data];
} else {
throw new OnmsError('Expected an array of events but got "' + (typeof data) + '" instead.');
Expand Down
Empty file added src/dao/alarm/XmlAlarmParser.ts
Empty file.
45 changes: 10 additions & 35 deletions src/rest/AbstractHTTP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,14 @@ import {IFilterProcessor} from '../api/IFilterProcessor';
import {OnmsHTTPOptions} from '../api/OnmsHTTPOptions';
import {OnmsResult} from '../api/OnmsResult';
import {OnmsServer} from '../api/OnmsServer';

if (global && !global.window) {
global.window = {} as Window;
if (!global.window.DOMParser) {
// tslint:disable-next-line
global.window.DOMParser = require('xmldom').DOMParser;
}
}
import {XmlTransformer} from './XmlTransformer';
import {JsonTransformer} from './JsonTransformer';

/** @hidden */
// tslint:disable-next-line
const X2JS = require('x2js');
const xmlTransformer = new XmlTransformer();

/** @hidden */
const xmlParser = new X2JS({
arrayAccessForm: 'property',
attributePrefix: '',
ignoreRoot: true,
});
const jsonTransformer = new JsonTransformer();

/**
* Abstract implementation of the OnmsHTTP interface meant to be extended by a concrete class.
Expand Down Expand Up @@ -83,29 +72,15 @@ export abstract class AbstractHTTP implements IOnmsHTTP {
* Use this to process a JSON response before returning it in an [[OnmsResult]] object.
*/
protected transformJSON(data: any) {
if (typeof data === 'string') {
if (data.length < 1) {
return {};
} else {
return JSON.parse(data);
}
} else {
// assume it's already parsed
return data;
}
return jsonTransformer.transform(data);
}

/**
* A convenience method for implementers to use to turn XML into a javascript object.
* Use this to process an XML response before returning it in an [[OnmsResult]] object.
*/
/**
* A convenience method for implementers to use to turn XML into a javascript object.
* Use this to process an XML response before returning it in an [[OnmsResult]] object.
*/
protected transformXML(data: any) {
if (typeof data === 'string') {
return xmlParser.xml2js(data);
} else {
// assume it's already parsed
return data;
}
return xmlTransformer.transform(data);
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/rest/JsonTransformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Helper to transform a json string to an json object.
*/
export class JsonTransformer {
/**
* A convenience method for implementers to use to turn JSON into a javascript object.
* Use this to process a JSON response before returning it in an [[OnmsResult]] object.
*/
public transform(data: any) {
if (typeof data === 'string') {
if (data.length < 1) {
return {};
} else {
return JSON.parse(data);
}
} else {
// assume it's already parsed
return data;
}
}
}
37 changes: 37 additions & 0 deletions src/rest/XmlTransformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

if (global && !global.window) {
global.window = {} as Window;
if (!global.window.DOMParser) {
// tslint:disable-next-line
global.window.DOMParser = require('xmldom').DOMParser;
}
}

/** @hidden */
// tslint:disable-next-line
const X2JS = require('x2js');

/** @hidden */
const xmlParser = new X2JS({
arrayAccessForm: 'property',
attributePrefix: '',
ignoreRoot: true,
});

/**
* Helper class to transform any xml string to a javascript object.
*/
export class XmlTransformer {
/**
* A convenience method for implementers to use to turn XML into a javascript object.
* Use this to process an XML response before returning it in an [[OnmsResult]] object.
*/
public transform(data: any) {
if (typeof data === 'string') {
return xmlParser.xml2js(data);
} else {
// assume it's already parsed
return data;
}
}
}
34 changes: 33 additions & 1 deletion test/dao/AlarmDAO.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {AlarmDAO} from '../../src/dao/AlarmDAO';
import {OnmsAlarm} from '../../src/model/OnmsAlarm';
import {TroubleTicketStates} from '../../src/model/OnmsTroubleTicketState';

import {XmlTransformer} from '../../src/rest/XmlTransformer';

import {MockHTTP19} from '../rest/MockHTTP19';
import {MockHTTP21} from '../rest/MockHTTP21';

Expand Down Expand Up @@ -101,7 +103,37 @@ describe('AlarmDAO with v1 API', () => {
return expect(dao.deleteStickyMemo(404725)).rejects.toBeDefined();
});
it('AlarmDAO.deleteJournalMemo(404725) should reject', () => {
return expect(dao.deleteJournalMemo(404725)).rejects.toBeDefined();
return expect(dao.deleteJournalMemo(404725)).rejects.toBeDefined();
});
describe('getData()', () => {
it('Can handle single alarm. See JS-10', () => {
const rawData = '<?xml version="1.0" encoding="UTF-8"?>\n' +
'<alarms count="1" totalCount="1">\n' +
' <alarm type="1" count="1" id="1" severity="CRITICAL">\n' +
' <description>A problem has been triggered.</description>\n' +
' <firstEventTime>2017-07-28T20:41:46.236Z</firstEventTime>\n' +
' <lastEvent display="Y" log="Y" id="17" severity="CRITICAL">\n' +
' <createTime>2017-07-28T20:41:46.239Z</createTime>\n' +
' <description>A problem has been triggered.</description>\n' +
' <logMessage>A problem has been triggered on //.</logMessage>\n' +
' <source>ReST</source>\n' +
' <time>2017-07-28T20:41:46.236Z</time>\n' +
' <uei>uei.opennms.org/alarms/trigger</uei>\n' +
' </lastEvent>\n' +
' <lastEventTime>2017-07-28T20:41:46.236Z</lastEventTime>\n' +
' <logMessage>A problem has been triggered on //.</logMessage>\n' +
' <reductionKey>uei.opennms.org/alarms/trigger:::</reductionKey>\n' +
' <suppressedTime>2017-07-28T20:41:46.236Z</suppressedTime>\n' +
' <suppressedUntil>2017-07-28T20:41:46.236Z</suppressedUntil>\n' +
' <uei>uei.opennms.org/alarms/trigger</uei>\n' +
' <x733ProbableCause>0</x733ProbableCause>\n' +
' </alarm>\n' +
'</alarms>';
const jsonObject = new XmlTransformer().transform(rawData);

// if this passes, no exception was thrown
dao.getData({ data: jsonObject });
});
});
});

Expand Down

0 comments on commit 544c174

Please sign in to comment.