/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 - 2 0 2 1 ĠSimon ĠZ i gel li Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . github . zi ge ll sn . webhook k Ċ Ċ import Ġio . ktor . http .* Ċ import Ġkotlinx . coroutines . Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġkotlinx . serialization . K Serializer Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . decode FromString Ċ import Ġkotlinx . serialization . descriptors . Primitive Kind Ċ import Ġkotlinx . serialization . descriptors . Primitive Serial Descriptor Ċ import Ġkotlinx . serialization . descriptors . Serial Descriptor Ċ import Ġkotlinx . serialization . encode ToString Ċ import Ġkotlinx . serialization . encoding . Decoder Ċ import Ġkotlinx . serialization . encoding . Encoder Ċ import Ġkotlinx . serialization . json . Json Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path ĊĊ Ċ /** Ċ Ġ* ĠAdds Ġa Ġcollection Ġof ĠURIs Ġto Ġa Ġwebhook Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopic ĠName Ġof Ġthe Ġwebhook Ċ Ġ* Ġ@ param Ġurls ĠCollection Ġof ĠURIs Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . addAll ( topic : ĠString , Ġurls : ĠCollection < Url >) Ġ{ ĊĠĠĠ Ġif Ġ(! this . containsKey ( topic )) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis [ topic ] Ġ= Ġurls . to Mutable List () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġthis [ topic ]?. addAll ( urls ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠAdds Ġa ĠURI Ġto Ġa Ġwebhook Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopic ĠName Ġof Ġthe Ġwebhook Ċ Ġ* Ġ@ param Ġurl ĠURI Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . add ( topic : ĠString , Ġurl : ĠUrl ) Ġ{ ĊĠĠĠ Ġif Ġ(! this . containsKey ( topic )) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis [ topic ] Ġ= Ġmutable ListOf ( url ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(!( this [ topic ]?. contains ( url ) Ġ?: Ġreturn )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis [ topic ]?. add ( url ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRemoves Ġa ĠURI Ġfrom Ġa Ġwebhook Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopic ĠName Ġof Ġthe Ġwebhook Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . remove Url ( topic : ĠString , Ġurl : ĠUrl ) Ġ{ ĊĠĠĠ Ġif Ġ( this . containsKey ( topic )) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis [ topic ]?. remove ( url ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError () ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRemoves Ġa Ġcollection Ġof ĠURIs Ġfrom Ġa Ġwebhook Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopic ĠName Ġof Ġthe Ġwebhook Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . removeAll Url ( topic : ĠString , Ġurls : ĠCollection < Url >) Ġ{ ĊĠĠĠ Ġif Ġ( this . containsKey ( topic )) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis [ topic ]?. removeAll ( urls ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠAssertionError () ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRemoves Ġa Ġwebhook Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopic ĠName Ġof Ġthe Ġwebhook Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . remove Topic ( topic : ĠString ) Ġ{ ĊĠĠĠ Ġthis . remove ( topic ) Ċ } Ċ Ċ /** Ċ Ġ* ĠRemoves Ġa Ġcollection Ġof Ġweb hooks Ċ Ġ* Ċ Ġ* Ġ@ param Ġtopics ĠCollection Ġof Ġweb hooks Ċ Ġ*/ Ċ public Ġfun ĠMutable Map < String , ĠMutable List < Url >> . removeAll Topic ( topics : ĠCollection < String >) Ġ{ ĊĠĠĠ Ġfor Ġ( topic Ġin Ġtopics ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . remove ( topic ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠInterface Ġfor ĠData Access Ċ Ġ*/ Ċ public Ġinterface ĠData Access Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCollection Ġof ĠWeb hooks ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġval Ġweb hooks : ĠMutable Map < String , ĠMutable List < Url >> ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPers ist ĠWeb hooks Ġif Ġpossible ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġpublic Ġsuspend Ġfun Ġpersist () Ċ } Ċ Ċ /** Ċ Ġ* Ġ' Memory DataAccess ' Ġstores Ġall Ġwebhook Ġdata Ġin Ġmemory Ċ Ġ*/ Ċ public Ġclass ĠMemory DataAccess Ġ: ĠData Access Ġ{ ĊĠĠĠ Ġoverride Ġval Ġweb hooks : ĠMutable Map < String , ĠMutable List < Url >> Ġ= Ġmutable Map Of () ĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġpersist () Ġ{} Ċ } Ċ Ċ private Ġobject ĠUrl AsString Serializer Ġ: ĠK Serializer < Url > Ġ{ ĊĠĠĠ Ġoverride Ġval Ġdescriptor : ĠSerial Descriptor Ġ= ĊĠĠĠĠĠĠĠ ĠPrimitive Serial Descriptor (" Url ", ĠPrimitive Kind . STRING ) ĊĊĠĠĠ Ġoverride Ġfun Ġserialize ( encoder : ĠEncoder , Ġvalue : ĠUrl ) Ġ= ĊĠĠĠĠĠĠĠ Ġencoder . encode String ( value . toString ()) ĊĊĠĠĠ Ġoverride Ġfun Ġdeserialize ( decoder : ĠDecoder ): ĠUrl Ġ= ĊĠĠĠĠĠĠĠ ĠUrl ( decoder . decode String ()) Ċ } Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠDB ( val Ġtopics : ĠMutable Map < String , ĠMutable List < @ Serializable ( with Ġ= ĠUrl AsString Serializer :: class ) ĠUrl >>) Ċ Ċ /** Ċ Ġ* Ġ' File DataAccess ' Ġstores Ġall Ġwebhook Ġdata Ġin Ġa Ġfile Ċ Ġ*/ Ċ public Ġclass ĠFile DataAccess ( private Ġval Ġfile : ĠPath , Ġprivate Ġval Ġio Dispatcher : ĠCor outine Dispatcher Ġ= ĠDispatch ers . IO ) Ġ: ĊĠĠĠ ĠData Access Ġ{ ĊĊĠĠĠ Ġpublic Ġoverride Ġval Ġweb hooks : ĠMutable Map < String , ĠMutable List < Url >> Ġ= Ġif Ġ( Files . exists ( file )) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= ĠFiles . new BufferedReader ( file ). read Text () ĊĠĠĠĠĠĠĠ ĠJson . decode FromString < DB >( bytes ). topics ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġmutable Map Of () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġpersist (): ĠUnit Ġ= Ġwith Context ( io Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjson Ġ= ĠJson . encode ToString ( DB ( web hooks )) ĊĠĠĠĠĠĠĠ Ġlaunch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . write ( file , Ġjson . toByteArray ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }