package Ġnet . a quad c . ly che e . http Ċ Ċ import Ġio . under tow . Under tow Ċ import Ġio . under tow . server . Routing Handler Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġnet . a quad c . ly che e . http . client . okhttp 3 . blocking Ċ import Ġnet . a quad c . ly che e . http . client . okhttp 3 . comp letable Ċ import Ġnet . a quad c . ly che e . http . client . okhttp 3 . defer Ċ import Ġnet . a quad c . ly che e . http . client . okhttp 3 . future Ċ import Ġnet . a quad c . ly che e . http . client . okhttp 3 . template Ċ import Ġnet . a quad c . ly che e . http . param . Field Ċ import Ġnet . a quad c . ly che e . http . param . Fields Ċ import Ġnet . a quad c . ly che e . http . param . Header Ċ import Ġnet . a quad c . ly che e . http . param . Part Ċ import Ġnet . a quad c . ly che e . http . param . Parts Ċ import Ġnet . a quad c . ly che e . http . param . Path Ċ import Ġnet . a quad c . ly che e . http . param . Query Ċ import Ġnet . a quad c . ly che e . http . param . QueryParams Ċ import Ġnet . a quad c . ly che e . http . param . Query Presence Ċ import Ġnet . a quad c . ly che e . http . param . Response Ċ import Ġnet . a quad c . ly che e . http . server . under tow 2 . add Ċ import Ġnet . a quad c . persistence . extended . uuid Ċ import Ġnet . a quad c . persistence . type . byteArray Ċ import Ġnet . a quad c . persistence . type . i 3 2 Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġorg . junit . After Ċ import Ġorg . junit . Assert . assertArrayEquals Ċ import Ġorg . junit . Assert . assertEquals Ċ import Ġorg . junit . Test Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . util . UUID Ċ import Ġjava . util . concurrent . Executors ĊĊ Ċ class ĠUnder tow Ok Http E 2 E Ġ{ ĊĊĠĠĠ Ġval Ġhost Ġ= Ġ" 1 2 7 . 0 . 0 . 1 " ĊĠĠĠ Ġval Ġport Ġ= Ġ 8 1 8 2 ĊĠĠĠ Ġval ĠbaseUrl Ġ= Ġ" http :// $ host :$ port /" ĊĊĠĠĠ Ġval Ġclient Ġ= ĠOk HttpClient () ĊĠĠĠ Ġvar Ġserver : ĠUnder tow ? Ġ= Ġnull ĊĠĠĠ Ġ@ After Ġfun Ġcleanup () Ġ{ ĊĠĠĠĠĠĠĠ Ġserver ?. let Ġ{ Ġit . stop (); Ġserver Ġ= Ġnull Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` get Ġstring Ġwith Ġheader , Ġpath , Ġand Ġquery `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠgetUser Ġ= ĠGET ("/ user /{ role }/ ", ĠHeader (" X - Token "), ĠPath (" role "), ĠQuery (" id ", Ġuuid ), ĠQuery (" xxx ", ĠbyteArray ), ĠResponse < String >()) ĊĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Token : ĠString ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Role : ĠString ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Id : ĠUUID ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q X xx : ĠByteArray ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( getUser , Ġ{ Ġresponse Sender . send ( it ) Ġ}, Ġ{ Ġ_, Ġe Ġ-> Ġthrow Ġe Ġ}) Ġ{ Ġtoken , Ġrole , Ġid , Ġxxx Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Token Ġ= Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Role Ġ= Ġrole ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Id Ġ= Ġid ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q X xx Ġ= Ġxxx ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Access Ġgranted ." ĊĠĠĠĠĠĠĠ Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfunc Ġ= Ġclient . template ( baseUrl , ĠgetUser , Ġblocking Ġ{ Ġbody !!. use Ġ{ Ġit . string () Ġ} Ġ}) ĊĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠ Ġval Ġauthorized Func Ġ= Ġfunc (" s ooper Ġsec red ") ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġauthorized Func (" admin ", Ġid , Ġbyte ArrayOf ( 1 , Ġ 1 , Ġ 2 , Ġ 3 , Ġ 5 )) ĊĊĠĠĠĠĠĠĠ ĠassertEquals (" s ooper Ġsec red ", Ġr q Token ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" admin ", Ġr q Role ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( id , Ġr q Id ) ĊĠĠĠĠĠĠĠ Ġassert ArrayEquals ( byte ArrayOf ( 1 , Ġ 1 , Ġ 2 , Ġ 3 , Ġ 5 ), Ġr q X xx ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" Access Ġgranted .", Ġresponse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġ` post Ġwith Ġint Ġquery Presence , ĠqueryParams , Ġand Ġform - data `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġupdate User Ġ= ĠPOST ("/", ĊĠĠĠĠĠĠĠĠĠĠĠ ĠQuery Presence (" admin "), ĠQuery Params , ĠField (" name "), ĠField (" email "), ĠField (" birth ", Ġi 3 2 ), ĠFields , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResponse < UUID >()) ĊĊĠĠĠĠĠĠĠ Ġvar Ġr q Admin : ĠBoolean ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Params : ĠCollection < Pair < CharSequence , ĠCharSequence ? >> ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Name : ĠString ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Email : ĠString ĊĠĠĠĠĠĠĠ Ġvar Ġr q Birth : ĠInt ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Rest : ĠCollection < Pair < CharSequence , ĠCharSequence >> ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġrs Id : ĠUUID ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( update User , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġrs Id Ġ= Ġit ; Ġresponse Sender . send ( it . toString ()) Ġ}, Ġ{ Ġ_, Ġe Ġ-> Ġthrow Ġe Ġ} ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġis Admin , Ġparams , Ġname , Ġemail , Ġbirth , Ġrest Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Admin Ġ= Ġis Admin ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Params Ġ= Ġparams ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Name Ġ= Ġname ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Email Ġ= Ġemail ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Birth Ġ= Ġbirth ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Rest Ġ= Ġrest ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠ Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdo Update User Ġ= Ġclient . template ( baseUrl , Ġupdate User , Ġblocking Ġ{ ĠUUID . fromString ( body !!. use Ġ{ Ġit . string () Ġ}) Ġ}) ĊĠĠĠĠĠĠĠ Ġvar Ġid Ġ= Ġdo Update User ( true , ĠlistOf (" wh atever " Ġto Ġ" b rr rr "), Ġ" John ", Ġ" john @ ", Ġ 1 7 3 6 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf (" blah " Ġto Ġ" wh atever 1 ", Ġ" blah " Ġto Ġ" wh atever 2 ", Ġ" zz z " Ġto Ġ" xxx ")) ĊĠĠĠĠĠĠĠ ĠassertEquals ( true , Ġr q Admin ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf (" wh atever " Ġto Ġ" b rr rr "), Ġr q Params ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" John ", Ġr q Name ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" john @ ", Ġr q Email ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 7 3 6 , Ġr q Birth ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf (" blah " Ġto Ġ" wh atever 1 ", Ġ" blah " Ġto Ġ" wh atever 2 ", Ġ" zz z " Ġto Ġ" xxx "), Ġr q Rest ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( rs Id , Ġid ) ĊĊĠĠĠĠĠĠĠ Ġid Ġ= Ġdo Update User ( false , ĠlistOf < Nothing >(), Ġ" J ane ", Ġ" j ane @ ", Ġ 1 8 2 4 , ĠlistOf ()) ĊĠĠĠĠĠĠĠ ĠassertEquals ( false , Ġr q Admin ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf < Nothing >(), Ġr q Params ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" J ane ", Ġr q Name ) ĊĠĠĠĠĠĠĠ ĠassertEquals (" j ane @ ", Ġr q Email ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 8 2 4 , Ġr q Birth ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf < Nothing >(), Ġr q Rest ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( rs Id , Ġid ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġupload () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġupload Ġ= ĠPOST ("/ update Photo ", ĠStream (" image /* "), ĠResponse < Int >()) ĊĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Bytes : ĠByteArray ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( upload , Ġ{ ĠstatusCode Ġ= Ġit Ġ}, Ġ{ Ġ_, Ġe Ġ-> Ġthrow Ġe }) Ġ{ Ġimage Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Bytes Ġ= Ġimage (). read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠĠ 2 0 4 ĊĠĠĠĠĠĠĠ Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdo Upload Ġ= Ġclient . template ( baseUrl , Ġupload , Ġblocking Ġ{ Ġbody ?. close (); Ġcode Ġ}) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 2 0 4 , Ġdo Upload Ġ{ ĠByteArrayInputStream ( byte ArrayOf ( 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 4 , Ġ 3 , Ġ 2 , Ġ 1 )) Ġ}) ĊĠĠĠĠĠĠĠ Ġassert ArrayEquals ( byte ArrayOf ( 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 4 , Ġ 3 , Ġ 2 , Ġ 1 ), Ġr q Bytes ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġmultipart () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġupload Ġ= ĠPOST ("/ update Photo ", ĠField (" name "), ĠField (" id ", Ġuuid ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPart (" photo ", ĠStream (" image /* "), Ġ{ Ġ" photo . jpg " Ġ}), ĠPart s ( Text ("* /* "), Ġ{ Ġ" wh atever . bin " Ġ}), ĠResponse < Int >()) ĊĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Name : ĠString ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Id : ĠUUID ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Bytes : ĠByteArray ĊĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġr q Files : ĠCollection < Pair < CharSequence , ĠCharSequence >> ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( upload , Ġ{ ĠstatusCode Ġ= Ġit Ġ}, Ġ{ Ġ_, Ġe Ġ-> Ġthrow Ġe }) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname , Ġid , Ġphoto , Ġfiles Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Name Ġ= Ġname ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Id Ġ= Ġid ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Bytes Ġ= Ġphoto (). read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr q Files Ġ= Ġfiles ĊĊĠĠĠĠĠĠĠĠĠĠĠĠ 2 0 4 ĊĠĠĠĠĠĠĠ Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdo Upload Ġ= Ġclient . template ( baseUrl , Ġupload , Ġblocking Ġ{ Ġbody ?. close (); Ġcode Ġ}) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= ĠUUID . randomUUID () ĊĠĠĠĠĠĠĠ ĠassertEquals ( 2 0 4 , Ġdo Upload (" Unnamed ", Ġid , Ġ{ ĠByteArrayInputStream ( byte ArrayOf ( 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 4 , Ġ 3 , Ġ 2 , Ġ 1 )) Ġ}, ĠlistOf (" q we " Ġto Ġ" asd "))) ĊĠĠĠĠĠĠĠ ĠassertEquals (" Unnamed ", Ġr q Name ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( id , Ġr q Id ) ĊĠĠĠĠĠĠĠ Ġassert ArrayEquals ( byte ArrayOf ( 1 , Ġ 2 , Ġ 3 , Ġ 4 , Ġ 5 , Ġ 4 , Ġ 3 , Ġ 2 , Ġ 1 ), Ġr q Bytes ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( listOf (" q we " Ġto Ġ" asd "), Ġr q Files ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġfuture () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġget Ġ= ĠGET ("/", ĠResponse < Unit >()) ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( get , Ġ{ Ġresponse Sender . send (" ok ") Ġ}) Ġ{ Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġexecutor Ġ= ĠExec utors . new Single Thread Executor () ĊĠĠĠĠĠĠĠ Ġval Ġdo Get Ġ= Ġclient . template ( baseUrl , Ġget , Ġfuture ( executor ) Ġ{ Ġbody ?. close (); ĠUnit Ġ}) ĊĠĠĠĠĠĠĠ Ġdo Get (). get () ĊĠĠĠĠĠĠĠ Ġexecutor . shutdown () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġcf () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġget Ġ= ĠGET ("/", ĠResponse < Unit >()) ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( get , Ġ{ Ġresponse Sender . send (" ok ") Ġ}) Ġ{ Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdo Get Ġ= Ġclient . template ( baseUrl , Ġget , Ġcomplet able Ġ{ Ġbody ?. close (); ĠUnit Ġ}) ĊĠĠĠĠĠĠĠ Ġdo Get (). get () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test Ġfun Ġcoroutine () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġget Ġ= ĠGET ("/", ĠResponse < Unit >()) ĊĠĠĠĠĠĠĠ Ġserver Ġ= Ġunder tow Ġ{ Ġadd ( get , Ġ{ Ġresponse Sender . send (" ok ") Ġ}) Ġ{ Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdo Get Ġ= Ġclient . template ( baseUrl , Ġget , Ġdefer Ġ{ Ġbody ?. close (); ĠUnit Ġ}) ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Get (). await () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġunder tow ( register : ĠRouting Handler . () Ġ-> ĠRouting Handler ): ĠUnder tow Ġ= ĊĠĠĠĠĠĠĠ ĠUnder tow . builder (). add Http Listener ( port , Ġhost , ĠRouting Handler (). register ()). build (). also Ġ{ Ġit . start () Ġ} ĊĊĠĠĠ Ġoperator Ġfun Ġ< T , ĠU , ĠV , ĠW , ĠR > Ġ(( T , ĠU , ĠV , ĠW ) Ġ-> ĠR ). invoke ( t : ĠT ): Ġ( U , ĠV , ĠW ) Ġ-> ĠR Ġ= ĊĠĠĠĠĠĠĠ Ġ{ Ġu , Ġv , Ġw Ġ-> Ġthis ( t , Ġu , Ġv , Ġw ) Ġ} Ċ Ċ } Ċ