/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 . ĠThe ĠHy ve Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* Ċ Ġ* ĠSee Ġthe Ġfile ĠLICENSE Ġin Ġthe Ġroot Ġof Ġthis Ġrepository . Ċ Ġ*/ Ċ Ċ package Ġorg . radar base . management . client Ċ Ċ import Ġcom . fasterxml . jackson . annotation . JsonInclude Ċ import Ġcom . fasterxml . jackson . databind . Deserialization Feature Ċ import Ġcom . fasterxml . jackson . databind . ObjectMapper Ċ import Ġcom . fasterxml . jackson . databind . Object Reader Ċ import Ġcom . fasterxml . jackson . databind . Serialization Feature Ċ import Ġcom . fasterxml . jackson . datatype . js r 3 1 0 . Java Time Module Ċ import Ġcom . fasterxml . jackson . module . kotlin . json Mapper Ċ import Ġcom . fasterxml . jackson . module . kotlin . kotlin Module Ċ import Ġokhttp 3 . Http Url Ċ import Ġokhttp 3 . Http Url . Companion . to Http Url OrNull Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġokhttp 3 . Request Ċ import Ġokhttp 3 . Response Ċ import Ġorg . radar base . oauth . OAuth 2 AccessToken Details Ċ import Ġorg . radar base . oauth . OAuth 2 Client Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Malformed URLException Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ /** Ċ Ġ* ĠClient Ġfor Ġthe ĠManagement Portal ĠREST ĠAPI . Ċ Ġ*/ Ċ @ Suppress (" unused ") Ċ class ĠMP Client ( ĊĠĠĠ Ġ/** ĠServer Ġconfiguration Ġof Ġthe ĠManagement Portal ĠAPI . Ġ*/ ĊĠĠĠ Ġserver Config : ĠMP Server Config , ĊĠĠĠ Ġ/** ĠObjectMapper Ġto Ġuse Ġfor Ġall Ġrequests . Ġ*/ ĊĠĠĠ ĠobjectMapper : ĠObjectMapper ? Ġ= Ġnull , ĊĠĠĠ Ġ/** ĠHTTP Ġclient Ġto Ġmake Ġrequests Ġwith . Ġ*/ ĊĠĠĠ ĠhttpClient : ĠOk HttpClient ? Ġ= Ġnull , Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval ĠclientId : ĠString Ġ= Ġserver Config . clientId ĊĠĠĠ Ġprivate Ġval Ġclient Secret : ĠString Ġ= Ġserver Config . client Secret ĊĠĠĠ Ġval ĠbaseUrl : ĠHttp Url Ġ= Ġ( server Config . url . to Http Url OrNull () ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠMal formed URLException (" Cannot Ġparse Ġbase ĠURL Ġ${ server Config . url } Ġas Ġan ĠURL ")) ĊĠĠĠĠĠĠĠ Ġ. newBuilder () ĊĠĠĠĠĠĠĠ Ġ. add Path Segment ("") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġprivate Ġval ĠobjectMapper : ĠObjectMapper Ġ= ĠobjectMapper Ġ?: Ġjson Mapper Ġ{ ĊĠĠĠĠĠĠĠ Ġserialization In clusion ( JsonInclude . Include . NON _ NULL ) ĊĠĠĠĠĠĠĠ Ġadd Module ( Java Time Module ()) ĊĠĠĠĠĠĠĠ Ġadd Module ( kotlin Module Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Is Same As Default ( true ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġconfigure ( Serialization Feature . WRITE _ DAT ES _ AS _ TIMESTAMP S , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġconfigure ( Deserialization Feature . FAIL _ ON _ UNKNOWN _ PROPERTIES , Ġfalse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠHTTP Ġclient Ġto Ġmake Ġrequests Ġwith . Ġ*/ ĊĠĠĠ Ġvar ĠhttpClient : ĠOk HttpClient Ġ= ĠhttpClient Ġ?: ĠOk HttpClient (). newBuilder () ĊĠĠĠĠĠĠĠ Ġ. connect Timeout ( 1 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ. write Timeout ( 1 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ. read Timeout ( 3 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġprivate Ġval Ġproject List Reader : ĠObject Reader Ġby Ġlazy Ġ{ Ġthis . object Mapper . reader For ListOf ( MP Project :: class . java ) Ġ} ĊĠĠĠ Ġprivate Ġval Ġsubject List Reader : ĠObject Reader Ġby Ġlazy Ġ{ Ġthis . object Mapper . reader For ListOf ( MP Subject :: class . java ) Ġ} ĊĠĠĠ Ġprivate Ġval Ġclient List Reader : ĠObject Reader Ġby Ġlazy Ġ{ Ġthis . object Mapper . reader For ListOf ( MP OAuth Client :: class . java ) Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġoauth 2 Client Ġ= ĠOAuth 2 Client . Builder () ĊĠĠĠĠĠĠĠ Ġ. httpClient ( httpClient ) ĊĠĠĠĠĠĠĠ Ġ. credentials ( clientId , Ġclient Secret ) ĊĠĠĠĠĠĠĠ Ġ. endpoint ( baseUrl . to Url (), Ġ" oauth / token ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠValid Ġaccess Ġtoken Ġfor Ġthe ĠManagement Portal ĠREST ĠAPI . ĊĠĠĠĠ Ġ* Ġ@ throws Ġorg . radar base . exception . Token Exception Ġif Ġa Ġnew Ġaccess Ġtoken Ġcould Ġnot Ġbe Ġfetched ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġvalid Token : ĠOAuth 2 AccessToken Details ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġoauth 2 Client . valid Token ĊĊĠĠĠ Ġ/** ĠRequest Ġlist Ġof Ġprojects Ġfrom ĠManagement Portal . Ġ*/ ĊĠĠĠ Ġfun Ġrequest Projects ( ĊĠĠĠĠĠĠĠ Ġpage : ĠInt Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠ Ġsize : ĠInt Ġ= ĠInt . MAX _ VALUE , ĊĠĠĠ Ġ): ĠList < MP Project > Ġ= Ġrequest ( ĊĠĠĠĠĠĠĠ Ġproject List Reader , ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Path Segments (" api / projects ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" page ", Ġpage . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" size ", Ġsize . toString ()) ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequest Ġlist Ġof Ġsubjects Ġfrom ĠManagement Portal Ġproject . ĠThe Ġ[ projectId ] Ġis Ġthe Ġname Ġthat ĊĠĠĠĠ Ġ* Ġthe Ġproject Ġis Ġidentified Ġby . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġrequest Subject s ( ĊĠĠĠĠĠĠĠ ĠprojectId : ĠString , ĊĠĠĠĠĠĠĠ Ġpage : ĠInt Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠ Ġsize : ĠInt Ġ= ĠInt . MAX _ VALUE , ĊĠĠĠ Ġ): ĠList < MP Subject > Ġ= Ġrequest < List < MP Subject >>( ĊĠĠĠĠĠĠĠ Ġsubject List Reader , ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Path Segments (" api / projects /$ projectId / subjects ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" page ", Ġpage . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" size ", Ġsize . toString ()) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . copy ( projectId Ġ= ĠprojectId ) Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRequest Ġlist Ġof ĠOAuth Ġ 2 . 0 Ġclients Ġfrom ĠManagement Portal . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġrequest Clients ( ĊĠĠĠĠĠĠĠ Ġpage : ĠInt Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠ Ġsize : ĠInt Ġ= ĠInt . MAX _ VALUE , ĊĠĠĠ Ġ): ĠList < MP OAuth Client > Ġ= Ġrequest ( ĊĠĠĠĠĠĠĠ Ġclient List Reader , ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Path Segments (" api / oauth - clients ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" page ", Ġpage . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" size ", Ġsize . toString ()) ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMake Ġa Ġrequest Ġand Ġparse Ġthe Ġresult Ġas ĠJSON . ĠThe Ġresponse Ġbody Ġis Ġparsed Ġby Ġ[ reader ]. ĠThe ĊĠĠĠĠ Ġ* Ġurl Ġto Ġquery Ġis Ġconstructed Ġusing Ġ[ url Builder ]. ĠIn Ġ[ url Builder ], Ġuse ĊĠĠĠĠ Ġ* Ġ[ Http Url . Builder . add Path Segments ] Ġover Ġ[ Http Url . Builder . encoded Path ] Ġto Ġpreserve Ġthe Ġcorrect ĊĠĠĠĠ Ġ* Ġbase ĠURL . ĠThe Ġrequest Ġcan Ġoptionally Ġbe Ġmodified Ġwith Ġ[ request Builder ], Ġfor Ġexample Ġto ĠPOST ĊĠĠĠĠ Ġ* Ġcontent Ġor Ġadd Ġheaders . ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException Ġif Ġthe Ġrequest Ġfails , Ġhas Ġa Ġun successful Ġstatus Ġcode Ġor Ġif Ġthe Ġresponse ĊĠĠĠĠ Ġ* ĠĠĠĠĠ Ġcannot Ġbe Ġread . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġ< T > Ġrequest ( ĊĠĠĠĠĠĠĠ Ġreader : ĠObject Reader , ĊĠĠĠĠĠĠĠ Ġurl Builder : ĠHttp Url . Builder . () Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠ Ġrequest Builder : Ġ( Request . Builder . () Ġ-> ĠUnit ) Ġ= Ġ{ Ġ} ĊĠĠĠ Ġ): ĠT Ġ= Ġrequest ( url Builder , Ġrequest Builder ) Ġ{ Ġrequest , Ġresponse Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ(! response . is Successful ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Request Ġto Ġ${ request . url } Ġfailed Ġ( code Ġ${ response . code }) ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġresponse . body Ġ?: Ġthrow ĠIOException (" No Ġresponse Ġbody Ġto Ġ${ request . url }") ĊĠĠĠĠĠĠĠ Ġreader . readValue ( body . byte Stream ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMake Ġa Ġrequest Ġwithout Ġany Ġresponse Ġprocessing . ĠThe ĊĠĠĠĠ Ġ* Ġurl Ġto Ġquery Ġis Ġconstructed Ġusing Ġ[ url Builder ]. ĠIn Ġ[ url Builder ], Ġuse ĊĠĠĠĠ Ġ* Ġ[ Http Url . Builder . add Path Segments ] Ġover Ġ[ Http Url . Builder . encoded Path ] Ġto Ġpreserve Ġthe Ġcorrect ĊĠĠĠĠ Ġ* Ġbase ĠURL . ĠThe Ġrequest Ġcan Ġoptionally Ġbe Ġmodified Ġwith Ġ[ request Builder ], Ġfor Ġexample Ġto ĠPOST ĊĠĠĠĠ Ġ* Ġcontent Ġor Ġadd Ġheaders . ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException Ġif Ġthe Ġrequest Ġfails Ġor Ġhas Ġa Ġun successful Ġstatus Ġcode . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġrequest ( ĊĠĠĠĠĠĠĠ Ġurl Builder : ĠHttp Url . Builder . () Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠ Ġrequest Builder : Ġ( Request . Builder . () Ġ-> ĠUnit ) Ġ= Ġ{ Ġ}, ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequest ( url Builder , Ġrequest Builder ) Ġ{ Ġrequest , Ġresponse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! response . is Successful ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Request Ġto Ġ${ request . url } Ġfailed Ġ( code Ġ${ response . code }) ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMake Ġa Ġrequest Ġwithout Ġcustom Ġresponse Ġprocessing . ĠThe ĊĠĠĠĠ Ġ* Ġurl Ġto Ġquery Ġis Ġconstructed Ġusing Ġ[ url Builder ]. ĠIn Ġ[ url Builder ], Ġuse ĊĠĠĠĠ Ġ* Ġ[ Http Url . Builder . add Path Segments ] Ġover Ġ[ Http Url . Builder . encoded Path ] Ġto Ġpreserve Ġthe Ġcorrect ĊĠĠĠĠ Ġ* Ġbase ĠURL . ĠThe Ġrequest Ġcan Ġoptionally Ġbe Ġmodified Ġwith Ġ[ request Builder ], Ġfor Ġexample Ġto ĠPOST ĊĠĠĠĠ Ġ* Ġcontent Ġor Ġadd Ġheaders . ĠThe Ġresponse Ġcan Ġbe Ġhandled Ġwith Ġ[ response Handler ], Ġe . g ., Ġby ĊĠĠĠĠ Ġ* Ġevaluating Ġthe Ġstatus Ġcode Ġor Ġthe Ġbody Ġwith Ġa Ġcustom Ġbody Ġreader . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġ< T > Ġrequest ( ĊĠĠĠĠĠĠĠ Ġurl Builder : ĠHttp Url . Builder . () Ġ-> ĠUnit , ĊĠĠĠĠĠĠĠ Ġrequest Builder : ĠRequest . Builder . () Ġ-> ĠUnit Ġ= Ġ{ Ġ}, ĊĠĠĠĠĠĠĠ Ġresponse Handler : Ġ( Request , ĠResponse ) Ġ-> ĠT , ĊĠĠĠ Ġ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest . Builder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġurl ( baseUrl . newBuilder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheader (" Authorization ", Ġ" Bearer Ġ${ valid Token . accessToken }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Builder () ĊĠĠĠĠĠĠĠ Ġ}. build () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠhttpClient . new Call ( request ). execute (). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Handler ( request , Ġit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠMP Server Config ( ĊĠĠĠĠĠĠĠ Ġval Ġurl : ĠString , ĊĠĠĠĠĠĠĠ Ġval ĠclientId : ĠString , ĊĠĠĠĠĠĠĠ Ġval Ġclient Secret : ĠString , ĊĠĠĠ Ġ) Ċ } Ċ