package Ġio . ze ko . rest api . core . mail Ċ Ċ import Ġio . vertx . circuit break er . Circuit Breaker Ċ import Ġio . vertx . circuit break er . Circuit Breaker Options Ċ import Ġio . vertx . core . Vert x Ċ import Ġio . vertx . core . json . JsonObject Ċ import Ġorg . slf 4 j . Logger Ċ import Ġio . vertx . ext . web . client . Web Client Ċ import Ġio . vertx . ext . web . client . Web Client Options Ċ import Ġio . vertx . kotlin . coroutines . await Ċ import Ġio . ze ko . rest api . core . Circuit Breaker Builder Ċ import Ġio . ze ko . rest api . core . utilities . execute Suspend Await Ċ import Ġkotlinx . coroutines .* Ċ import Ġjava . lang . Exception Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ class ĠM and r ill Mail ( ĊĠĠĠ Ġval Ġweb Client : ĠWeb Client , ĊĠĠĠ Ġval Ġconfig : ĠMail Config , ĊĠĠĠ Ġval Ġlogger : ĠLogger , ĊĠĠĠ Ġval Ġsend Endpoint : ĠString Ġ= Ġ"/ api / 1 . 0 / messages / send . json " Ċ ) Ġ: ĠMail Service Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġcreate Shared Client ( vertx : ĠVert x , Ġoptions : ĠWeb Client Options ? Ġ= Ġnull ): ĠWeb Client Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( options Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠWeb Client . create ( vertx , Ġoptions ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠWeb Client . create ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvert x , ĠWeb Client Options () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setMax PoolSize ( 1 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setDefault Host (" mand r ill app . com ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Ssl ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setDefault Port ( 4 4 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Idle Timeout ( 1 5 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Idle Timeout Unit ( TimeUnit . MILLISECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Connect Timeout ( 3 0 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Log Activity ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġcreate Circuit Breaker ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvert x : ĠVert x , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname : ĠString Ġ= Ġ" ze ko . mail . mand r ill ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoptions : ĠCircuit Breaker Options ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ): ĠCircuit Breaker Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCircuit Breaker Builder . make ( vertx , Ġname , Ġoptions ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend ( ĊĠĠĠĠĠĠĠ Ġto Email : ĠString , ĊĠĠĠĠĠĠĠ Ġname : ĠString , ĊĠĠĠĠĠĠĠ Ġsubject : ĠString , ĊĠĠĠĠĠĠĠ Ġhtml : ĠString , ĊĠĠĠĠĠĠĠ Ġtext : ĠString ?, ĊĠĠĠĠĠĠĠ Ġtags : ĠList < String >? ĊĠĠĠ Ġ): ĠMail Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsend ( listOf ( to Email ), ĠlistOf ( name ), Ġsubject , Ġhtml , Ġtext , Ġtags ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend ( ĊĠĠĠĠĠĠĠ Ġto List : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġsubject : ĠString , ĊĠĠĠĠĠĠĠ Ġhtml : ĠString , ĊĠĠĠĠĠĠĠ Ġtext : ĠString ?, ĊĠĠĠĠĠĠĠ Ġtags : ĠList < String >? ĊĠĠĠ Ġ): ĠMail Response Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Email Ġ= Ġarray ListOf < String >() ĊĠĠĠĠĠĠĠ Ġval Ġnames Ġ= Ġarray ListOf < String >() ĊĠĠĠĠĠĠĠ Ġto List . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparts Ġ= Ġit . split ("< ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( parts . size Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġparts [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġemail Ġ= Ġit . remove Prefix ( name ). trim (). remove Prefix ("< "). remove Suffix ("> ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Email . add ( email ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnames . add ( name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Email . add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnames . add ("") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsend ( to Email , Ġnames , Ġsubject , Ġhtml , Ġtext , Ġtags ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend ( ĊĠĠĠĠĠĠĠ Ġto Email : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġnames : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġsubject : ĠString , ĊĠĠĠĠĠĠĠ Ġhtml : ĠString , ĊĠĠĠĠĠĠĠ Ġtext : ĠString ?, ĊĠĠĠĠĠĠĠ Ġtags : ĠList < String >? ĊĠĠĠ Ġ): ĠMail Response Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpost Data Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" key " Ġto Ġconfig . apiKey , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" message " Ġto Ġmutable Map Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" html " Ġto Ġhtml , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" subject " Ġto Ġsubject , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" from _ email " Ġto Ġconfig . from Email , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" from _ name " Ġto Ġconfig . from Name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġmsg Ġ= Ġpost Data [" message "] Ġas ĠMutable Map < String , ĠAny > ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! tags . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmsg [" tags "] Ġ= Ġtags ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( text . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmsg [" auto _ text "] Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmsg [" text "] Ġ= Ġtext ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġto List Ġ= Ġarray ListOf < Map < String , ĠString ? >>() ĊĊĠĠĠĠĠĠĠ Ġif Ġ( config . dev Mode Ġ&& Ġ! config . to Dev . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Email . forEach Indexed Ġ{ Ġidx , Ġs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto List . add ( map Of (" type " Ġto Ġ" to ", Ġ" email " Ġto Ġconfig . to Dev , Ġ" name " Ġto Ġnames [ idx ])) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Email . forEach Indexed Ġ{ Ġidx , Ġs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto List . add ( map Of (" type " Ġto Ġ" to ", Ġ" email " Ġto Ġs , Ġ" name " Ġto Ġnames [ idx ])) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmsg [" to "] Ġ= Ġto List ĊĊĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġweb Client . post ( send Endpoint ). send Json ( JsonObject ( post Data )). await () ĊĠĠĠĠĠĠĠ Ġval Ġstatus Ġ= Ġres . statusCode () ĊĠĠĠĠĠĠĠ Ġval Ġtag Str Ġ= Ġif Ġ( tags . isNull OrEmpty ()) Ġ"" Ġelse Ġtags . join ToString (",") ĊĊĠĠĠĠĠĠĠ Ġif Ġ( status Ġin Ġ 2 0 0 .. 2 9 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjson Ġ= Ġres . body As JsonArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( json Ġ!= Ġnull Ġ&& Ġ! json . isEmpty Ġ&& Ġjson . size () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmand r ill Status Ġ= Ġjson . get JsonObject ( 0 ). getString (" status ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( mand r ill Status Ġ== Ġ" sent ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMail Response ( true , Ġres . body AsString (), ĠJsonObject (). put (" results ", Ġjson )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" M AND R ILL _ RE JECT Ġ${ to Email [ 0 ]} Ġ$ tag Str Ġ$ json ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMail Response ( false , Ġres . body AsString (), ĠJsonObject (). put (" results ", Ġjson )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// mand r ill Ġfailed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" M AND R ILL _ FAIL _$ status Ġ${ to Email [ 0 ]} Ġ$ tag Str Ġ$ json ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMail Response ( false , Ġres . body AsString (), ĠJsonObject (). put (" results ", Ġjson )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" M AND R ILL _ FAIL _$ status Ġ${ to Email [ 0 ]} Ġ$ tag Str Ġ${ res . body AsString () }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMail Response ( false , Ġres . body AsString (), Ġres . body As JsonObject ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġretry ( num Retries : ĠInt , Ġdelay Try : ĠLong , Ġoperation : Ġsuspend Ġ( Mail Service ) Ġ-> ĠMail Response ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġres : ĠMail Response ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġshould Retry Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar ĠerrMsg Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġres Ġ= Ġoperation . invoke ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! res . success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshould Retry Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠerrMsg Ġ= Ġres . body ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshould Retry Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠerrMsg Ġ= Ġe . message . toString () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num Retries Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res Ġ== Ġnull Ġ|| Ġ! res . success ) Ġlogger . error (" M AND R ILL _ RETRY _ ALL _ FAIL Ġ$ err Msg ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( should Retry ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num Retries Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( delay Try Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( delay Try ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug (" M AND R ILL _ RETRY _$ num Retries Ġ$ err Msg ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġretry ( num Retries Ġ- Ġ 1 , Ġdelay Try , Ġoperation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend In Circuit ( ĊĠĠĠĠĠĠĠ Ġbreak er : ĠCircuit Breaker , Ġto Email : ĠString , ĊĠĠĠĠĠĠĠ Ġname : ĠString , Ġsubject : ĠString , ĊĠĠĠĠĠĠĠ Ġhtml : ĠString , Ġtext : ĠString ?, Ġtags : ĠList < String >? ĊĠĠĠ Ġ): ĠMail Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġbreak er . execute Suspend Await Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġsend ( to Email , Ġname , Ġsubject , Ġhtml , Ġtext , Ġtags ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! res . success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException ( res . body ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġres ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