/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠNet flix , ĠInc . Ċ Ġ* Ċ Ġ* Ġ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 . example . demo . services Ċ Ċ import Ġcom . example . demo . generated . types . Review Ċ import Ġcom . example . demo . generated . types . Submitted Review Ċ import Ġcom . github . java faker . F aker Ċ import Ġorg . reactiv est ream s . Publisher Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . springframework . stereotype . Service Ċ import Ġreactor . core . publisher . Connect able Flux Ċ import Ġreactor . core . publisher . Flux Ċ import Ġreactor . core . publisher . Flux Sink Ċ import Ġjava . time . Offset DateTime Ċ import Ġjava . time . Zone Id Ċ import Ġjava . time . Zone Offset Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . stream . Int Stream Ċ import Ġjavax . annotation . Post Construct Ċ import Ġkotlin . streams . toList Ċ Ċ interface ĠRe views Service Ġ{ ĊĠĠĠ Ġfun Ġreviews For Show ( show Id : ĠInt ): ĠList < Review >? ĊĠĠĠ Ġfun Ġreviews For Shows ( show Ids : ĠList < Int >): ĠMap < Int , ĠList < Review >> ĊĠĠĠ Ġfun Ġsave Review ( review Input : ĠSub mitted Review ) ĊĠĠĠ Ġfun Ġget Reviews Publisher (): ĠPublisher < Review > Ċ } Ċ Ċ /** Ċ Ġ* ĠThis Ġservice Ġem ulates Ġa Ġdata Ġstore . Ċ Ġ* ĠFor Ġconvenience Ġin Ġthe Ġdemo Ġwe Ġjust Ġgenerate ĠRe views Ġin Ġmemory , Ġbut Ġimagine Ġthis Ġwould Ġbe Ġbacked Ġby Ġfor Ġexample Ġa Ġdatabase . Ċ Ġ* ĠIf Ġthis Ġwas Ġindeed Ġbacked Ġby Ġa Ġdatabase , Ġit Ġwould Ġbe Ġvery Ġimportant Ġto Ġavoid Ġthe ĠN + 1 Ġproblem , Ġwhich Ġmeans Ġwe Ġneed Ġto Ġuse Ġa ĠDataLoader Ġto Ġcall Ġthis Ġclass . Ċ Ġ*/ Ċ @ Service Ċ class ĠDefault Reviews Service ( private Ġval Ġshows Service : ĠShows Service ): ĠRe views Service Ġ{ ĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠLoggerFactory . getLogger ( Reviews Service :: class . java ) ĊĊĠĠĠ Ġprivate Ġval Ġreviews Ġ= Ġmutable Map Of < Int , ĠMutable List < Review >>() ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġreviews Stream Ġ: ĠFlux Sink < Review > ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġreviews Publisher : ĠConnect able Flux < Review > ĊĊĠĠĠ Ġ@ Post Construct ĊĠĠĠ Ġfun Ġcreate Reviews () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfaker Ġ= ĠFaker () ĊĊĠĠĠĠĠĠĠ Ġ// For Ġeach Ġshow Ġwe Ġgenerate Ġa Ġrandom Ġset Ġof Ġreviews . ĊĠĠĠĠĠĠĠ Ġshows Service . shows (). forEach Ġ{ Ġshow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgenerated Reviews Ġ= ĠInt Stream . range ( 0 , Ġfaker . number (). number Between ( 1 , Ġ 2 0 )). map To Obj Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdate Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfaker . date (). past ( 3 0 0 , ĠTimeUnit . DAYS ). to Instant (). at Zone ( Zone Id . system Default ()). to LocalDateTime () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠReview ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġusername Ġ= Ġfaker . name (). username (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstar Score Ġ= Ġfaker . number (). number Between ( 0 , Ġ 6 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubmitted Date Ġ= ĠOffset DateTime . of ( date , ĠZone Offset . UTC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toList (). to Mutable List () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreviews [ show . id ] Ġ= Ġgenerated Reviews ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpublisher Ġ= ĠFlux . create < Review > Ġ{ Ġemitter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreviews Stream Ġ= Ġemitter ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠ Ġreviews Publisher Ġ= Ġpublisher . publish () ĊĠĠĠĠĠĠĠ Ġreviews Publisher . connect () ĊĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHope fully Ġnobody Ġcalls Ġthis Ġfor Ġmultiple Ġshows Ġwithin Ġa Ġsingle Ġquery , Ġthat Ġwould Ġindicate Ġthe ĠN + 1 Ġproblem ! ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġreviews For Show ( show Id : ĠInt ): ĠList < Review >? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġreviews [ show Id ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġis Ġthe Ġmethod Ġwe Ġwant Ġto Ġcall Ġwhen Ġloading Ġreviews Ġfor Ġmultiple Ġshows . ĊĠĠĠĠ Ġ* ĠIf Ġthis Ġcode Ġwas Ġbacked Ġby Ġa Ġrel ational Ġdatabase , Ġit Ġwould Ġselect Ġreviews Ġfor Ġall Ġrequested Ġshows Ġin Ġa Ġsingle ĠSQL Ġquery . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġreviews For Shows ( show Ids : ĠList < Int >): ĠMap < Int , ĠList < Review >> Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . info (" Loading Ġreviews Ġfor Ġshows Ġ${ show Ids . join ToString () }") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġreviews . filter Ġ{ Ġshow Ids . contains ( it . key ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġsave Review ( review Input : ĠSub mitted Review ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġreviews For Movie Ġ= Ġreviews . get Or Put ( review Input . show Id , Ġ{ Ġmutable ListOf () Ġ}) ĊĠĠĠĠĠĠĠ Ġval Ġreview Ġ= ĠReview ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġusername Ġ= Ġreview Input . username , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstar Score Ġ= Ġreview Input . star Score , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubmitted Date Ġ= ĠOffset DateTime . now () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġreviews For Movie . add ( review ) ĊĠĠĠĠĠĠĠ Ġreviews Stream . next ( review ) ĊĊĠĠĠĠĠĠĠ Ġlogger . info (" Review Ġadded Ġ{}", Ġreview ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Reviews Publisher (): ĠPublisher < Review > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġreviews Publisher ĊĠĠĠ Ġ} Ċ }