From 4e9af8fb7b2fe38dd65aa23fc76df940c2332351 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 27 Nov 2021 15:00:42 +0100 Subject: [PATCH 1/3] Signals Nodes Arriving at the TS --- .../TradingSessionFunctions.js | 3 +++ .../App-Schema/take-position-event.json | 20 +++++++++--------- .../Schemas/App-Schema/trigger-off-event.json | 20 +++++++++--------- .../Schemas/App-Schema/trigger-on-event.json | 20 +++++++++--------- ...ceive-signals.png => incoming-signals.png} | Bin ...{send-signals.png => outgoing-signals.png} | Bin ...ive-signals.json => incoming-signals.json} | 4 ++-- ...end-signals.json => outgoing-signals.json} | 4 ++-- .../TS/Bot-Modules/TradingSignals.js | 1 + 9 files changed, 38 insertions(+), 34 deletions(-) rename Projects/Trading-Signals/Icons/{receive-signals.png => incoming-signals.png} (100%) rename Projects/Trading-Signals/Icons/{send-signals.png => outgoing-signals.png} (100%) rename Projects/Trading-Signals/Schemas/App-Schema/{receive-signals.json => incoming-signals.json} (93%) rename Projects/Trading-Signals/Schemas/App-Schema/{send-signals.json => outgoing-signals.json} (93%) diff --git a/Projects/Algorithmic-Trading/UI/Function-Libraries/TradingSessionFunctions.js b/Projects/Algorithmic-Trading/UI/Function-Libraries/TradingSessionFunctions.js index 1a3d66ec7..0ab17f9f4 100644 --- a/Projects/Algorithmic-Trading/UI/Function-Libraries/TradingSessionFunctions.js +++ b/Projects/Algorithmic-Trading/UI/Function-Libraries/TradingSessionFunctions.js @@ -105,6 +105,9 @@ function newAlgorithmicTradingFunctionLibraryTradingSessionFunctions() { 'Managed Stop Loss->Managed Take Profit->' + 'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' + 'Situation->Condition->Javascript Code->' + + 'Outgoing Signals->Incoming Signals->Signal Reference->' + + 'Trigger On Signal->Trigger Off Signal->Take Position Signal->' + + 'Create Order Signal->Cancel Order Signal->' + 'Close Stage->' + 'Initial Targets->Target Size In Base Asset->Target Size In Quoted Asset->Target Rate->Formula->' + 'Open Execution->Close Execution->' + diff --git a/Projects/Foundations/Schemas/App-Schema/take-position-event.json b/Projects/Foundations/Schemas/App-Schema/take-position-event.json index 6d6c2472f..5a203b569 100644 --- a/Projects/Foundations/Schemas/App-Schema/take-position-event.json +++ b/Projects/Foundations/Schemas/App-Schema/take-position-event.json @@ -21,20 +21,20 @@ "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "sendSignals", + "propertyToCheckFor": "outgoingSignals", "actionFunction": "payload.executeAction", - "label": "Add Send Signals", - "relatedUiObject": "Send Signals", + "label": "Add Outgoing Signals", + "relatedUiObject": "Outgoing Signals", "relatedUiObjectProject": "Trading-Signals" }, { "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "receiveSignals", + "propertyToCheckFor": "incomingSignals", "actionFunction": "payload.executeAction", - "label": "Add Receive Signals", - "relatedUiObject": "Receive Signals", + "label": "Add Incoming Signals", + "relatedUiObject": "Incoming Signals", "relatedUiObjectProject": "Trading-Signals" }, { @@ -67,15 +67,15 @@ "project": "Social-Bots" }, { - "name": "sendSignals", + "name": "outgoingSignals", "type": "node", - "childType": "Send Signals", + "childType": "Outgoing Signals", "project": "Trading-Signals" }, { - "name": "receiveSignals", + "name": "incomingSignals", "type": "node", - "childType": "Receive Signals", + "childType": "Incoming Signals", "project": "Trading-Signals" } ], diff --git a/Projects/Foundations/Schemas/App-Schema/trigger-off-event.json b/Projects/Foundations/Schemas/App-Schema/trigger-off-event.json index 57977f828..65eec5f08 100644 --- a/Projects/Foundations/Schemas/App-Schema/trigger-off-event.json +++ b/Projects/Foundations/Schemas/App-Schema/trigger-off-event.json @@ -21,20 +21,20 @@ "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "sendSignals", + "propertyToCheckFor": "outgoingSignals", "actionFunction": "payload.executeAction", - "label": "Add Send Signals", - "relatedUiObject": "Send Signals", + "label": "Add Outgoing Signals", + "relatedUiObject": "Outgoing Signals", "relatedUiObjectProject": "Trading-Signals" }, { "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "receiveSignals", + "propertyToCheckFor": "incomingSignals", "actionFunction": "payload.executeAction", - "label": "Add Receive Signals", - "relatedUiObject": "Receive Signals", + "label": "Add Incoming Signals", + "relatedUiObject": "Incoming Signals", "relatedUiObjectProject": "Trading-Signals" }, { @@ -67,15 +67,15 @@ "project": "Social-Bots" }, { - "name": "sendSignals", + "name": "outgoingSignals", "type": "node", - "childType": "Send Signals", + "childType": "Outgoing Signals", "project": "Trading-Signals" }, { - "name": "receiveSignals", + "name": "incomingSignals", "type": "node", - "childType": "Receive Signals", + "childType": "Incoming Signals", "project": "Trading-Signals" } ], diff --git a/Projects/Foundations/Schemas/App-Schema/trigger-on-event.json b/Projects/Foundations/Schemas/App-Schema/trigger-on-event.json index 270ab9c48..2b7a7e9ab 100644 --- a/Projects/Foundations/Schemas/App-Schema/trigger-on-event.json +++ b/Projects/Foundations/Schemas/App-Schema/trigger-on-event.json @@ -21,20 +21,20 @@ "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "sendSignals", + "propertyToCheckFor": "outgoingSignals", "actionFunction": "payload.executeAction", - "label": "Add Send Signals", - "relatedUiObject": "Send Signals", + "label": "Add Outgoing Signals", + "relatedUiObject": "Outgoing Signals", "relatedUiObjectProject": "Trading-Signals" }, { "action": "Add UI Object", "actionProject": "Visual-Scripting", "disableIfPropertyIsDefined": true, - "propertyToCheckFor": "receiveSignals", + "propertyToCheckFor": "incomingSignals", "actionFunction": "payload.executeAction", - "label": "Add Receive Signals", - "relatedUiObject": "Receive Signals", + "label": "Add Incoming Signals", + "relatedUiObject": "Incoming Signals", "relatedUiObjectProject": "Trading-Signals" }, { @@ -67,15 +67,15 @@ "project": "Social-Bots" }, { - "name": "sendSignals", + "name": "outgoingSignals", "type": "node", - "childType": "Send Signals", + "childType": "Outgoing Signals", "project": "Trading-Signals" }, { - "name": "receiveSignals", + "name": "incomingSignals", "type": "node", - "childType": "Receive Signals", + "childType": "Incoming Signals", "project": "Trading-Signals" } ], diff --git a/Projects/Trading-Signals/Icons/receive-signals.png b/Projects/Trading-Signals/Icons/incoming-signals.png similarity index 100% rename from Projects/Trading-Signals/Icons/receive-signals.png rename to Projects/Trading-Signals/Icons/incoming-signals.png diff --git a/Projects/Trading-Signals/Icons/send-signals.png b/Projects/Trading-Signals/Icons/outgoing-signals.png similarity index 100% rename from Projects/Trading-Signals/Icons/send-signals.png rename to Projects/Trading-Signals/Icons/outgoing-signals.png diff --git a/Projects/Trading-Signals/Schemas/App-Schema/receive-signals.json b/Projects/Trading-Signals/Schemas/App-Schema/incoming-signals.json similarity index 93% rename from Projects/Trading-Signals/Schemas/App-Schema/receive-signals.json rename to Projects/Trading-Signals/Schemas/App-Schema/incoming-signals.json index 788124a5e..92cb341ee 100644 --- a/Projects/Trading-Signals/Schemas/App-Schema/receive-signals.json +++ b/Projects/Trading-Signals/Schemas/App-Schema/incoming-signals.json @@ -1,5 +1,5 @@ { - "type": "Receive Signals", + "type": "Incoming Signals", "menuItems": [ { "action": "Add UI Object", @@ -33,5 +33,5 @@ "autoAdd": false } ], - "propertyNameAtParent": "receiveSignals" + "propertyNameAtParent": "incomingSignals" } \ No newline at end of file diff --git a/Projects/Trading-Signals/Schemas/App-Schema/send-signals.json b/Projects/Trading-Signals/Schemas/App-Schema/outgoing-signals.json similarity index 93% rename from Projects/Trading-Signals/Schemas/App-Schema/send-signals.json rename to Projects/Trading-Signals/Schemas/App-Schema/outgoing-signals.json index 246f118d0..9ea63a012 100644 --- a/Projects/Trading-Signals/Schemas/App-Schema/send-signals.json +++ b/Projects/Trading-Signals/Schemas/App-Schema/outgoing-signals.json @@ -1,5 +1,5 @@ { - "type": "Send Signals", + "type": "Outgoing Signals", "menuItems": [ { "action": "Add UI Object", @@ -33,5 +33,5 @@ "autoAdd": false } ], - "propertyNameAtParent": "sendSignals" + "propertyNameAtParent": "outgoingSignals" } \ No newline at end of file diff --git a/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js b/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js index b000feecb..1ca3f825a 100644 --- a/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js +++ b/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js @@ -18,6 +18,7 @@ exports.newTradingSignalsBotModulesTradingSignals = function (processIndex) { tradingEngine = TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SIMULATION_STATE.tradingEngine sessionParameters = TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.tradingParameters + taskParameters = { exchange: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.name, market: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + From d571630134585eb5541f452bac713da9531f92e0 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 27 Nov 2021 16:52:30 +0100 Subject: [PATCH 2/3] Task Server App Reference Implemented --- .../Foundations/Schemas/App-Schema/task.json | 16 + .../UI/Function-Libraries/TaskFunctions.js | 2 + .../Icons/task-server-app-reference.png | Bin 0 -> 15217 bytes Projects/Governance/Icons/task-server-app.png | Bin 0 -> 15217 bytes .../User-Profiles/Luis-Fernando-Molina.json | 280 ++++++++++++------ .../Schemas/App-Schema/server-apps.json | 14 + .../App-Schema/task-server-app-reference.json | 25 ++ .../Schemas/App-Schema/task-server-app.json | 44 +++ .../Function-Libraries/ProfileConstructor.js | 2 + Projects/Network/SA/Modules/UserProfiles.js | 2 + 10 files changed, 302 insertions(+), 83 deletions(-) create mode 100644 Projects/Governance/Icons/task-server-app-reference.png create mode 100644 Projects/Governance/Icons/task-server-app.png create mode 100644 Projects/Governance/Schemas/App-Schema/task-server-app-reference.json create mode 100644 Projects/Governance/Schemas/App-Schema/task-server-app.json diff --git a/Projects/Foundations/Schemas/App-Schema/task.json b/Projects/Foundations/Schemas/App-Schema/task.json index c13b68202..bd0891240 100644 --- a/Projects/Foundations/Schemas/App-Schema/task.json +++ b/Projects/Foundations/Schemas/App-Schema/task.json @@ -87,6 +87,16 @@ "actionProject": "Visual-Scripting", "relatedUiObjectProject": "Foundations" }, + { + "action": "Add UI Object", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "taskServerAppReference", + "label": "Add Task Server App Reference", + "relatedUiObject": "Task Server App Reference", + "actionFunction": "payload.executeAction", + "actionProject": "Visual-Scripting", + "relatedUiObjectProject": "Governance" + }, { "action": "Delete UI Object", "actionProject": "Visual-Scripting", @@ -134,6 +144,12 @@ "name": "keyReference", "type": "node", "childType": "Key Reference" + }, + { + "name": "taskServerAppReference", + "type": "node", + "childType": "Task Server App Reference", + "project": "Governance" } ], "propertyNameAtParent": "tasks" diff --git a/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js b/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js index 3e945c6ef..8cc0a6c3d 100644 --- a/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js +++ b/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js @@ -116,11 +116,13 @@ function newFoundationsFunctionLibraryTaskFunctions() { } let taskLightingPath = '->Task->' + + 'Task Server App Reference->Signing Account->' 'Sensor Bot Instance->' + 'API Data Fetcher Bot Instance->' + 'Indicator Bot Instance->' + 'Trading Bot Instance->' + 'Learning Bot Instance->' + + 'Social Trading Bot Reference->Signing Account->' + 'Sensor Process Instance->Time Frames Filter->API Data Fetcher Process Instance->Indicator Process Instance->Trading Process Instance->Learning Process Instance->' + 'Social Trading Bot Reference->Social Trading Bot->Signing Account->' + 'Execution Started Event->' + diff --git a/Projects/Governance/Icons/task-server-app-reference.png b/Projects/Governance/Icons/task-server-app-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..a4ee2a209ae5922e1d49d3686dfabf910a979d02 GIT binary patch literal 15217 zcmYj&c|4Tg7yo@`h8g?5WSc=Dglq|!5tT|vKB5%Ln!PNkm}jV@5=9}&Xj4%{*$N{q z%388lrq#Y=UuNd{UEkm9^?UvLr|~@ZIrrRi?>)==oRjS2utP*pK@b2SveVAi82}vo zi322l_}}cwFU#=1HIdugBKL*)MaFm^_XXBIVMlx^J43wveVu*1ePSa%_*w#BA+^)i z+T~>5Sni?A9)Ge22SQ^?1WJdSi&P1g`_6du1U(B3utpU>HXQhQEYQjLVurwTeKj>B z3Dcm!y{>{Sb~%f$FQrHxl!~xEI)6lZo6X7<34G{4R?*dbo1f41Q5PRciE9B07PQm# zBU`W;@64vo@yF(#lkX=rb6xs3M$esgn46*V+GeaK(-2U&xgzdW?|jpJvTHMc)qa-UE^YlNQ>zze?lPvz)szUk9Mf!~Rr z3xIq^^pEg+d(7S>s7eY7S&9G>00RkUWE;z9^spVQ;_DX)G<}~0wp~to`^7ibmkLM# z0qm{JuYd5>?-Hha-1VF{%gaq-$ zoWOSjJ|^P8X>-{l@hsoN&rVx1$Ovd9F+yfZaAni{ z@zu)`fUVJS-p?AYD39TJdSPLeHakVU=YtYlCF>84ia#R`*koa890BMma;}dXmCC{O zbr@cj=O=)BjJiO{m-Ne>@Oy*i?0dQfP0kcRc?EgLQwwHP0mZ}5S+)JhdK`ySMzH3` z9u583kU*tP4f(SU?mlh0=b5w_V8^iY?8LLF}M<1n3F8& z&rF--NiwHEIGPG(9b9F5>YdpD&0%;R;wlX6j-j#viy2UXe#D*7<->t7F^&TJE|>E# z27bPG%;*CLoF}OQ)@SyB{r~160j;bX`8&lC;KPLn;w!j;`+q-a0Ju{r0BnK+blN^u z&_IS_7aEfepMyM@$#DwoON;Z^V!)J{x9zgjI|P-))74v+bBg#ONB5f_gwihEXCdg3 z1kCp4oD>IP`Q3b^$ojok2{f)*>>Mgs!%P3)(4+P_zwHqPLIhy8v5Twwyc4Lv>|%Vh z^5MR+|nPMiNM28R|Z*YD7#gF^^}$RN37EiWB{i51CezI0Yr-MQilGl zD}|y$-v_v|62~MBsgVybVzj3-qZ*^gd+hv;)>P`+1CVKiP^G=b^OFmv32M& zuFi^}FqSBJe%TQ00#5oy8f%nnJ%K3ApuW!g+W#n=y&TVfER&Xap9ao~b8^m~q5|6X zF1dD}_2R&ah(gXiG7C;{2x9`*Rx(2!GQQ-{F5`ot3K?!)#4klvKkOnhS!r-l; zH2x*HD8LisXzdHv$9u_v$`7+p^@ix;MFAW{(bdSD4}Kl74Ty6PAda-_X8?X7&d9EB zyQheQMo=PbtBy}E(izqy^l<{Ug9|T{mzceX(yEA8KT*;dDkIpY4jflom#y(uv{_f7UclLvqD*B~uUwY`+Tz;^Xm z)$k%YiRov|%R6t~KB>k#HTR*rMdnGxukQbZ=#80(0TD3M`O=$70jl7u7|;DZbq}3A z;dn3X3^f{ALx-rI^2Bf!@dUcsHrf|EDu=h*s0rst{kGEihijU7;A1>#_W zj~+62I(bmeW5)~n9QbXGqiv-~@j=UTJJvuFF(QGO1bRdJEb;bKfpW(`J@mEJY~Uld z&=b#_g{`%I&AmpthOFt6{nA6ZfH^F7X6qc6O82J+(y^$~Zp9NLB1gZ+np8PpSGEx= zrS)@galyE+@W6SRz5I838oMeIv$p$&rW7K6iP5d*9e!C6q#4|JcO%3M%==;K=e?Mc1t<=^U=%) z>pmEfYRy6GKdTdXirLN8Q>_Xfi|~%UW~Y&-B*$0ukI#nr-pcy%*ZP8`Oft~SY0s4c z!#AiSJoW~MK1@OKO)wzI&Ed`VUy1&NIQ?zAL7lqsN)zkEwa~>)9jZS&2%uUkVcYdB zPIj^Oe_8VUJLCzCf8dx~U)iH%pryHZl$*Gq>l(4>xaLc2c>8&alqx@UF|i(W-+hp& zfqXn1ICX~6X4cE~T(GvTpzExm-CIaY(YQhRF{SqK_I8EB=;|rITr(lc3!d0aFk|w} z;_o(XWnetz4#t(fhcxF9M-M*7c%u__1M#lNi~#dMq$^7oN1;z;=1$A@QqQJw_0RlT zxz5WuM?we7yX3sCFHxuNHes7<>fD51xrSBYw&u$ms_2dPN)uWKis&TV1588tLy*RJ4GrUdb zi18b{bm44Y@K#OEOO)tkFtnUR@md}L4`--hQ*FH4LAUK|TX*rfV}Qn!kIs1#*4h_> z?wv2@@`O2z|BcLum<@N;cJi#J@&*gc*0nsRx=c(2d+n1YTnI-BL`$F(sq zd&w_&rYt=5bA9I=zrRNES(VXVhM&U`DfiZ$l- zxmpE%9r2s@9GtH@I8hd~Wj5aUnmht@-j^#%fF^%z-}xMThN3iezEFO@Kr~M-Tez4!-(4htQ!MNP}IL(*X zp={p%D*O~bnO3RfYC<@m3IaHZrON1ax2G=5?)#MFe`ae7IY+i*I!UayCeVQeL(&iJQKMR5aemu2u#ucA-;Bw9t+2&vKtS+uU|W zIxv3P-Ppq0ylx?5tlrD`v%J}V-HH##4VcC&{{3XLtK5a@$wGUkdK|{d<^JpLwM+;# z;D&(`te*OOLrM9!uqbm7yn+vdn(NyxKFPuURN{8|d;Rltm zMW;QzboEn9A`2=PY0=9`j=bjNg`3v}c%L~$9e!}AB0g@CzBmtu~tz!e_Y_dQ01DxggwuUrS}LPlrn76N&RTLX{Tmb8h27j&(RV6s)l z1#@h4EVAy0gRR8bt@k&U8X~lLF<*ADP42#4ddocKC)6fTcu*SALywArUaGW?_KxC1 z5j~>Pwz-Vfu3@?{#vnc`m0bPG2Qvfs`YAGtFZ??~SxI{Bz2YguxH3$Ko_V2=Q#G(F z;9ce7ap+hb-PElIJRGM-T~s5zM(t&=jclw+S0a(WEx%CMai z>J*@Kc9{On8>70|40j++(V&r+FC748EmzuBdwcK6Dhez*JjBMnJF>^oN-;$$o=r{=AC0;9~kI{piQh4)8>AP2c9*tqU zP2cp-vuvP)>bGA4N1@G{uc+rH7<#Sb-H*H>SZc^9Z=UP74;Wwc9KoCvMN)_=&?pDJ z#M8#fyAsFgSD0Hky;kvag3!=<%-6k$T=vX0k^t9wjuk`y9J3G4V-}5hZUJoh-1`Yd z_U%txyx<9ld4}ajYZ%K11azNiawVc;f)+$+vfxJ79NtV)K>2 zB18tHemAfU~uqVDNS@^0Pv&QaYnQ>_MEv0(2~JH)BSlvd8O&JLI+cVLz~?&B24 z>813Nq^%VM+08_@#Dqv1H!%hVp?ZRsUO+npx98H~n_uN%h!Jz^=Pb44qTk*Eg6to- z{Wgz^td^>)?#!7AA)WqM?0E$w!$wtPVVeo!aGc7tuU(wUUi@rI+k@v6MFep^meaI0 zt@tmBxg{S7o$zDjzoJ|BaTY8W@FTQ?`2SSex21bw9u@IhE|o~Oh4=#To{#0wE_6g$ z0I_f~Q_n@V{l)yByf-+C6uwy){i-!3#i>6mefop|>LE%qUz*(Xl~^Kjo!>A9bw)&4 zv{$k1Sq(4Ui6z;JGxq$=qrhNZuE;0g->=FDr*88Z`!i>!3XUE;x|bF4x?O7W)jI`r zT#J9Qa5pemmb>NkJ8|KsA)|2@U$zZszn%&e&ncA;>VRJlxpx{HIKr*>-KsC+gsT)* zK#J5;{_q=!fwAAK{GRwv2(9_lB-*8NM(w#Xf@6vqi&3n)7UgFUmd5-xoELKgBbI>P z#1x9QEbb!R#}Q}_G3+{=9E14qO@{*Mjo@)&X8a_^du{ zI##}>>sA%ESF?#gLM5+CQ6$1S6fVxmROl*Lbgskp4kRJl>gfq=v2X_T!o7qydVH)N zO{rSh2(QQFyRT9;PY*ZUq`6<#8}I$H;Bnj90q+CpCgEA(s&2A;@n=DXVEN&p zRr-PAUz8A(H@w+(VJ&D4A$PO$G)4u(krW)i7TEvWp7`z;F=O0R$kB0b_NcRF0c~ zOq-Om+EQ8;(5PRIT{@k-kJ1e;ZVPR~Q~i{^*z)mJl3daW? z3th6<#kcLw=Sx?lx=bBVtD}p52tX9j6!WfxL`}y9jpm&K$F}VWs&-LJ17-tuCy8RN zDv`HJcIg@OZOz+wrdN_yjgf)#jV_NrW3zQ8|Mg(pc6V*F*+aYdVwq%cW2Neae@72x z)nL*TFNud4ZwW!d%e`Tb0 zV8Lr|Z!WP|GS`vu=@<5nExoo&;~vm^Gabhjgg62Ssq6!8ee-qNP@nXIJC#=rL?Ye3 zXO{l?a8C|(7MvAtdN~hn^;>;6XvT<@S}Xg-&`U+-Pk7X+J$AeK`VKs-Wyp~Y|ITrR z8v=J+`LNhfgnxeb1fsw-13nl~@xcxYpbj@IJ{Zh8Gotx8$21}w;q0@n#W-}C3hyax zsv;{?bB$jOUbR)pX+3(LR%!O24IabUWDRU1w{4?&jEtS|*E28(6)a7>nI!^r-pu|X z(9-8{;T9`$4x51N+vE3f1CEB5i3C;PwUiZ~47`9iO2*L+V$b=+`-WV#r{>n$#CcYN zv^xyiD*B)|2=Ne5D%Ntd@Ky-$kb3;Tb4UA?3|0MOG5-Cjzh7RUiHLN_6OQUWgC=!tMTJ&5oMs4bdLk z3ixo5$>R_v7gGi|F+p3|YS9g!%gyDC0v~8>)yGkCf!RlMWNiZ-I$VQ$i&^zalK!km zN!}Y8uF@_?I}pYqfkKf4EupC&69>Lqr2Vg*x2{6;TKem9|FOaYFHcH?JzYe00u*DC z?>BIr&tr2E?WMxjTNg-v_vHuH1Ky1}#O?tW$NQ5b4oWNqd3wp#Jf#!n=9?%bqD}tohq;Xo-ga^);m2F| zPzU;=al-okB2cTne1H8!aX5Z-t1lQAFIlq;m>aq(gaAK4|F$S1W_dut59_ZV6B~~UQxN>!WWB>c>+UxKtENck?3HpJbbOBIJJX`S zmZTKz0EE^WGXM@PMg|v_P3H2`E}2yid|x<^NAd03Ksz4P|C*kq&H;4YP&?(|A#^UM zlIndTLX1^4{>ujwx72gQ)K@CR4~mJrMo71zH?_TA8I;l~D={Zm$a8d|z4~a16t0uh z_>WZyLU4cx65e-?)9tY``GZZM+lil~1mP+&0nFFEeMP@)0!EbqNT|DOz->F?f-CuV z8EnVdz=iR{v$g7BUbz6k%St&SpuFwmr#-+n17A?`6$vPj7T4}uF4%zTZC$9t>mG2! zRWghaTmb_BgHmiVV!oyW3<3H*0*Dp@Xt1Mwm}OOn=DSnp8COgh^%eD4{(+&R$AV-(8HsNHclR8 zS51Io)u}h(k`%&)rVgxh0sCLr*@7M?xX3b%z1ECAb=2!$BoRS#4=D(!{+yn#b6D$R zrQEOJsV0S!e-cdNE_2NWaUbR(KkXoq9mtjV>1xxH>BC=nx9#8Jp7}> zU3;;xjULi$Q7kF`(Tn44G0>f)PGnpqw9h=1|7mv&k zdZ}*ua5G;Q@UvdGyP6!T*x^3fYm}@LKH@fgYF>EM$Zo3Q*@|bl<;Ht3kxXpp*|c|4-EoK-cIJhnw; z@#?q9e{mj)G_V>r?Qzu>cYg$tKhf~H^B z`0}tO-ub#{m*d_mVJghv z(=&5&Bjf+w5R_hg-(h&JHaexK4F_jeH3#f9FxW73Fw7W|$6VK%t3(=2`76<{4#G5y zxXMk=!cu0~5!Evf`gfl1z3?-B^!xJZwYs6T`b&LLv)sIs$^L}ZaXlF0)8^Z5^9wub z>P`}#e&ipmJ<{CS?b$dRRrTf5fKHgoy(O3r6W4$PJ2q4%-4mdjG#G&4z< zOC?=vp!)Q$N-(&GN32)v#|SobCLJ+&Z-_dUaK#d~x>LKTvu(EstQ|#oXvUQOw8soD zCs{9Ekc8O&2JcnW`tdnxxKw^j#*$nt!H{rH6o0^L4Rph)cd=>5e}y;Y=i-L$2a8DisW_bNw6n7Js(+|J>bh+4$2`*}EtIbQ)49+xO7Fa8=1Cl!(IL znNR2+Zy%Ba<@s^z3FjuyF4Hqw3_rPX5vsSs^FXCRGHdaY{TIHRMhnkKjTqRba;Igi{l7xU0K zO@I-A2~6SmEcb8tXVTPz#l>aGQLi+Ss+IV%+aYPdsY|T9$$eQ(jgLa+FptK=T~U#B8%LjR@@r5|rnK{!Y-#tuRs_>3PAWUX z0YohPPJQF;7ch7E`({#)ppuN*i`yyDOcKThEm;lB~r+xDD2|%;j-`H4KlbF15vh`sw1Y8080VZ&+9kCkWves zcsTI$4;I+`=x7n2%asS9+yZ2)$sY}5$-wO#%z&;EgtZi*r~ioZVfMwZt)qCSqw~wX1rhV>OQP};T&t=90d1lspg#g!>#X^f0PeczOF`hpXsXX{IGE7EkyUP zetV+K*A}uzFD`B*rKF2JpR~l@`c0`GX0Xtk505VAMLp!#Q?z{U%qZXcn82JQGyRCn zG9q9JeBrjuQXPkMWgcF2VmP;)wQ5zW9DD{Z4sA>1I1=zok8R%^zUX2RrU)*ng|4;t zXBX~=Fm1lR9yo|GtspxyTR@?x(hgYM!Gw|@8K#$Cy)Gyk*PTVCZ}@O4Zb(tSKn{#} z2Xu4p<0!s2{viFIep4S{=N>M9c4n9lciIk3dv7+zZ{6Y{{VOT6j30&)O)zar@u!8N zXVFVnPzB}x1i`}_UAu7XiXt%z_-K6)bKSsUD7rltPg7?~GJ;IzTEvcH%wzE{uYoMz zIF{d+rO6QveGHTQWNl6)9}jB0qM*3h0(tBky$)$V0tdh?NaA`j6sLaLgwF9VmX;wN z`7erqT@21ZT#F)G`!8+=rhfj;zL9cp8-*TE1M-kG$6u+28^WW4^sg0@KwSM0FYP?R z*uBu8F@XnRhF>~OE;2>4#}2mKg#KU|DO{Cxto`aoV9$Scy2_`Aj6>N2a|= zh&@MWN!?$z)E(Bus?52QFts$zQpHu@H3S9tgmpN!T+zNB9MfoMWcl~g;~-Eq^eDy2yjZow^s?#Qcw~KoLuu_Zr;X~ek2@I`*Ody>DbyYr#nwaOH^Y) z+vlQkS^h@m0uoHy^U*B}E;#YB^H!iv>TW{Lur%{OjaAgd!pY?kI!sR!av$r>-&$S` z3a&)tF?Ic3a{o38x*|B%QQ6(X54B}{U^poAFgARThqjq{xO#r!eBCZ}=nkIkUf98i z?rU9ma5uFjenKMStp^pywu>D1YT?)-)w?VXVO^e)CUt9w4fEd_@dUnJ>hG;<%3DQB zKJk@Q?UXpfwyP5bCv&*n6`6do41p3EaqVW_X$i2yjY?RAAnbmteMc%PEv`~Z) za<~iHP~S|UZ3-2oBpGHa9eU;^Xw$n;B}kjHLWJsL_s&7&x!dlTz2gJthUr$&cmvt? z1A!QwDhl+_U+r8^Wqa%dY5toHtCtS&jsecCDzSKmqh@}9qE{P zYWKP0mB%M!WEo>*mOjy|lkrRF0@zf~D;8Bgdgd>0M}&umSIs#bElC=Y7U#fh#Da01 z|Gm^Ymm6EtUqlHd?2T#+xk_rk?~E=Zk!wp1uNQH9$1mjgy)43VW2If&x|MhW%RX}4 zH{_djE=0cPo^V%h=IHZSweKnqm2uVbQo)I!GSLKhX0P`EMdsnJqC!_r>MWPmFJI%@ zU<+F_cM&9kBo6BDi+j2BZ*%iC#S5tsVHEv7Ubl7w(wOm9w5vy?kvD#?%q2|#`l~X} zVqdo|ys#4kE}2|0HE@^)D)AlIn5It0kn*>MWpz9@g3e z0<OS9 z8%3TTak z27#u*KO})(9_=c2tZlb8R@ip>$h%aVK#lmF|be@8fEYNh%Yrl=_>r`Wnsn?)6V#&D;O?o}<0kAG+cXbKS9tuQr~X za!cz#oaQmb2?o^%X7i+Js3>cf9e8tuZL(tCZSrSw;{DfZqz6k&Rb1K3Ep|fEE~1%t zG6g0Q>8tJ?JclH7H&n`!xKmFGU6@66OZOD#c+o?=q%+O7^;o?nz1|K9`zelNIl5>! zp8xpJg*lCyH?EhV*?+r_>s-7(7ZyGHUJME?wPq>)o!mb?c@ZU*48d^Vx)vf{cbIk= z!vnmMmkjE`yutEm0GDgLTp>)P*(>_t2p#P=;)Zj!-Ii!nJaJ-Q2EN?@+Ixs?n_qF$lyuf6eL*Tc<_pKe=$D_S-YIs( zc%P|dR)UK`T?!`}a(7O}+%K$?TYKU5O0g0q6x-Oz+5ZsOZDaiyy8j`Laq0G@PeJ-O z?MNh){o^;a@qMr~r$YLlT#EGK19%r{n$Q5jkn6XmBm(P2>W#OOq-Gi7Dk>IV@YbsYH@{d%qZ4CQRkca+2l4rLaD8B+ame%edaCz>h$Hb0p>2HX+o% zidrJsw+@J}O`_Y)i@Cn-*~-UyjDLSnT*p#uh)SHeIH&vrFa0_+cQlqL8dS7->C}39akO-i0~UIn*c$rkz3%n|);VV+ z66q%^weobLR>|79Pr#ZCi-p?j+$O$OQi`g;Q@+f1PjmL|-akD2U~MOj^FYQQyjTil~3Y2fEH%v`^kRt;Da_hb5X~ z=U(~MGpl$+@{w9U!@MTI1vl`H$!uCi!TBHJ}#z8fm;zJi{iB(VNTH;M1CxVu~G$o48MKHt3jQU^9t zgh_EWSeJ2RI076e5urfcqI1=|z;R?Yh1$ej5NmlI1LOJ*SsH=Hd{~ARq<;vEC(s{W z@xMDp&o9qAZ9<<}xiflo=-8CfBEBDc?PjF!R6?!JGpByB)=6Q!*yu4xyS+h^-{N+Jb(Z^4qt=^e9p6S#-;^G4JgJEiyM?WlI%d|BmkJ;&PiHur+94fCi0x0vo?`0RL#binQy>G_#_MtjM`+OOXI-_sOu zcje{>&CWj=bb(s^R)=S8^U!=_wW$u8+x9&+(-V2%Q&x9e;0;TLvhtSBTqFK@zTl-MQ@KGB_phVRWM%`b>Oq;ZFTA=;rK)QTX=cUQT#~o%@iDYiXH3) zjlpM7wX1VsbDKA*>*?Ovxt*}-}zL~vs zhe<$r&6&^@voZt+9ZrfWGx5aq4Z+`LU#kB5vS2t&|k?(a+q`f%2fa%KQyy>O;Qnd*}MCDNi?5)Q<4svtF@A8;Uw3kl4*~p&<@`k zT8=pkoif(W7ku7#ozF%Ej1H{ZF^8j(-KbOVbyn~BqaoiL{$d{WyNKuyDu~TWNx(7+ z!{U4Xz1_dwi{URG?4K6Pcb&E9iCRb0Dvdt}?a%7Z$AfU7Sb)9l5YOfj4Z?B9MmN^w zn*m8=m-mBM+4^W$#4}v#!d@KW+X*O20y7`k+*B^YiXnj#QyxC?96-XiEss z$bA~RH2N+rEN1ZQ{J+7wnLBUqE0Gu{G`4CtzLV-^5R%`m6C0Qn*u=-&Ud;yD^1&`&_jYa2q-DO7D%?aH#M?=`^lHMiI8*;sWLDCdSNou5*mNhe;!aS; zpzN*K&>h7!Ljk`^1E>-bM8Gb6_?@0JdXSeO0UnXEE*w7mvzJe9Jv?Kueh^~dG{@kG z@r*h)A59zgV6~PuzCP-ruFRRhW%{iF1j6KQR|^iQ%qc#Ho*3$Z3fw+A^*6h9ueOue zYm=9C@w{$WP3xPToPZ@-(G%5?ueMPkrowv|Y=Or=n%;GVBDEUEy3`o$cQYQ(|lYbWTBpn{xSdfU|_bni|Wt84*>rjqUC@8UP+=-*Ft0rdveMMaQU1 zlx#ZHTYo|nt|8#4r!*%~L6a)|^N^qaYI_n>WYU87GMCP`Ql6Fmn z{AykG0m~Ht>hH*xyv_U-Cjq$0z}-sd4D4u1P``rY^JC0aY5jH91OU7igr)6?dVFF@ zJn4ICUW$1{fO_?;IW@Hdc!(n%FsFr5NXLq)IA)B*l(7y3OQZfePC2eQBB1vdnvy+& zw|v%7E(oKWfw*YL-l_M)ZxOdo0`2&Otpr$ct`3XY0iZ!*6da_)P6bm6%EI-Hkl%$Y zb@+O^67)8D*}``=^#caKMGzDwPf7ZVNtQq5{`VVJmg8VaI-~)U2x|YA2FkEy85bhJ z$)bY*OZKG0MdcNRTm4~4I{*7b>OpQe7&(rYmxYJp|C^Y!2cBXB2xVCAnbPM!1q6S? zgZyFWPpm8M)(0?zfQlYjJ}mGCLS${%q={*Klm<*USrX3-JT*g(erozLqyU>1V0JHN zs@s(M7w)y$4}uSI?{ha1fHDFlI1=FLMYLadA07exs=PJ3;M|qkxY9=qBiJ}VYipK& zuyS2=3y_HjU0M7-H3F=Gn?05|*f>fB+&htgkV8{4eZo*Ccx|Z(Vq5Ie&c| z6zi7@@%*2LlJLN!3TgQw5>TRm;(^SkU1dBd8zLAvfuBWQiEIKuyLowYErhMY@o)

