/* Ċ Ġ* ĠCopyright ĠOpen Search ĠContributors Ċ Ġ* ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ġ*/ Ċ Ċ package Ġorg . opense arch . notifications . core . client Ċ Ċ import Ġorg . apache . http . Http Entity Ċ import Ġorg . apache . http . HttpResponse Ċ import Ġorg . apache . http . client . config . Request Config Ċ import Ġorg . apache . http . client . methods . Closeable HttpResponse Ċ import Ġorg . apache . http . client . methods . Http Entity En closing Request Base Ċ import Ġorg . apache . http . client . methods . Http Patch Ċ import Ġorg . apache . http . client . methods . HttpPost Ċ import Ġorg . apache . http . client . methods . Http Put Ċ import Ġorg . apache . http . client . methods . HttpRequest Base Ċ import Ġorg . apache . http . entity . String Entity Ċ import Ġorg . apache . http . impl . client . Closeable HttpClient Ċ import Ġorg . apache . http . impl . client . Default HttpRequest Retry Handler Ċ import Ġorg . apache . http . impl . client . HttpClient Builder Ċ import Ġorg . apache . http . impl . conn . Pooling HttpClient ConnectionManager Ċ import Ġorg . apache . http . util . Entity Utils Ċ import Ġorg . opense arch . common . x content . X Content Factory Ċ import Ġorg . opense arch . common . x content . X ContentType Ċ import Ġorg . opense arch . notifications . core . setting . Plugin Settings Ċ import Ġorg . opense arch . notifications . core . utils . Open ForTesting Ċ import Ġorg . opense arch . notifications . core . utils . logger Ċ import Ġorg . opense arch . notifications . core . utils . string Ċ import Ġorg . opense arch . notifications . core . utils . validate Url Host Ċ import Ġorg . opense arch . notifications . spi . model . Message Content Ċ import Ġorg . opense arch . notifications . spi . model . destination . Ch ime Destination Ċ import Ġorg . opense arch . notifications . spi . model . destination . Custom Webhook Destination Ċ import Ġorg . opense arch . notifications . spi . model . destination . Slack Destination Ċ import Ġorg . opense arch . notifications . spi . model . destination . Webhook Destination Ċ import Ġorg . opense arch . rest . Rest Status Ċ import Ġjava . io . IOException Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . util . Collections Ċ import Ġkotlin . collections . HashSet Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġhandles Ġthe Ġconnections Ġto Ġthe Ġgiven ĠDestination . Ċ Ġ*/ Ċ class ĠDestination HttpClient Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠhttpClient : ĠClose able HttpClient ĊĊĠĠĠ Ġconstructor () Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . httpClient Ġ= Ġcreate HttpClient () ĊĠĠĠ Ġ} ĊĠĠĠ Ġ@ Open ForTesting ĊĠĠĠ Ġconstructor ( httpClient : ĠClose able HttpClient ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . httpClient Ġ= ĠhttpClient ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġby Ġlogger ( Destination HttpClient :: class . java ) ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġall Ġvalid Ġresponse Ġstatus ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠVALID _ RESPONSE _ STATUS Ġ= ĠCollections . unmodifiable Set ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHashSet ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRest Status . OK . status , ĠRest Status . CREATED . status , ĠRest Status . ACCEPT ED . status , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRest Status . NON _ AUTHOR IT ATIVE _ INFORMATION . status , ĠRest Status . NO _ CONTENT . status , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRest Status . RESET _ CONTENT . status , ĠRest Status . PAR TIAL _ CONTENT . status , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRest Status . MULTI _ STATUS . status ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcreate HttpClient (): ĠClose able HttpClient Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconfig : ĠRequest Config Ġ= ĠRequest Config . custom () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Connect Timeout ( Plugin Settings . connection Timeout ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setConnection Request Timeout ( Plugin Settings . connection Timeout ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Socket Timeout ( Plugin Settings . socket Timeout ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnection Manager Ġ= ĠPool ing HttpClient ConnectionManager () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnection Manager . max Total Ġ= ĠPlugin Settings . max Connections ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnection Manager . default Max Per Route Ġ= ĠPlugin Settings . max Connections Per Route ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠHttpClient Builder . create () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setDefault Request Config ( config ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set ConnectionManager ( connection Manager ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Retry Handler ( Default HttpRequest Retry Handler ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. use System Properties () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġexecute ( destination : ĠWeb hook Destination , Ġmessage : ĠMessage Content , Ġreference Id : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresponse : ĠClose able HttpResponse ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġvalidate Ġwebhook Ġurl Ġagainst Ġhost _ deny _ list Ġin Ġplugin Ġsettings ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate Url Host ( destination . url , ĠPlugin Settings . host Den y List ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Ġ= Ġget HttpResponse ( destination , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate ResponseStatus ( response ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse String Ġ= Ġget Response String ( response ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Http Ġresponse Ġfor Ġid Ġ$ reference Id : Ġ$ response String ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse String ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEntity Utils . consume Quiet ly ( response . entity ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġprivate Ġfun Ġget HttpResponse ( destination : ĠWeb hook Destination , Ġmessage : ĠMessage Content ): ĠClose able HttpResponse Ġ{ ĊĠĠĠĠĠĠĠ Ġvar ĠhttpRequest : ĠHttpRequest Base Ġ= ĠHttp Post ( destination . url ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( destination Ġis ĠCustom Webhook Destination ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠhttpRequest Ġ= Ġconstruct HttpRequest ( destination . method , Ġdestination . url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( destination . header Params . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġset Ġdefault Ġheader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠhttpRequest . setHeader (" Content - type ", Ġ" application / json ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( key , Ġvalue ) Ġin Ġdestination . header Params . entries ) ĠhttpRequest . setHeader ( key , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġentity Ġ= ĠString Entity ( build RequestBody ( destination , Ġmessage ), ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠ Ġ( httpRequest Ġas ĠHttp Entity En closing Request Base ). entity Ġ= Ġentity ĊĊĠĠĠĠĠĠĠ Ġreturn ĠhttpClient . execute ( httpRequest ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconstruct HttpRequest ( method : ĠString , Ġurl : ĠString ): ĠHttpRequest Base Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( method ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHttp Post . METHOD _ NAME Ġ-> ĠHttp Post ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHttp Put . METHOD _ NAME Ġ-> ĠHttp Put ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHttp Patch . METHOD _ NAME Ġ-> ĠHttp Patch ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġor Ġempty Ġmethod Ġsupplied . ĠOnly ĠPOST , ĠPUT Ġand ĠP ATCH Ġare Ġallowed " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun Ġget Response String ( response : ĠClose able HttpResponse ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġentity : ĠHttp Entity Ġ= Ġresponse . entity Ġ?: Ġreturn Ġ"{} " ĊĠĠĠĠĠĠĠ Ġreturn ĠEntity Utils . toString ( entity ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġvalidate ResponseStatus ( response : ĠHttpResponse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠstatusCode : ĠInt Ġ= Ġresponse . status Line . statusCode ĊĠĠĠĠĠĠĠ Ġif Ġ(! VALID _ RESPONSE _ STATUS . contains ( statusCode )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Failed : Ġ${ Entity Utils . toString ( response . entity )} ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbuild RequestBody ( destination : ĠWeb hook Destination , Ġmessage : ĠMessage Content ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠX Content Factory . content Builder ( X ContentType . JSON ) ĊĠĠĠĠĠĠĠ Ġval Ġkey Name Ġ= Ġwhen Ġ( destination ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSlack Ġwebhook Ġrequest Ġbody Ġhas Ġrequired Ġ" text " Ġas Ġkey Ġname Ġhttps :// api . slack . com / messaging / web hooks ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCh ime Ġwebhook Ġrequest Ġbody Ġhas Ġrequired Ġ" Content " Ġas Ġkey Ġname ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCustomer Ġwebhook Ġallows Ġinput Ġas Ġjson Ġor Ġplain Ġtext , Ġso Ġwe Ġjust Ġreturn Ġthe Ġmessage Ġas Ġit Ġis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSlack Destination Ġ-> Ġ" text " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCh ime Destination Ġ-> Ġ" Content " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCustom Webhook Destination Ġ-> Ġreturn Ġmessage . text Description ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġdestination Ġtype Ġis Ġprovided , ĠOnly ĠSlack , ĠCh ime Ġand ĠCustom Webhook Ġare Ġallowed " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbuilder . start Object () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. field ( key Name , Ġmessage . build Message With Title ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object () ĊĠĠĠĠĠĠĠ Ġreturn Ġbuilder . string () ĊĠĠĠ Ġ} Ċ } Ċ