diff --git a/Projects/Social-Trading/NT/Modules/ClientInterface.js b/Projects/Social-Trading/NT/Modules/ClientInterface.js index bd429b878..0da1aa0d4 100644 --- a/Projects/Social-Trading/NT/Modules/ClientInterface.js +++ b/Projects/Social-Trading/NT/Modules/ClientInterface.js @@ -1,15 +1,16 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModulesClientInterface() { /* This module represents the Interface the Network Node have - with Network Clients connected to it. There are two things + with Network Clients connected to it. There are 3 things Network Clients can do with this Network Node: - * Send an Event that happened at the Network Client to the Network. * Make a Query to the Network Node for info needed at the Network Client. + * Send an Event that happened at the Network Client to the Network. + * Send a Signal that needs to be distributed. This interface is one layer above the communication protocol interface where actual messages are received through, like for instance the - websockets interface. + websockets interface or http interface. */ let thisObject = { messageReceived: messageReceived, @@ -47,7 +48,7 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule return response } - if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') { + if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query' && messageHeader.requestType !== 'Signal') { let response = { result: 'Error', message: 'Client Interface requestType Not Supported.' @@ -56,15 +57,99 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule } switch (messageHeader.requestType) { + case 'Query': { + return await queryReceived(messageHeader.queryMessage, userProfile) + } case 'Event': { return await eventReceived(messageHeader.eventMessage, userProfile) } - case 'Query': { - return await queryReceived(messageHeader.queryMessage, userProfile) + case 'Signal': { + return await signalReceived(messageHeader.eventMessage, userProfile) } } } + async function queryReceived(queryMessage, userProfile) { + /* + We expect here a JSON string with some or all of the following properties: + + { + "queryType": 10, + "emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterUserProfileHandle": "Luis-Fernando-Molina", + "targetUserProfileHandle": "Luis-Fernando-Molina", + "emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "timestamp": 124234234234, + "botAsset": "BTC", + "botExchange": "Binance", + "botEnabled": true, + "initialIndex": 35, + "amountRequested": 50, + "direction": "Past" + } + */ + + let queryReceived + try { + queryReceived = JSON.parse(queryMessage) + } catch (err) { + let response = { + result: 'Error', + message: 'Client Interface queryMessage Not Correct JSON Format.' + } + return response + } + /* + At the Client Interface, queries need to be emitted by the same userProfile that is + connected at the Network Node. + */ + if (queryReceived.emitterUserProfileId !== userProfile.userProfileId) { + let response = { + result: 'Error', + message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.' + } + return response + } + /* + Here we will process the query. This does not change the state of the Social Graph. + */ + try { + let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery() + query.initialize(queryReceived) + + // console.log((new Date()).toISOString(), '- Client Interface', '- Query Message Received', queryMessage) + + let response = { + result: 'Ok', + message: 'Client Interface Query Processed.', + data: query.execute() + } + + // console.log((new Date()).toISOString(), '- Client Interface', '- Query Response Sent', JSON.stringify(response)) + + return response + + } catch (err) { + /* + Any exception that happens while trying to execute the query. + */ + if (err.stack !== undefined) { + console.log('[ERROR] Client Interface -> err.stack = ' + err.stack) + } + let errorMessage = err.message + if (errorMessage === undefined) { errorMessage = err } + let response = { + result: 'Error', + message: 'Client Interface ' + errorMessage + } + return response + } + } + async function eventReceived(eventMessage, userProfile) { /* We expect here a JSON string with some or all of the following properties: @@ -160,16 +245,15 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule } } - async function queryReceived(queryMessage, userProfile) { + async function signalReceived(signalMessage, userProfile) { /* We expect here a JSON string with some or all of the following properties: { - "queryType": 10, + "signalId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "signalType": 10, "emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", "targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", - "emitterUserProfileHandle": "Luis-Fernando-Molina", - "targetUserProfileHandle": "Luis-Fernando-Molina", "emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", "targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", "emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", @@ -177,56 +261,60 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule "timestamp": 124234234234, "botAsset": "BTC", "botExchange": "Binance", - "botEnabled": true, - "initialIndex": 35, - "amountRequested": 50, - "direction": "Past" + "botEnabled": true } */ - let queryReceived + let signalReceived try { - queryReceived = JSON.parse(queryMessage) + signalReceived = JSON.parse(signalMessage) } catch (err) { let response = { result: 'Error', - message: 'Client Interface queryMessage Not Correct JSON Format.' + message: 'Client Interface signalMessage Not Correct JSON Format.' } return response } /* - At the Client Interface, queries need to be emitted by the same userProfile that is - connected at the Network Node. + We will not accept signals that don't have an signalId. */ - if (queryReceived.emitterUserProfileId !== userProfile.userProfileId) { + if (signalReceived.signalId === undefined) { let response = { result: 'Error', - message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.' + message: 'signalId Not Provided.' } return response } /* - Here we will process the query. This does not change the state of the Social Graph. + We will not accept signals that have already been processed. + */ + + if (NT.projects.network.globals.memory.maps.SIGNALS.get(signalReceived.signalId) !== undefined) { + let response = { + result: 'Error', + message: 'Client Interface Signal Already Exists.' + } + return response + } + /* + Here we will process the signal and change the state of the Social Graph. */ try { - let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery() - query.initialize(queryReceived) - - // console.log((new Date()).toISOString(), '- Client Interface', '- Query Message Received', queryMessage) + let signal = NT.projects.socialTrading.modules.signal.newSocialTradingModulesSignal() + signal.initialize(signalReceived) + NT.projects.network.globals.memory.maps.SIGNALS.set(signalReceived.eventId, signal) + NT.projects.network.globals.memory.arrays.SIGNALS.push(signal) let response = { result: 'Ok', - message: 'Client Interface Query Processed.', - data: query.execute() + message: 'Client Interface Signal Processed.' } - - // console.log((new Date()).toISOString(), '- Client Interface', '- Query Response Sent', JSON.stringify(response)) - return response } catch (err) { /* - Any exception that happens while trying to execute the query. + Any exception that happens while trying to change the state of the Social Graph, + will be returned to the caller without doing anything else here. */ if (err.stack !== undefined) { console.log('[ERROR] Client Interface -> err.stack = ' + err.stack)