RpcMz)%$uM4rLoL`Z6O>#hyp!} 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

RpcMz)%$uM4rLoL`Z6O>#hyp!} zk~?Jo7l$6cpqVNOSHaTX#0(6OBq)I)ho<)5NdQcqW4X*uSLW-Y08%)zKy8wTwcTgc zaldh6DNk1$yFk6#OS-=_=iq9W&}%7NiwmjbAj~lRFv#RzCBGqTCGL>5+xL%*U!SXBiPb|1Gjec@*Hqf3Sg2| z+YNTQ168O%HsP@j<3$9vTL~g9VgaR)aLH}=^szzBDR{jEArD_9Xe5}zX=P!?xm@_g zS%}q=H~=OtVV4%l5`%LbIY(<~*S!GH$62Pv3y_#N4h57cn3H13s!4*&dVJENHNb`X*<9Yb`8EIUK3#oAp(-IPY^Eb}{ zPrvjBKv_}v*Wy$*2CLhGv&p3#xsoLW0hPE)*gRAk2j3IM1ueaXWN2XV+_9CU#(DU* zJx9mjsySW+w%oBPCqB(3Bv5;;C;;$F;g7<;xGb751?U!B_gi^9-u4X23uw6t`}7M8 z!&<@~Rs!siOJ#~dLm>DDwMCctZkpjqsDdHaJ^jm^zndrxfG?xMP8u|jp*;I+0Z!-j zOg`Y=R+wf2h=Eqbjj({U!O)t0eK$KFWQ7PVo-m$3D6pq6S|BpcB(C$1k3ORTM=6_*;;MNxS6G`? s;XgsX@9Cd?db;7Task->" + }, + "referencingRules": { + "compatibleTypes": "->Task Server App->" + }, + "childrenNodesProperties": [], + "propertyNameAtParent": "taskServerAppReference" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/task-server-app.json b/Projects/Governance/Schemas/App-Schema/task-server-app.json new file mode 100644 index 000000000..e009fd499 --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/task-server-app.json @@ -0,0 +1,44 @@ +{ + "type": "Task Server App", + "menuItems": [ + { + "action": "Configure", + "actionProject": "Foundations", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration", + "dontShowAtFullscreen": true, + "actionFunction": "uiObject.configEditor.activate" + }, + { + "action": "Delete UI Object", + "actionProject": "Visual-Scripting", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{ \n\"codeName\": \"\"\n}" + }, + "addLeftIcons": true, + "level": 1, + "attachingRules": { + "compatibleTypes": "->Server Apps->" + }, + "childrenNodesProperties": [ + { + "name": "signingAccount", + "type": "node", + "childType": "Signing Account", + "autoAdd": false + } + ], + "propertyNameAtParent": "taskServerApps" +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js index bc92d6b46..106575b8e 100644 --- a/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js +++ b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js @@ -217,6 +217,7 @@ function newGovernanceFunctionLibraryProfileConstructor() { let socialTradingDesktopApp = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.userApps, 'Social Trading Desktop App') let socialTradingMobileApp = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.userApps, 'Social Trading Mobile App') let socialTradingServerApp = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.userApps, 'Social Trading Server App') + let taskServerApp = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.userApps, 'Task Server App') let socialTradingBots = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.userBots, 'Social Trading Bot') let socialPersonas = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.socialPersonas, 'Social Persona') let p2pNetworkNodes = UI.projects.visualScripting.utilities.branches.nodeBranchToArray(userProfile.p2pNetworkNodes, 'P2P Network Node') @@ -225,6 +226,7 @@ function newGovernanceFunctionLibraryProfileConstructor() { addSigningAccounts(socialTradingDesktopApp, 'Social Trading Desktop App') addSigningAccounts(socialTradingMobileApp, 'Social Trading Mobile App') addSigningAccounts(socialTradingServerApp, 'Social Trading Server App') + addSigningAccounts(taskServerApp, 'Task Server App') addSigningAccounts(socialTradingBots, 'Social Trading Bot') addSigningAccounts(socialPersonas, 'Social Persona') addSigningAccounts(p2pNetworkNodes, 'P2P Network Node') diff --git a/Projects/Network/SA/Modules/UserProfiles.js b/Projects/Network/SA/Modules/UserProfiles.js index ee068b497..5dcb1d1ba 100644 --- a/Projects/Network/SA/Modules/UserProfiles.js +++ b/Projects/Network/SA/Modules/UserProfiles.js @@ -102,6 +102,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles() let socialTradingDesktopApp = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.userApps, 'Social Trading Desktop App') let socialTradingMobileApp = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.userApps, 'Social Trading Mobile App') let socialTradingServerApp = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.userApps, 'Social Trading Server App') + let taskServerApp = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.userApps, 'Task Server App') let socialTradingBots = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.userBots, 'Social Trading Bot') let socialPersonas = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.socialPersonas, 'Social Persona') let p2pNetworkNodes = SA.projects.visualScripting.utilities.nodeFunctions.nodeBranchToArray(userProfilePlugin.p2pNetworkNodes, 'P2P Network Node') @@ -110,6 +111,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles() checkNwetworkClients(socialTradingDesktopApp) checkNwetworkClients(socialTradingMobileApp) checkNwetworkClients(socialTradingServerApp) + checkNwetworkClients(taskServerApp) checkNwetworkClients(socialTradingBots) checkNwetworkClients(socialPersonas) checkNwetworkClients(p2pNetworkNodes) From 524c9ec28aeadc871f0339deb8f8b98ebb332ecb Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 27 Nov 2021 20:10:35 +0100 Subject: [PATCH 3/3] Task Server connecting itself to the p2p Network --- Environment.js | 1 + .../Foundations/TS/Globals/TaskConstants.js | 1 + .../UI/Function-Libraries/TaskFunctions.js | 2 +- TaskServer/TaskServer.js | 105 ++++++++++++------ TaskServerRoot.js | 11 ++ 5 files changed, 88 insertions(+), 32 deletions(-) diff --git a/Environment.js b/Environment.js index 544f5ffa1..6909eb088 100644 --- a/Environment.js +++ b/Environment.js @@ -32,6 +32,7 @@ exports.newEnvironment = function () { PATH_TO_FONTS: path.join(basePath, './Platform/WebServer/Fonts'), DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1', DESKTOP_APP_MAX_OUTGOING_PEERS: 1, + TASK_SERVER_APP_MAX_OUTGOING_PEERS: 1, MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1', SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1', PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1', diff --git a/Projects/Foundations/TS/Globals/TaskConstants.js b/Projects/Foundations/TS/Globals/TaskConstants.js index a3c8e5cc9..68b8ef837 100644 --- a/Projects/Foundations/TS/Globals/TaskConstants.js +++ b/Projects/Foundations/TS/Globals/TaskConstants.js @@ -9,6 +9,7 @@ exports.newFoundationsGlobalsTaskConstants = function () { PROJECT_DEFINITION_NODE: undefined, PROJECTS_SCHEMA: undefined, EVENT_SERVER_CLIENT_MODULE_OBJECT: undefined, // This is an instance of the Event Server Client pointing to the localhost server + P2P_NETWORK: undefined, TASK_HEARTBEAT_INTERVAL_HANDLER: undefined } diff --git a/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js b/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js index 8cc0a6c3d..6085e9d2e 100644 --- a/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js +++ b/Projects/Foundations/UI/Function-Libraries/TaskFunctions.js @@ -116,7 +116,7 @@ function newFoundationsFunctionLibraryTaskFunctions() { } let taskLightingPath = '->Task->' + - 'Task Server App Reference->Signing Account->' + 'Task Server App Reference->Task Server App->Signing Account->' + 'Sensor Bot Instance->' + 'API Data Fetcher Bot Instance->' + 'Indicator Bot Instance->' + diff --git a/TaskServer/TaskServer.js b/TaskServer/TaskServer.js index 463058c99..d690a33ef 100644 --- a/TaskServer/TaskServer.js +++ b/TaskServer/TaskServer.js @@ -82,10 +82,12 @@ exports.newTaskServer = function newTaskServer() { } } - function bootingProcess() { + async function bootingProcess() { try { initializeProjectDefinitionNode() + await setupNetwork() setupTaskHeartbeats() + startProcesses() function initializeProjectDefinitionNode() { TS.projects.foundations.globals.taskConstants.PROJECT_DEFINITION_NODE = SA.projects.visualScripting.utilities.nodeFunctions.findNodeInNodeMesh(TS.projects.foundations.globals.taskConstants.TASK_NODE, 'Project Definition') @@ -109,6 +111,45 @@ exports.newTaskServer = function newTaskServer() { } } + async function setupNetwork() { + /* + If we received a App Server Reference Node and a Signing Account, then we will connect to the P2P Network + */ + if ( + TS.projects.foundations.globals.taskConstants.TASK_NODE.taskServerAppReference === undefined || + TS.projects.foundations.globals.taskConstants.TASK_NODE.taskServerAppReference.referenceParent === undefined || + TS.projects.foundations.globals.taskConstants.TASK_NODE.taskServerAppReference.referenceParent.signingAccount === undefined + ) { + return + } + TS.projects.foundations.globals.taskConstants.P2P_NETWORK = {} + /* + We set up ourselves as a Network Client. + */ + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkClient = SA.projects.network.modules.p2pNetworkClient.newNetworkModulesP2PNetworkClient() + await TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkClient.initialize() + /* + We will read all user profiles plugins and get from there our network identity. + */ + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles() + await TS.projects.foundations.globals.taskConstants.P2P_NETWORK.userProfiles.initialize(TS.projects.foundations.globals.taskConstants.TASK_NODE.taskServerAppReference.referenceParent.config.codeName, TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkClient) + /* + We set up the P2P Network. + */ + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork() + await TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetwork.initialize('Network Client') + /* + Set up the connections to network nodes. + */ + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers() + await TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkPeers.initialize( + 'Network Client', + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetworkClient, + TS.projects.foundations.globals.taskConstants.P2P_NETWORK.p2pNetwork, + global.env.TASK_SERVER_APP_MAX_OUTGOING_PEERS + ) + } + function setupTaskHeartbeats() { /* Heartbeat sent to the UI @@ -129,42 +170,44 @@ exports.newTaskServer = function newTaskServer() { } } - for (let processIndex = 0; processIndex < TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes.length; processIndex++) { - /* - Here we will validate that the process is connected all the way to a Mine - and that nodes in the middle have whatever config is mandatory. - */ - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Instance without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); - continue - } + function startProcesses() { + for (let processIndex = 0; processIndex < TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes.length; processIndex++) { + /* + Here we will validate that the process is connected all the way to a Mine + and that nodes in the middle have whatever config is mandatory. + */ + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Instance without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex])); + continue + } - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Definition without parent Bot Definition. -> Process Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent)); - continue - } + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Definition without parent Bot Definition. -> Process Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent)); + continue + } - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Bot Definition without parent Mine. -> Bot Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode)); - continue - } + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Bot Definition without parent Mine. -> Bot Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode)); + continue + } - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Definition without a codeName defined. -> Process Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent)); - continue - } + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.config.codeName === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Process Definition without a codeName defined. -> Process Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent)); + continue + } - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Bot Definition without a codeName defined. -> Bot Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode)); - continue - } + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.config.codeName === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Bot Definition without a codeName defined. -> Bot Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode)); + continue + } - if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName === undefined) { - console.log("[ERROR] Task Server -> Task -> bootingProcess -> Mine without a codeName defined. -> Mine Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode)); - continue - } + if (TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName === undefined) { + console.log("[ERROR] Task Server -> Task -> bootingProcess -> Mine without a codeName defined. -> Mine Definition = " + JSON.stringify(TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode)); + continue + } - startProcessInstance(processIndex); + startProcessInstance(processIndex); + } } } catch (err) { console.log('[ERROR] Task Server -> Task -> bootingProcess -> Fatal Error. Can not run this task. -> ' + err.stack) diff --git a/TaskServerRoot.js b/TaskServerRoot.js index d45d37f38..0be6ec1e1 100644 --- a/TaskServerRoot.js +++ b/TaskServerRoot.js @@ -55,6 +55,17 @@ SA.nodeModules = { lookpath: require('lookpath'), twitter: require('twitter') } +/* +Setting up Secrets. +*/ +SA.secrets = { + array: require('./My-Secrets/Secrets.json').secrets, + map: new Map() +} +for (let i = 0; i < SA.secrets.array.length; i++) { + let secret = SA.secrets.array[i] + SA.secrets.map.set(secret.nodeCodeName, secret) +} run()