Skip to content

Commit

Permalink
handling braoder set of incoming validation messages (#212)
Browse files Browse the repository at this point in the history
  • Loading branch information
slevertbiot committed Aug 16, 2022
1 parent 444ed3c commit bb4aea4
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 142 deletions.
10 changes: 6 additions & 4 deletions udmif/event-handler/src/DeviceDocumentFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DeviceBuilder, Device } from './model/Device';
import { isPointsetSubType, isSystemSubType, isValidationSubType } from './MessageUtils';
import { UdmiMessage } from './model/UdmiMessage';
import { PointsetMessage, SystemMessage, UdmiMessage, ValidationMessage } from './model/UdmiMessage';
import { PointBuilder, Point } from './model/Point';
import { Validation, ValidationBuilder } from './model/Validation';

Expand All @@ -26,7 +26,7 @@ export function createDeviceDocument(udmiMessage: UdmiMessage, existingPoints: P
/**
* https://faucetsdn.github.io/udmi/gencode/docs/event_system.html describes the incoming schema for an event system message
*/
function buildDeviceDocumentFromSystem(udmiMessage: UdmiMessage, builder: DeviceBuilder): Device {
function buildDeviceDocumentFromSystem(udmiMessage: SystemMessage, builder: DeviceBuilder): Device {
return builder
.lastPayload(udmiMessage.data.timestamp)
.operational(udmiMessage.data.operational)
Expand All @@ -42,9 +42,11 @@ function buildDeviceDocumentFromSystem(udmiMessage: UdmiMessage, builder: Device
/**
* https://faucetsdn.github.io/udmi/gencode/docs/event_validation.html describes the incoming schema for an event validation message
*/
function buildDeviceDocumentFromValidation(udmiMessage: UdmiMessage, builder: DeviceBuilder): Device {
function buildDeviceDocumentFromValidation(udmiMessage: ValidationMessage, builder: DeviceBuilder): Device {
const validation: Validation = new ValidationBuilder()
.timestamp(udmiMessage.data.timestamp)
.version(udmiMessage.data.version)
.status(udmiMessage.data.status)
.category(udmiMessage.data.status.category)
.message(udmiMessage.data.status.message)
.detail(udmiMessage.data.status.detail)
Expand All @@ -58,7 +60,7 @@ function buildDeviceDocumentFromValidation(udmiMessage: UdmiMessage, builder: De
* https://faucetsdn.github.io/udmi/gencode/docs/event_pointset.html describes the incoming schema for an event pointset message
*/
function buildDeviceDocumentFromPointset(
udmiMessage: UdmiMessage,
udmiMessage: PointsetMessage,
existingPoints: Point[],
deviceBuilder: DeviceBuilder
): Device {
Expand Down
19 changes: 15 additions & 4 deletions udmif/event-handler/src/MessageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,27 @@ export const CONFIG = 'config';
export const EVENT = 'event';

export function isPointsetSubType(message): boolean {
return isSubFolder(message, POINTSET_SUB_FOLDER) && (!message.attributes.subType || isSubType(message, MODEL) || isSubType(message, STATE) || isSubType(message, CONFIG));
return (
isSubFolder(message, POINTSET_SUB_FOLDER) &&
(!message.attributes.subType ||
isSubType(message, MODEL) ||
isSubType(message, STATE) ||
isSubType(message, CONFIG))
);
}

export function isSystemSubType(message): boolean {
return isSubFolder(message, SYSTEM_SUB_FOLDER) && (!message.attributes.subType || isSubType(message, MODEL) || isSubType(message, STATE) || isSubType(message, CONFIG));
return (
isSubFolder(message, SYSTEM_SUB_FOLDER) &&
(!message.attributes.subType ||
isSubType(message, MODEL) ||
isSubType(message, STATE) ||
isSubType(message, CONFIG))
);
}

export function isValidationSubType(message): boolean {
return isSubFolder(message, VALIDATION_SUB_FOLDER) && isSubType(message, EVENT);
return isSubFolder(message, VALIDATION_SUB_FOLDER);
}

export function isSubFolder(message, folderName: string): boolean {
Expand All @@ -25,4 +37,3 @@ export function isSubFolder(message, folderName: string): boolean {
export function isSubType(message, typeName: string): boolean {
return message.attributes.subType === typeName;
}

25 changes: 23 additions & 2 deletions udmif/event-handler/src/__tests__/DeviceDocumentFactory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createDeviceDocument } from '../DeviceDocumentFactory';
import { createDeviceDocument, DeviceDocumentFactory } from '../DeviceDocumentFactory';
import { Device } from '../model/Device';
import {
CONFIG,
Expand All @@ -18,6 +18,16 @@ const site: string = 'site-1';
const BASIC_SYSTEM_ATTRIBUTES = { deviceId: name, deviceRegistryId: site, subFolder: SYSTEM_SUB_FOLDER };
const BASIC_POINTSET_ATTRIBUTES = { deviceId: name, deviceRegistryId: site, subFolder: POINTSET_SUB_FOLDER };

describe('DeviceDocumentFactory.constructor', () => {
const tags: string[] = [];

test('creates a default device document', () => {
const inputMessage: UdmiMessage = { attributes: { ...BASIC_SYSTEM_ATTRIBUTES }, data: {} };
const expectedDeviceDocument: Device = { name, site, tags };
expect(new DeviceDocumentFactory().createDeviceDocument(inputMessage, [])).toEqual(expectedDeviceDocument);
});
});

describe('DeviceDocumentFactory.createDeviceDocument.default', () => {
const tags: string[] = [];

Expand Down Expand Up @@ -229,10 +239,12 @@ describe('DeviceDocumentFactory.createDeviceDocument.validation', () => {
timestamp: '2022-08-03T17:28:49Z',
version: '1.3.14',
status: {
timestamp: '2022-08-03T17:28:49Z',
message: 'Multiple validation errors',
detail:
'While converting to json node: 2 schema violations found; While converting to json node: 1 schema violations found',
category: 'category-x',
level: 600,
},
errors: [
{
Expand All @@ -251,9 +263,18 @@ describe('DeviceDocumentFactory.createDeviceDocument.validation', () => {

test('a device document with the validation is populated', () => {
const expectedValidations: Validation = {
timestamp: '2022-08-03T17:28:49Z',
version: '1.3.14',
category: 'category-x',
status: {
timestamp: '2022-08-03T17:28:49Z',
message: 'Multiple validation errors',
detail:
'While converting to json node: 2 schema violations found; While converting to json node: 1 schema violations found',
category: 'category-x',
level: 600,
},
message: 'Multiple validation errors',
timestamp: '2022-08-03T17:28:49Z',
detail:
'While converting to json node: 2 schema violations found; While converting to json node: 1 schema violations found',
errors: [
Expand Down
14 changes: 7 additions & 7 deletions udmif/event-handler/src/__tests__/MessageUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '../MessageUtils';
import { UdmiMessage } from '../model/UdmiMessage';

describe('DeviceTypeUtils.Ssystem', () => {
describe('MessageUtils.System', () => {
const systemSubFolder = SYSTEM_SUB_FOLDER;

test.each([
Expand All @@ -27,7 +27,7 @@ describe('DeviceTypeUtils.Ssystem', () => {
});
});

describe('DeviceDocumentFactory.PointSet', () => {
describe('MessageUtils.PointSet', () => {
const pointSubFolder = POINTSET_SUB_FOLDER;

test.each([
Expand All @@ -42,14 +42,14 @@ describe('DeviceDocumentFactory.PointSet', () => {
});
});

describe('DeviceTypeUtils.Validation', () => {
describe('MessageUtils.Validation', () => {
const validationSubFolder = VALIDATION_SUB_FOLDER;

test.each([
[validationSubFolder, null, false],
[validationSubFolder, STATE, false],
[validationSubFolder, MODEL, false],
[validationSubFolder, CONFIG, false],
[validationSubFolder, null, true],
[validationSubFolder, STATE, true],
[validationSubFolder, MODEL, true],
[validationSubFolder, CONFIG, true],
[validationSubFolder, EVENT, true],
])('is a pointset sub type %p %p', (subFolder: string, subType: string, expected: boolean) => {
const inputMessage: UdmiMessage = createMessage(subFolder, subType);
Expand Down
19 changes: 19 additions & 0 deletions udmif/event-handler/src/__tests__/UdmiMessageHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ describe('UdmiMessageHandler', () => {
}
}
);

test('Points are empty array if none found', async () => {
const message = createMessageFromTypes(POINTSET_SUB_FOLDER, STATE, AHU_ID);
console.log(message);
getMock.mockResolvedValue(null);
await udmiMessageHandler.handleUdmiEvent(message);
expect(getMock).toHaveBeenCalled();
expect(createMock).toHaveBeenCalledWith(message, []);
expect(upsertMock).toHaveBeenCalled();
});
test('Points are array if array found', async () => {
const message = createMessageFromTypes(POINTSET_SUB_FOLDER, STATE, AHU_ID);
console.log(message);
getMock.mockResolvedValue([]);
await udmiMessageHandler.handleUdmiEvent(message);
expect(getMock).toHaveBeenCalled();
expect(createMock).toHaveBeenCalledWith(message, []);
expect(upsertMock).toHaveBeenCalled();
});
});

function createMessageFromTypes(subFolder: string, subType: string, deviceId: string = 'AHU-1'): UdmiMessage {
Expand Down
3 changes: 2 additions & 1 deletion udmif/event-handler/src/__tests__/model/Device.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ const serialNumber: string = 'serialNumber';
const points: Point[] = [];
const tags: string[] = [];
const validation: Validation = {
timestamp: '2022-08-03T17:28:49Z',
version: '',
category: 'category-x',
message: 'Multiple validation errors',
timestamp: '2022-08-03T17:28:49Z',
detail:
'While converting to json node: 2 schema violations found; While converting to json node: 1 schema violations found',
errors: [
Expand Down
112 changes: 54 additions & 58 deletions udmif/event-handler/src/__tests__/model/Validation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,64 @@
import { Error } from "../../model/UdmiMessage";
import { Validation, ValidationBuilder } from "../../model/Validation";
import { Error, Status } from '../../model/UdmiMessage';
import { Validation, ValidationBuilder } from '../../model/Validation';

describe('Validation.ValidationBuilder', () => {
const TIMESTAMP_ERROR: string = 'Validation timestamp can not be empty';
const VERSION_ERROR: string = 'Validation version can not be empty';

const CATEGORY_ERROR: string = 'Validation category can not be empty';
const MESSAGE_ERROR: string = 'Validation message can not be empty';
const TIMESTAMP_ERROR: string = 'Validation timestamp can not be empty';
const ERRORS_ERROR: string = 'Validation errors can not be empty';
let builder: ValidationBuilder;
beforeEach(() => {
builder = new ValidationBuilder();
});

let builder: ValidationBuilder;
beforeEach(() => {
builder = new ValidationBuilder();
});
test.each([undefined, null])('throws exception when timestamp is not provided', (timestamp: string) => {
expect(() => {
builder.timestamp(timestamp);
}).toThrow(TIMESTAMP_ERROR);
});

test.each([undefined, null])('throws exception when category is not provided', (category: string) => {
expect(() => {
builder.category(category);
}).toThrow(CATEGORY_ERROR);
})
test.each([undefined, null])('throws exception when version is not provided', (version: string) => {
expect(() => {
builder.version(version);
}).toThrow(VERSION_ERROR);
});

test.each([undefined, null])('throws exception when message is not provided', (message: string) => {
expect(() => {
builder.message(message);
}).toThrow(MESSAGE_ERROR);
})
test('build returns a Validation object', () => {
const status: Status = {
message: 'some-message',
category: 'some-category',
level: 500,
timestamp: '2022-08-03T17:28:49Z',
detail: 'some-detail',
};

test.each([undefined, null])('throws exception when timestamp is not provided', (timestamp: string) => {
expect(() => {
builder.timestamp(timestamp);
}).toThrow(TIMESTAMP_ERROR);
})
const errors: Error[] = [
{
message: 'While converting to json node: 2 schema violations found',
level: 500,
category: 'category-x',
},
];

test.each([undefined, null])('throws exception when errors are not provided', (error: Error[]) => {
expect(() => {
builder.errors(error);
}).toThrow(ERRORS_ERROR);
})
const output: Validation = builder
.timestamp('2022-08-03T17:28:49Z')
.version('1.0')
.status(status)
.category('some-category')
.message('some-message')
.detail('some-detail')
.errors(errors)
.build();

test('build returns a Validation object', () => {
const expectedValidation: Validation = {
timestamp: '2022-08-03T17:28:49Z',
version: '1.0',
status,
category: 'some-category',
message: 'some-message',
detail: 'some-detail',
errors,
};

const output: Validation = builder
.category('some-category')
.message('some-message')
.detail('some-detail')
.timestamp('2022-08-03T17:28:49Z')
.errors([{
message: "While converting to json node: 2 schema violations found",
level: 500,
category: "category-x"
}]).build();

const expectedValidation: Validation = {
category: 'some-category',
message: 'some-message',
detail: 'some-detail',
timestamp: '2022-08-03T17:28:49Z',
errors: [{
message: "While converting to json node: 2 schema violations found",
level: 500,
category: "category-x"
}]
};

expect(output).toEqual(expectedValidation);
})

});
expect(output).toEqual(expectedValidation);
});
});
Loading

0 comments on commit bb4aea4

Please sign in to comment.