From e1e8ebcc80601b24510234b544aa77ad46ce56fd Mon Sep 17 00:00:00 2001 From: naveen30 Date: Tue, 17 May 2022 14:39:06 -0400 Subject: [PATCH] testing with source --- cloud/gcp/functions.tf | 4 +- udmif/event-handler/.gitignore | 2 +- udmif/event-handler/dist.zip | Bin 8479 -> 0 bytes udmif/event-handler/dist/DeviceDao.js | 22 ++++++ udmif/event-handler/dist/DeviceDaoFactory.js | 29 ++++++++ .../dist/DeviceDocumentFactory.js | 65 ++++++++++++++++++ .../event-handler/dist/UdmiMessageHandler.js | 37 ++++++++++ udmif/event-handler/dist/index.js | 23 +++++++ udmif/event-handler/dist/model.js | 39 +++++++++++ udmif/event-handler/dist/package.json | 39 +++++++++++ udmif/event-handler/index.zip | Bin 0 -> 4160 bytes 11 files changed, 257 insertions(+), 3 deletions(-) delete mode 100644 udmif/event-handler/dist.zip create mode 100644 udmif/event-handler/dist/DeviceDao.js create mode 100644 udmif/event-handler/dist/DeviceDaoFactory.js create mode 100644 udmif/event-handler/dist/DeviceDocumentFactory.js create mode 100644 udmif/event-handler/dist/UdmiMessageHandler.js create mode 100644 udmif/event-handler/dist/index.js create mode 100644 udmif/event-handler/dist/model.js create mode 100644 udmif/event-handler/dist/package.json create mode 100644 udmif/event-handler/index.zip diff --git a/cloud/gcp/functions.tf b/cloud/gcp/functions.tf index 7bb3a2dd35..71369a4db3 100644 --- a/cloud/gcp/functions.tf +++ b/cloud/gcp/functions.tf @@ -13,8 +13,8 @@ resource "google_storage_bucket" "function-bucket" { # Generates an archive of the source code compressed as a .zip file. data "archive_file" "source" { type = "zip" - source_dir = "../../udmif/event-handler/src" - output_path = "../../udmif/event-handler/dist.zip" + source_dir = "../../udmif/event-handler/dist" + output_path = "../../udmif/event-handler/index.zip" } # Add the zipped file to the bucket. resource "google_storage_bucket_object" "function-object" { diff --git a/udmif/event-handler/.gitignore b/udmif/event-handler/.gitignore index eb50c88fda..ff4c33a5ef 100644 --- a/udmif/event-handler/.gitignore +++ b/udmif/event-handler/.gitignore @@ -21,4 +21,4 @@ setupEnv.sh # mongo output .mongodb -dist/ \ No newline at end of file +#dist/ \ No newline at end of file diff --git a/udmif/event-handler/dist.zip b/udmif/event-handler/dist.zip deleted file mode 100644 index 4afd9e06c7af757af0de0a4ee21c3d028817503f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8479 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 Goc$l&y4D*2 diff --git a/udmif/event-handler/dist/DeviceDao.js b/udmif/event-handler/dist/DeviceDao.js new file mode 100644 index 0000000000..8627890fb5 --- /dev/null +++ b/udmif/event-handler/dist/DeviceDao.js @@ -0,0 +1,22 @@ +import { Collection } from 'mongodb'; +import { DeviceKey, DeviceDocument } from './model'; + +const options = { upsert: true }; + +export interface DeviceDao { + upsert(filterQuery: any, updateQuery: any); +} + +export class DefaultDeviceDao implements DeviceDao { + constructor(private collection: Collection) {} + + async upsert(deviceKey: DeviceKey, deviceDocument: DeviceDocument): Promise { + // we're using upsert which will allow document updates if it already exists and a document cretion if it does not + console.debug('Attempting to write the following device document: ' + JSON.stringify(deviceDocument)); + + const result = await this.collection.updateOne(deviceKey, { $set: deviceDocument }, options); + + // let's log the result to give us some feedback on what occurred during the upsert + console.log(JSON.stringify(result)); + } +} diff --git a/udmif/event-handler/dist/DeviceDaoFactory.js b/udmif/event-handler/dist/DeviceDaoFactory.js new file mode 100644 index 0000000000..c9c13561ce --- /dev/null +++ b/udmif/event-handler/dist/DeviceDaoFactory.js @@ -0,0 +1,29 @@ +import { DeviceDao, DefaultDeviceDao } from './DeviceDAO'; +import { Collection, MongoClient } from 'mongodb'; + +const COLLECTION_NAME: string = 'device'; + +export async function getDeviceDAO(): Promise { + return new DefaultDeviceDao(await getMongoCollection()); +} + +async function getMongoCollection(): Promise { + const client = await MongoClient.connect(getUri(), {}); + + // get the collection + const db = process.env.MONGO_DATABASE; + console.log(`Getting the Mongo Collection for db: ${db} collection: ${COLLECTION_NAME}`); + return client.db(db).collection(COLLECTION_NAME); +} + +export function getUri(): string { + const protocol = process.env.MONGO_PROTOCOL; + const host = process.env.MONGO_HOST; + const userName = process.env.MONGO_USER; + const password = process.env.MONGO_PWD; + + // get the uri + const credentials = userName ? `${userName}:${password}@` : ''; + console.log(`Building a new Mongo Client uri: ${protocol}://*****:*****@${host}`); + return `${protocol}://${credentials}${host}`; +} diff --git a/udmif/event-handler/dist/DeviceDocumentFactory.js b/udmif/event-handler/dist/DeviceDocumentFactory.js new file mode 100644 index 0000000000..ea5df1bda6 --- /dev/null +++ b/udmif/event-handler/dist/DeviceDocumentFactory.js @@ -0,0 +1,65 @@ +import { DeviceDocument, UdmiMessage } from './model'; + +const POINTSET_SUB_FOLDER = 'pointset'; +const SYSTEM_SUB_FOLDER = 'system'; +const MODEL = 'model'; +const STATE = 'state'; + +export function createDeviceDocument(message: UdmiMessage): DeviceDocument { + if (isSystemState(message)) { + return createSystemStateDocument(message); + } else if (isSystemModel(message)) { + return createSystemModelDocument(message); + } else { + return createDefaultDeviceDocument(message); + } +} + +function createSystemModelDocument(message: UdmiMessage): DeviceDocument { + const deviceDocument: DeviceDocument = createDefaultDeviceDocument(message); + + deviceDocument.section = message.data.location.section; + deviceDocument.site = message.data.location.site; + + return deviceDocument; +} + +function createSystemStateDocument(message: UdmiMessage): DeviceDocument { + const deviceDocument: DeviceDocument = createDefaultDeviceDocument(message); + + deviceDocument.make = message.data.hardware.make; + deviceDocument.model = message.data.hardware.model; + deviceDocument.operational = message.data.operational; + deviceDocument.serialNumber = message.data.serial_no; + deviceDocument.firmware = message.data.software.firmware; + + return deviceDocument; +} + +function createDefaultDeviceDocument(message: UdmiMessage): DeviceDocument { + const deviceDocument: DeviceDocument = { + name: message.attributes.deviceId, + id: message.attributes.deviceNumId, + }; + + if (message.data.timestamp) { + deviceDocument.lastPayload = message.data.timestamp; + } + return deviceDocument; +} + +export function isSystemState(message): boolean { + return isSubFolder(message, SYSTEM_SUB_FOLDER) && isSubType(message, STATE); +} + +export function isSystemModel(message): boolean { + return isSubFolder(message, SYSTEM_SUB_FOLDER) && isSubType(message, MODEL); +} + +export function isSubFolder(message, folderName: string): boolean { + return message.attributes.subFolder === folderName; +} + +export function isSubType(message, type: string): boolean { + return message.attributes.subType === type; +} diff --git a/udmif/event-handler/dist/UdmiMessageHandler.js b/udmif/event-handler/dist/UdmiMessageHandler.js new file mode 100644 index 0000000000..027dc9bade --- /dev/null +++ b/udmif/event-handler/dist/UdmiMessageHandler.js @@ -0,0 +1,37 @@ +import { DeviceDao } from './DeviceDao'; +import { createDeviceDocument } from './DeviceDocumentFactory'; +import { DeviceDocument, DeviceKey, UdmiMessage } from './model'; + +export default class UdmiMessageHandler { + constructor(private deviceDao: DeviceDao) {} + + handleUdmiEvent(event: any) { + try { + const message: UdmiMessage = decodeEventData(event); + const deviceKey: DeviceKey = getDeviceKey(message); + const document: DeviceDocument = createDeviceDocument(message); + this.writeDocument(deviceKey, document); + } catch (e) { + console.error('An unexpected error occurred: ', e); + } + } + + private async writeDocument(key: DeviceKey, document: DeviceDocument) { + await this.deviceDao.upsert(key, document); + } +} + +export function decodeEventData(event: any): UdmiMessage { + const stringData = Buffer.from(event.data, 'base64').toString(); + event.data = JSON.parse(stringData); + console.debug('Decoded event: ', JSON.stringify(event)); + return event; +} + +export function getDeviceKey(message: UdmiMessage): DeviceKey { + if (!message.attributes.deviceId || !message.attributes.deviceNumId) { + throw new Error('An invalid device name or id was submitted'); + } + + return { name: message.attributes.deviceId, id: message.attributes.deviceNumId }; +} diff --git a/udmif/event-handler/dist/index.js b/udmif/event-handler/dist/index.js new file mode 100644 index 0000000000..f3b89d89ab --- /dev/null +++ b/udmif/event-handler/dist/index.js @@ -0,0 +1,23 @@ +import type { EventFunction } from '@google-cloud/functions-framework/build/src/functions'; +import { getDeviceDAO } from './DeviceDaoFactory'; +import UdmiMessageHandler from './UdmiMessageHandler'; + +let messageHandler: UdmiMessageHandler; + +/** + * Triggered from a message on a Cloud Pub/Sub topic. + * + * @param {!Object} event Event payload. + * @param {!Object} context Metadata for the event. + */ +export const handleUdmiEvent: EventFunction = async (event: any, context: any) => { + try { + if (!messageHandler) { + console.log('Creating Message Handler'); + messageHandler = new UdmiMessageHandler(await getDeviceDAO()); + } + messageHandler.handleUdmiEvent(event); + } catch (e) { + console.error('An unexpected error occurred: ', e); + } +}; diff --git a/udmif/event-handler/dist/model.js b/udmif/event-handler/dist/model.js new file mode 100644 index 0000000000..8c759a49e6 --- /dev/null +++ b/udmif/event-handler/dist/model.js @@ -0,0 +1,39 @@ +export interface DeviceKey { + name: string; + id: string; + } + + export interface DeviceDocument { + name: string; + id: string; + lastPayload?: string; + make?: string; + model?: string; + operational?: string; + serialNumber?: string; + firmware?: string; + section?: string; + site?: string; + } + + export interface UdmiMessage { + attributes: { + deviceId: string; + deviceNumId: string; + }; + data: { + hardware?: { + make: string; + model: string; + }; + location?: { + section: string; + site: string; + }; + software?: any; + operational?: string; + serial_no?: string; + timestamp?: string; + }; + } + \ No newline at end of file diff --git a/udmif/event-handler/dist/package.json b/udmif/event-handler/dist/package.json new file mode 100644 index 0000000000..4a7e91b0c6 --- /dev/null +++ b/udmif/event-handler/dist/package.json @@ -0,0 +1,39 @@ +{ + "name": "udmi-device-cf", + "version": "1.0.0", + "description": "Cloud Function that Receives Events and Writes Device Documents to MongoDB", + "author": "Buildings IOT", + "main": "dist/index.js", + "license": "ISC", + "dependencies": { + "mongodb": "^4.4.1" + }, + "devDependencies": { + "@google-cloud/functions-framework": "^3.0.0", + "@shelf/jest-mongodb": "^2.2.1", + "@types/jest": "^27.4.0", + "@types/node": "^17.0.10", + "concurrently": "^7.1.0", + "husky": "^7.0.4", + "jest": "^27.4.7", + "jest-junit": "^13.0.0", + "lint-staged": "^12.2.2", + "nodemon": "^2.0.16", + "prettier": "^2.5.1", + "ts-jest": "^27.1.3", + "ts-node": "^10.4.0", + "typescript": "^4.5.5" + }, + "scripts": { + "dev": "nodemon --watch src --watch data -e js,ts,txt,response,json --exec node -r ts-node/register --inspect=0.0.0.0:6329 src/index.ts", + "start": "functions-framework --source=dist/ --target=handleUdmiEvent --signature-type=event", + "watch": "concurrently \"tsc -w\" \"nodemon --watch ./build/ --exec npm run start\"", + "test": "NODE_ENV=test jest --runInBand --silent --detectOpenHandles", + "testInteractive": "NODE_ENV=test jest --runInBand --silent --watchAll", + "postinstall": "cd ../.. && husky install udmif/event-handler/.husky", + "build": "tsc -p ." + }, + "lint-staged": { + "src/**/*.{ts,tsx,json}": "prettier --single-quote --arrow-parens always --trailing-comma es5 --print-width 120 --write" + } + } \ No newline at end of file diff --git a/udmif/event-handler/index.zip b/udmif/event-handler/index.zip new file mode 100644 index 0000000000000000000000000000000000000000..ffcb0a5c8f7b4a0e083bc0dab11f508fde21426d GIT binary patch literal 4160 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 IkzINJ0d24k(*OVf literal 0 HcmV?d00001