Skip to content

Commit

Permalink
feat(reverseproxy): updated DB amd api's to store the connection status
Browse files Browse the repository at this point in the history
BREAKING CHANGE: metadata api route is removed
  • Loading branch information
madhavilosetty-intel committed May 24, 2021
1 parent 903b199 commit 144e664
Show file tree
Hide file tree
Showing 36 changed files with 2,014 additions and 10,756 deletions.
1 change: 1 addition & 0 deletions .mpsrc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"cors_headers":"*",
"cors_methods":"*",
"connection_string": "postgresql://postgresadmin:admin123@localhost:5432/mpsdb",
"instance_name" : "localhost",
"mps_tls_config" : {
"key": "../private/mpsserver-cert-private.key",
"cert": "../private/mpsserver-cert-public.crt",
Expand Down
2 changes: 2 additions & 0 deletions data/initMPS.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ CREATE TABLE IF NOT EXISTS devices(
guid uuid NOT NULL,
tags text[],
hostname varchar(256),
mpsinstance text,
connectionstatus boolean,
CONSTRAINT device_guid UNIQUE(guid)
);
11,325 changes: 1,060 additions & 10,265 deletions package-lock.json

Large diffs are not rendered by default.

149 changes: 149 additions & 0 deletions src/db/device.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*********************************************************************
* Copyright (c) Intel Corporation 2021
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
import { logger as log } from '../utils/logger'
import { PostgresDb } from '.'
import { IDeviceDb } from '../interfaces/IDeviceDb'
import { Environment } from '../utils/Environment'
import { Device } from '../models/models'
import { mapToDevice } from './mapToDevice'
import { MPSValidationError } from '../utils/MPSValidationError'

export class DeviceDb implements IDeviceDb {
db: PostgresDb
constructor (db?: PostgresDb) {
this.db = db ?? new PostgresDb(Environment.Config.connection_string)
}

/**
* @description Get all devices from DB
* @returns {Device[]} returns an array of objects
*/
async get (): Promise<Device[]> {
const results = await this.db.query('SELECT * FROM devices')
return results.rows.map(p => {
const result = mapToDevice(p)
return result
})
}

/**
* @description Get a device from DB by guid
* @param {string} guid
* @returns {Device} Device object
*/
async getById (guid: string): Promise<Device> {
const results = await this.db.query('SELECT * FROM devices WHERE guid = $1', [guid])
let domain: Device = null
if (results.rowCount > 0) {
domain = mapToDevice(results.rows[0])
}
return domain
}

async getByTags (tags: string[], method: string): Promise<Device[]> {
let results
if (method === 'AND') {
results = await this.db.query('SELECT * FROM devices WHERE tags @> $1', [tags])
} else { // assume OR
results = await this.db.query('SELECT * FROM devices WHERE tags && $1', [tags])
}
return results.rows.map(p => {
const result = mapToDevice(p)
return result
})
}

async getDistinctTags (): Promise<string[]> {
const results = await this.db.query('SELECT DISTINCT unnest(tags) as tag FROM Devices')
return results.rows.map(p => {
return p.tag
})
}

/**
* @description Insert a device into DB
* @param {Device} device
* @returns {boolean} Return true on successful insertion
*/
async insert (device: Device): Promise<Device> {
try {
const results = await this.db.query('INSERT INTO devices(guid, hostname, tags, mpsinstance, connectionstatus) values($1, $2, ARRAY(SELECT json_array_elements_text($3)), $4, $5)',
[
device.guid,
device.hostname,
JSON.stringify(device.tags),
device.mpsInstance,
device.connectionStatus
])
if (results.rowCount > 0) {
return await this.getById(device.guid)
}
return null
} catch (error) {
log.error(`Failed to insert: ${device.guid}`, error)
if (error.code === '23505') { // Unique key violation
throw new MPSValidationError(`Device ID: ${device.guid} already exists`, 400, 'Unique key violation')
}
throw new MPSValidationError(`Failed to insert device: ${device.guid}, error: ${error}`, 500)
}
}

/**
* @description Update into DB
* @param {Device} deviceMetadata object
* @returns {boolean} Return true on successful update
*/
async update (device: Device): Promise <Device> {
try {
const results = await this.db.query('UPDATE devices SET tags=$2, hostname=$3, mpsinstance=$4, connectionstatus=$5 WHERE guid=$1',
[
device.guid,
device.tags,
device.hostname,
device.mpsInstance,
device.connectionStatus
])
if (results.rowCount > 0) {
return await this.getById(device.guid)
}
throw new MPSValidationError(`Failed to update device: ${device.guid}`, 400)
} catch (error) {
log.error(`Failed to update: ${device.guid}`, error)
throw new MPSValidationError(`Failed to update device: ${device.guid}, error: ${error}`, 500)
}
}

/**
* @description Clear the mpsInstance for associated devices before process exit
* @param {string} mpsInstance
* @returns {void}
*/
clearInstanceStatus (mpsInstance: string): void {
try {
const results = this.db.query('UPDATE devices SET mpsinstance=$2, connectionstatus=$3 WHERE mpsinstance=$1',
[
mpsInstance,
null,
false
])
log.info('Clean DB instance before exit', results)
} catch (error) {
log.error('Failed to update DB:', error)
}
}

/**
* @description Delete from DB by name
* @param {string} guid
* @returns {boolean} Return true on successful deletion
*/
async delete (guid): Promise<boolean> {
const results = await this.db.query('DELETE FROM devices WHERE guid = $1', [guid])
if (results.rowCount > 0) {
return true
}
return false
}
}
8 changes: 5 additions & 3 deletions src/db/mapToMetadata.ts → src/db/mapToDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
* Copyright (c) Intel Corporation 2021
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
import { DeviceMetadata } from '../models/models'
import { Device } from '../models/models'

export function mapToMetadata (result): DeviceMetadata {
export function mapToDevice (result): Device {
return {
guid: result.guid,
hostname: result.hostname,
tags: result.tags
tags: result.tags,
mpsInstance: result.mpsinstance,
connectionStatus: result.connectionstatus
}
}
135 changes: 0 additions & 135 deletions src/db/metadata.ts

This file was deleted.

15 changes: 14 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { parseValue } from './utils/parseEnvValue'

import rc from 'rc'
import { Environment } from './utils/Environment'

import { DeviceDb } from './db/device'
try {
// To merge ENV variables. consider after lowercasing ENV since our config keys are lowercase
process.env = Object.keys(process.env)
Expand Down Expand Up @@ -47,6 +47,19 @@ try {
// DB initialization

const db: IDbProvider = new SecretsDbProvider(new SecretManagerService(config, log), log, config)
const deviceDb = new DeviceDb()

// Cleans the DB before exit when it listens to the signals
const signals = ['SIGINT', 'exit', 'uncaughtException', 'SIGTERM', 'SIGHUP']
signals.forEach((signal) => {
process.on(signal, () => {
console.log('signal received :', signal)
deviceDb.clearInstanceStatus(Environment.Config.instance_name)
if (signal !== 'exit') {
setTimeout(() => process.exit(), 1000)
}
})
})

// Certificate Configuration and Operations
if (config.https || !config.tls_offload) {
Expand Down
14 changes: 7 additions & 7 deletions src/interfaces/IDeviceDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
* Copyright (c) Intel Corporation 2021
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
import { DeviceMetadata } from '../models/models'
import { Device } from '../models/models'

export interface IMetadataDb {
get: () => Promise<DeviceMetadata[]>
export interface IDeviceDb {
get: () => Promise<Device[]>
getDistinctTags: () => Promise<String[]>
getById: (guid: string) => Promise<DeviceMetadata>
getByTags: (tags: string[], method: string) => Promise<DeviceMetadata[]>
getById: (guid: string) => Promise<Device>
getByTags: (tags: string[], method: string) => Promise<Device[]>
delete: (guid: string) => Promise<boolean>
insert: (data: DeviceMetadata) => Promise<DeviceMetadata>
update: (data: DeviceMetadata) => Promise<DeviceMetadata>
insert: (data: Device) => Promise<Device>
update: (data: Device) => Promise<Device>
}
1 change: 1 addition & 0 deletions src/models/Config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface configType {
cors_headers: string
cors_methods: string
connection_string: string
instance_name: string
}

export interface certificatesType {
Expand Down
Loading

0 comments on commit 144e664

Please sign in to comment.