/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 7 ĠVS CT Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* Ġ ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* Ġ ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġfr . vs ct . to ck . bot . engine Ċ Ċ import Ġfr . vs ct . to ck . bot . admin . bot . Bot ApplicationConfiguration Ċ import Ġfr . vs ct . to ck . bot . admin . bot . Bot ApplicationConfiguration DAO Ċ import Ġfr . vs ct . to ck . bot . connector . Connector Ċ import Ġfr . vs ct . to ck . bot . connector . Connector Configuration Ċ import Ġfr . vs ct . to ck . bot . connector . Connector Provider Ċ import Ġfr . vs ct . to ck . bot . connector . Connector Type Ċ import Ġfr . vs ct . to ck . bot . definition . Bot Answer Interceptor Ċ import Ġfr . vs ct . to ck . bot . definition . Bot Definition Ċ import Ġfr . vs ct . to ck . bot . definition . Bot Provider Ċ import Ġfr . vs ct . to ck . bot . definition . Story Handler Listener Ċ import Ġfr . vs ct . to ck . bot . engine . config . Story Configuration Monitor Ċ import Ġfr . vs ct . to ck . bot . engine . monitoring . Request Timer Ċ import Ġfr . vs ct . to ck . bot . engine . nlp . BuiltIn Keyword Listener Ċ import Ġfr . vs ct . to ck . bot . engine . nlp . N lp Listener Ċ import Ġfr . vs ct . to ck . nlp . api . client . N lp Client Ċ import Ġfr . vs ct . to ck . shared . Executor Ċ import Ġfr . vs ct . to ck . shared . default Locale Ċ import Ġfr . vs ct . to ck . shared . error Ċ import Ġfr . vs ct . to ck . shared . injector Ċ import Ġfr . vs ct . to ck . shared . provide Ċ import Ġfr . vs ct . to ck . shared . vertx . vertx Ċ import Ġio . vertx . ext . web . Router Ċ import Ġio . vertx . ext . web . Routing Context Ċ import Ġmu . Kotlin Logging Ċ import Ġjava . util . Service Loader Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . Copy On Write Array Set Ċ Ċ /** Ċ Ġ* ĠAdvanced Ġbot Ġconfiguration . Ċ Ġ* Ċ Ġ* Ġ[ fr . vs ct . to ck . bot . register And Install Bot ] Ġmethod Ġis Ġthe Ġpreferred Ġway Ġto Ġstart Ġa Ġbot Ġin Ġmost Ġuse Ġcases . Ċ Ġ*/ Ċ object ĠBot Repository Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} ĊĊĠĠĠ Ġprivate Ġval Ġbot Configuration DAO : ĠBot ApplicationConfiguration DAO Ġget () Ġ= Ġinjector . provide () ĊĠĠĠ Ġinternal Ġval Ġbot Providers : ĠMutable Set < Bot Provider > Ġ= Ġmutable Set Of () ĊĠĠĠ Ġinternal Ġval Ġstory Handler Listeners : ĠMutable List < Story Handler Listener > Ġ= Ġmutable ListOf () ĊĠĠĠ Ġinternal Ġval Ġn lp Listeners : ĠMutable List < N lp Listener > Ġ= Ġmutable ListOf ( BuiltIn Keyword Listener ) ĊĠĠĠ Ġprivate Ġval Ġn lp Client : ĠN lp Client Ġget () Ġ= Ġinjector . provide () ĊĠĠĠ Ġprivate Ġval Ġexecutor : ĠExecutor Ġget () Ġ= Ġinjector . provide () ĊĠĠĠ Ġinternal Ġval Ġbot Answer Intercept ors : ĠMutable List < Bot Answer Interceptor > Ġ= Ġmutable ListOf () ĊĊĠĠĠ Ġinternal Ġval Ġconnector Providers : ĠMutable Set < Connector Provider > Ġ= ĠCopy On Write Array Set ( ĊĠĠĠĠĠĠĠ ĠService Loader . load ( Connector Provider :: class . java ). map Ġ{ Ġit Ġ}. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠforEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" Connector Ġ${ it . connector Type } Ġloaded " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġval Ġconnector Controller Map : ĠMutable Map < Bot ApplicationConfiguration , ĠConnector Controller > Ġ= ĊĠĠĠĠĠĠĠ ĠConcurrent HashMap () ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequest Ġtimer Ġfor Ġconnector s . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġvar Ġrequest Timer : ĠRequest Timer Ġ= Ġobject Ġ: ĠRequest Timer Ġ{} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġhealth check Ġhandler Ġto Ġanswer Ġto ĠGET Ġ/ health check . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Volatile ĊĠĠĠ Ġvar Ġhealth check Handler : Ġ( Routing Context ) Ġ-> ĠUnit Ġ= Ġ{ ĊĠĠĠĠĠĠĠ Ġexecutor . execute Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . response (). set StatusCode ( if Ġ( nlp Client . health check ()) Ġ 2 0 0 Ġelse Ġ 5 0 0 ). end () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġvert icle Ġby Ġlazy Ġ{ ĠBot Vert icle () Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegisters Ġa Ġnew Ġ[ Connector Provider ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġfun Ġregister Connector Provider ( connector Provider : ĠConnector Provider ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconnector Providers . add ( connector Provider ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegisters Ġa Ġnew Ġ[ Bot Provider ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Bot Provider ( bot : ĠBot Provider ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbot Providers . add ( bot ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegisters Ġa Ġnew Ġ[ Story Handler Listener ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Story Handler Listener ( listener : ĠStory Handler Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstory Handler Listeners . add ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegisters Ġa Ġnew Ġ[ Bot Answer Interceptor ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister Bot Answer Interceptor ( bot Answer Interceptor Ġ: Bot Answer Interceptor ){ ĊĠĠĠĠĠĠĠ Ġbot Answer Intercept ors . add ( bot Answer Interceptor ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRegisters Ġan Ġnew Ġ[ N lp Listener ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġregister N lp Listener ( listener : ĠN lp Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġn lp Listeners . add ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġcurrent Ġ[ Connector Controller ] Ġfor Ġa Ġgiven Ġpredicate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Controller ( predicate : Ġ( Bot ApplicationConfiguration ) Ġ-> ĠBoolean ): ĠConnector Controller ? Ġ= ĊĠĠĠĠĠĠĠ Ġconnector Controller Map ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. keys ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull ( predicate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnector Controller Map [ it ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInstall s Ġthe Ġbot ( s ). ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġrouter Handlers Ġthe Ġadditional Ġrouter Ġhandlers ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġinstall Bot s ( router Handlers : ĠList <( Router ) Ġ-> ĠUnit >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbots Ġ= Ġbot Providers . map Ġ{ Ġit . bot Definition () Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// check Ġthat Ġn lp Ġapplications Ġexist ĊĠĠĠĠĠĠĠ Ġbots . distinct By Ġ{ Ġit . namespace Ġto Ġit . nlp ModelName Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġbot Definition Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn lp Client . create Application ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbot Definition . namespace , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbot Definition . nlp ModelName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Locale ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" nlp Ġapplication Ġinitialized Ġ$ namespace Ġ$ name Ġwith Ġlocale Ġ$ supported Locales " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// load Ġconfigurations ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Bot Configurations ( true ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// register Ġservices ĊĠĠĠĠĠĠĠ Ġrouter Handlers . forEach Indexed Ġ{ Ġindex , Ġhandler Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvert icle . register Services ("_ handler _$ index ", Ġhandler ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// deploy Ġvert icle ĊĠĠĠĠĠĠĠ Ġvert x . deploy Vert icle ( vert icle ) ĊĊĠĠĠĠĠĠĠ Ġ// listen Ġfuture Ġchanges ĊĠĠĠĠĠĠĠ Ġbot Configuration DAO . listen Changes Ġ{ Ġexecutor . execute Blocking Ġ{ Ġcheck Bot Configurations () Ġ} Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġthe Ġ[ Connector Provider ] Ġfor Ġthe Ġspecified Ġ[ Connector Type ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġfind Connector Provider ( connector Type : ĠConnector Type ): ĠConnector Provider Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġconnector Providers . first Ġ{ Ġit . connector Type Ġ== Ġconnector Type Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Bot Configurations ( startup : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . trace Ġ{ Ġ" check Ġconfigurations " Ġ} ĊĠĠĠĠĠĠĠ Ġ// clone Ġconf Ġlist Ġas Ġwe Ġmay Ġupdate Ġconnector Controller Map ĊĠĠĠĠĠĠĠ Ġval Ġexisting Con fs Ġ= ĠArrayList ( connector Controller Map . keys ) ĊĠĠĠĠĠĠĠ Ġval Ġcon fs Ġ= Ġbot Configuration DAO . get Configurations () ĊĊĠĠĠĠĠĠĠ Ġcon fs . forEach Ġ{ Ġc Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( existing Con fs . none Ġ{ Ġc . equals Without Id ( it ) Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbot Definition Ġ= Ġbot Providers . find Ġ{ Ġit . bot Id () Ġ== Ġc . bot Id Ġ} ?. bot Definition () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bot Definition Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" refresh Ġconfiguration Ġ$ c " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Configuration Ġ= Ġexisting Con fs . find Ġ{ Ġit ._ id Ġ== Ġc ._ id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnector Ġ= Ġfind Connector Provider ( c . connector Type ). connector ( Connector Configuration ( c )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Bot ( bot Definition , Ġconnector , Ġc ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old Configuration Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Bot ( old Configuration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . trace Ġ{ Ġ" unknown Ġbot Ġ${ c . bot Id } Ġ- Ġinstallation Ġskipped " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// remove Ġold Ġcon fs ĊĠĠĠĠĠĠĠ Ġconnector Controller Map . keys . forEach Ġ{ Ġconf Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( con fs . none Ġ{ Ġit ._ id Ġ== Ġconf ._ id Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Bot ( conf ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! startup ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// register Ġnew Ġcon fs ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvert icle . configure () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Bot ( ĊĠĠĠĠĠĠĠ Ġbot Definition : ĠBot Definition , ĊĠĠĠĠĠĠĠ Ġconnector : ĠConnector , ĊĠĠĠĠĠĠĠ Ġconf : ĠBot ApplicationConfiguration ĊĠĠĠ Ġ): ĠBot ApplicationConfiguration Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġbot Ġ= ĠBot ( bot Definition , Ġconf ) ĊĠĠĠĠĠĠĠ Ġreturn Ġbot Configuration DAO . save ( conf ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontroller Ġ= ĠT ock Connector Controller . register ( connector , Ġbot , Ġvert icle ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// monitor Ġbot ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStory Configuration Monitor . monitor ( bot ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// register Ġconnector Ġcontroller Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnector Controller Map [ this ] Ġ= Ġcontroller ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġremove Bot ( conf : ĠBot ApplicationConfiguration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" uninstall Ġ$ conf " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcontroller Ġ= Ġconnector Controller Map . remove ( conf ) ĊĠĠĠĠĠĠĠ Ġif Ġ( controller Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller . unregister Services () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( controller Ġis ĠT ock Connector Controller ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠStory Configuration Monitor . un monitor ( controller . bot ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ }