package Ġno . nav . hel se . h ops . domain Ċ Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . cancel And Join Ċ import Ġkotlinx . coroutines . isActive Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġno . nav . hel se . h ops . infrastructure . Configuration Ċ import Ġorg . hl 7 . fhir . r 4 . model . Bundle Ċ import Ġorg . hl 7 . fhir . r 4 . model . Instant Type Ċ import Ġorg . hl 7 . fhir . r 4 . model . Message Header Ċ import Ġorg . hl 7 . fhir . r 4 . model . Operation Outcome Ċ import Ġorg . hl 7 . fhir . r 4 . model . Reference Ċ import Ġorg . slf 4 j . Logger Ċ import Ġjava . io . Closeable Ċ import Ġjava . util . UUID Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ class ĠBest illing Consumer Job ( ĊĠĠĠ Ġprivate Ġval Ġmessage Bus : ĠMessage Bus , ĊĠĠĠ Ġprivate Ġval Ġlogger : ĠLogger , ĊĠĠĠ Ġprivate Ġval Ġvalidator : ĠF hir Resource Validator , ĊĠĠĠ Ġprivate Ġval Ġfhir Repo : ĠF hir Repository , ĊĠĠĠ Ġmessaging Config : ĠConfiguration . Fhir Messaging , ĊĠĠĠ Ġcontext : ĠCor outine Context Ġ= ĠDispatch ers . Default Ċ ) Ġ: ĠClose able Ġ{ ĊĠĠĠ Ġprivate Ġval Ġjob Ġ= ĠCor outine Scope ( context ). launch Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( isActive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessages Ġ= Ġmessage Bus . poll () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessages . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug (" Message : Ġ${ it . toJson () }") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . has Destination ( messaging Config . endpoint )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjob . cancel And Join () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġprocess ( message : ĠBundle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoperation Outcome Ġ= Ġvalidator . validate ( message ) ĊĠĠĠĠĠĠĠ Ġval Ġresources Ġ= Ġmessage . entry . map NotNull Ġ{ Ġit . resource Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( operation Outcome . is All Ok ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfhir Repo . add Range ( resources ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Message Header Ġ= Ġresources . first () Ġas ĠMessage Header ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalidation ErrorResponse Ġ= Ġcreate Response Message ( request Message Header , Ġoperation Outcome ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Bus . publish ( validation ErrorResponse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠBundle . has Destination ( expected Destination : ĠString ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġheader Ġ= Ġentry [ 0 ]. resource Ġas ĠMessage Header ĊĠĠĠ Ġreturn Ġheader . destination ?. count () Ġ== Ġ 1 Ġ&& Ġheader . destination . any Ġ{ Ġit . endpoint Ġ== Ġexpected Destination Ġ} Ċ } Ċ Ċ private Ġfun Ġcreate Response Message ( ĊĠĠĠ Ġrequest Message Header : ĠMessage Header , ĊĠĠĠ Ġoperation Outcome : ĠOperation Outcome Ċ ): ĠBundle Ġ{ ĊĠĠĠ Ġval Ġoutcome Copy Ġ= Ġoperation Outcome . copy (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġid Ġ= ĠIdentity Generator . Create UUID 5 ( request Message Header . id , Ġ" details "). toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġresponse Message Header Ġ= ĠMessage Header (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġid Ġ= ĠIdentity Generator . Create UUID 5 ( request Message Header . id , Ġ" response "). toString () ĊĠĠĠĠĠĠĠ Ġevent Ġ= Ġrequest Message Header . event ĊĠĠĠĠĠĠĠ Ġdestination Ġ= ĠlistOf ( as Destination ( request Message Header . source )) ĊĠĠĠĠĠĠĠ Ġsource Ġ= Ġas Source ( request Message Header . destination . single ()) ĊĠĠĠĠĠĠĠ Ġresponse Ġ= ĠMessage Header . Message Header Response Component (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier Ġ= Ġrequest Message Header . id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= ĠMessage Header . ResponseType . FATAL ERROR ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdetails Ġ= ĠReference ( outcome Copy ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠBundle (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġid Ġ= ĠUUID . randomUUID (). toString () ĊĠĠĠĠĠĠĠ Ġtimestamp Element Ġ= ĠInstant Type . with Current Time () ĊĠĠĠĠĠĠĠ Ġtype Ġ= ĠBundle . Bundle Type . MESSAGE ĊĠĠĠĠĠĠĠ Ġadd Resource ( response Message Header ) ĊĠĠĠĠĠĠĠ Ġadd Resource ( outcome Copy ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġas Destination ( src : ĠMessage Header . Message Source Component ) Ġ= ĊĠĠĠ ĠMessage Header . Message Destination Component ( src . endpoint Element ). apply Ġ{ Ġname Ġ= Ġsrc . name Ġ} Ċ Ċ private Ġfun Ġas Source ( dest : ĠMessage Header . Message Destination Component ) Ġ= ĊĠĠĠ ĠMessage Header . Message Source Component ( dest . endpoint Element ). apply Ġ{ Ġname Ġ= Ġdest . name Ġ} Ċ