package Ġcom . ke ith m ack ay . api . routes Ċ Ċ import Ġcom . google . inject . Inject Ċ import Ġcom . google . inject . Singleton Ċ import Ġcom . ke ith m ack ay . api . auth . Request Validator Ċ import Ġcom . ke ith m ack ay . api . db . ID atabase Ċ import Ġcom . ke ith m ack ay . api . model . Success Response Ċ import Ġcom . ke ith m ack ay . api . model . User Ċ import Ġcom . ke ith m ack ay . api . utils .* Ċ import Ġio . jav al in . api builder . Api Builder . path Ċ import Ġio . jav al in . http . Context Ċ import Ġio . jav al in . http . Unauthorized Response Ċ import Ġorg . bson . Document Ċ import Ġjava . util . concurrent . Comp letableFuture ĊĊ Ċ @ Singleton Ċ class ĠTracker Router Ġ@ Inject Ċ internal Ġconstructor ( private Ġval Ġvalidator : ĠRequest Validator , Ġdb : ĠID atabase ) Ġ: ĠRouter Ġ{ ĊĊĠ Ġprivate Ġval Ġlog Ġ= Ġget Logger ( this :: class ) ĊĊĠ Ġprivate Ġval Ġevent Collection Ġ= Ġdb . get Collection (" events ") ĊĊĠ Ġoverride Ġfun Ġroutes () Ġ{ ĊĠĠĠ Ġpath (" tracker ") Ġ{ ĊĠĠĠĠĠ Ġvalidator . secure Put (" events ", Ġthis :: add Event ) Ġ{ Ġctx , Ġbody Ġ-> ĊĠĠĠĠĠĠĠ Ġthis . add Event ( ctx , Ġbody ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġvalidator . secure Get (" events ", Ġ{ Ġctx , Ġ_, Ġuser Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ(! user . admin ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlog . info (" User Ġ'${ user . username }' Ġtried Ġto Ġaccess Ġtracking Ġevents , Ġbut Ġis Ġnot Ġadmin ") ĊĠĠĠĠĠĠĠĠĠ Ġthrow ĠUnauthorized Response () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġlimit Ġ= ĠInteger . parseInt ( ctx . query Param (" pageSize ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. coerce At Most ( 1 0 0 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġpage Ġ= ĠInteger . parseInt ( ctx . query Param (" page ", Ġ" 0 ")) ĊĠĠĠĠĠĠĠ Ġval Ġquery Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠDocument . parse ( ctx . query Param (" query ")) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlog . info (" Invalid ĠQuery ĠSup p lied : Ġ${ ctx . query Param (" query ") }") ĊĠĠĠĠĠĠĠĠĠ Ġdoc () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġctx . json ( Comp letableFuture . supply Async Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġevent Collection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. find ( query ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. skip ( page Ġ* Ġlimit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. limit ( limit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. into ( thread Safe List < Document >()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map (:: clean Doc ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġadd Event ( ctx : ĠContext , Ġbody : ĠDocument , Ġuser : ĠUser ? Ġ= Ġnull ): ĠNothing Ġ{ ĊĠĠĠ Ġval Ġadditional Ġ= Ġdoc (" time ", ĠSystem . currentTimeMillis ()) ĊĠĠĠ Ġadditional . run Ġ{ ĊĠĠĠĠĠ Ġif Ġ( user Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . append (" user ", Ġuser . username ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġevent Collection . insert One ( body ĊĠĠĠĠĠĠĠ Ġ. clean To (" url ", Ġ" time ", Ġ" data ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" feature ", Ġ" userAgent ", Ġ" ip ", Ġ" location ") ĊĠĠĠĠĠĠĠ Ġ. join ( doc (" ip ", Ġctx . ip ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add (" userAgent ", Ġctx :: userAgent ), Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ. join ( additional , Ġtrue )) ĊĠĠĠ Ġthrow ĠSuccess Response () ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġis Health y (): ĠBoolean Ġ= Ġtrue Ċ }