const AWS = require ( "aws-sdk" ) ; export class Statistics { public static Table = "bst-stats" ; private static Singleton = new Statistics ( ) ; private _dynamoClient : any = null ; private _docClient : any = null ; public static instance ( ) { return Statistics . Singleton ; } private dynamoClient ( ) { this . configure ( ) ; if ( this . _dynamoClient === null ) { this . _dynamoClient = new AWS . DynamoDB ( ) ; } return this . _dynamoClient ; } private docClient ( ) { this . configure ( ) ; if ( this . _docClient === null ) { console . time ( "OpenClient" ) ; this . _docClient = new AWS . DynamoDB . DocumentClient ( { maxRetries : 0 } ) ; console . timeEnd ( "OpenClient" ) ; } return this . _docClient ; } private configure ( ) { AWS . config . update ( { region : "us-east-1" } ) ; } public deleteTable ( deleted ) { const dynamoClient = this . dynamoClient ( ) ; const dynamoParams = { TableName : Statistics . Table } ; dynamoClient . deleteTable ( dynamoParams , function ( ) { deleted ( ) ; } ) ; } public createTable ( created ) { const dynamoClient = this . dynamoClient ( ) ; const dynamoParams = { TableName : Statistics . Table , KeySchema : [ { AttributeName : "nodeID" , KeyType : "HASH" } , { AttributeName : "timestamp" , KeyType : "RANGE" } ] , AttributeDefinitions : [ { AttributeName : "nodeID" , AttributeType : "S" } , { AttributeName : "timestamp" , AttributeType : "S" } ] , ProvisionedThroughput : { ReadCapacityUnits : 10 , WriteCapacityUnits : 10 } } ; dynamoClient . createTable ( dynamoParams , function ( ) { created ( ) ; } ) ; } public record ( nodeID , accessType , confirmation ? ) { console . time ( "Statistics.record" ) ; const self = this ; const timestamp = new Date ( ) . toISOString ( ) ; const docClient = this . docClient ( ) ; if ( nodeID === null || nodeID === "" ) { nodeID = "N/A" ; } const dynamoParams = { TableName : Statistics . Table , Item : { "nodeID" : nodeID , "timestamp" : timestamp , "accessType" : AccessType [ accessType ] } } ; console . log ( "Access Node: " + nodeID + " Time: " + timestamp + " Access: " + AccessType [ accessType ] ) ; docClient . put ( dynamoParams , function ( error ) { if ( error ) { console . error ( "DynamoPutError: " + error ) ; if ( error . code === "ResourceNotFoundException" ) { self . createTable ( function ( ) { self . record ( nodeID , accessType , confirmation ) ; } ) ; } else { if ( confirmation ) { confirmation ( error ) ; } } } else { if ( confirmation ) { confirmation ( ) ; } } } ) ; console . timeEnd ( "Statistics.record" ) ; } } export enum AccessType { CONNECT , REQUEST_FORWARDED , REQUEST_DROPPED }