99import org .apache .commons .collections4 .CollectionUtils ;
1010import org .apache .commons .lang3 .ObjectUtils ;
1111import org .apache .commons .lang3 .StringUtils ;
12+ import org .apache .http .client .utils .URIBuilder ;
1213import org .prebid .server .auction .model .AuctionContext ;
1314import org .prebid .server .auction .model .BidInfo ;
1415import org .prebid .server .auction .model .CachedDebugLog ;
2223import org .prebid .server .cache .model .DebugHttpCall ;
2324import org .prebid .server .cache .proto .request .bid .BidCacheRequest ;
2425import org .prebid .server .cache .proto .request .bid .BidPutObject ;
26+ import org .prebid .server .cache .proto .response .CacheErrorResponse ;
2527import org .prebid .server .cache .proto .response .bid .BidCacheResponse ;
2628import org .prebid .server .cache .proto .response .bid .CacheObject ;
2729import org .prebid .server .cache .utils .CacheServiceUtil ;
4547import org .prebid .server .vertx .httpclient .HttpClient ;
4648import org .prebid .server .vertx .httpclient .model .HttpClientResponse ;
4749
50+ import java .net .URISyntaxException ;
4851import java .net .URL ;
4952import java .time .Clock ;
5053import java .util .ArrayList ;
5558import java .util .Objects ;
5659import java .util .Set ;
5760import java .util .concurrent .TimeoutException ;
61+ import java .util .function .BiConsumer ;
5862import java .util .function .Function ;
5963import java .util .stream .Collectors ;
6064import java .util .stream .Stream ;
@@ -66,6 +70,8 @@ public class CoreCacheService {
6670 private static final String BID_WURL_ATTRIBUTE = "wurl" ;
6771 private static final String TRACE_INFO_SEPARATOR = "-" ;
6872 private static final int MAX_DATACENTER_REGION_LENGTH = 4 ;
73+ private static final String UUID_QUERY_PARAMETER = "uuid" ;
74+ private static final String CH_QUERY_PARAMETER = "ch" ;
6975
7076 private final HttpClient httpClient ;
7177 private final URL externalEndpointUrl ;
@@ -186,18 +192,27 @@ private Future<BidCacheResponse> makeRequest(BidCacheRequest bidCacheRequest,
186192 cacheHeaders ,
187193 mapper .encodeToString (bidCacheRequest ),
188194 remainingTimeout )
189- .map (response -> toBidCacheResponse (
195+ .map (response -> processVtrackWriteCacheResponse (
190196 response .getStatusCode (), response .getBody (), bidCount , accountId , startTime ))
191- .recover (exception -> failResponse (exception , accountId , startTime ));
197+ .recover (exception -> failVtrackCacheWriteResponse (exception , accountId , startTime ));
192198 }
193199
194- private Future <BidCacheResponse > failResponse (Throwable exception , String accountId , long startTime ) {
195- metrics .updateCacheRequestFailedTime (accountId , clock .millis () - startTime );
200+ private BidCacheResponse processVtrackWriteCacheResponse (int statusCode ,
201+ String responseBody ,
202+ int bidCount ,
203+ String accountId ,
204+ long startTime ) {
196205
197- logger .warn ("Error occurred while interacting with cache service: {}" , exception .getMessage ());
198- logger .debug ("Error occurred while interacting with cache service" , exception );
206+ final BidCacheResponse bidCacheResponse = toBidCacheResponse (statusCode , responseBody , bidCount );
207+ metrics .updateVtrackCacheWriteRequestTime (accountId , clock .millis () - startTime , MetricName .ok );
208+ return bidCacheResponse ;
209+ }
199210
200- return Future .failedFuture (exception );
211+ private <T > Future <T > failVtrackCacheWriteResponse (Throwable exception , String accountId , long startTime ) {
212+ if (exception instanceof PreBidException ) {
213+ metrics .updateVtrackCacheWriteRequestTime (accountId , clock .millis () - startTime , MetricName .err );
214+ }
215+ return failResponse (exception );
201216 }
202217
203218 public Future <BidCacheResponse > cachePutObjects (List <BidPutObject > bidPutObjects ,
@@ -210,7 +225,10 @@ public Future<BidCacheResponse> cachePutObjects(List<BidPutObject> bidPutObjects
210225 final List <CachedCreative > cachedCreatives =
211226 updatePutObjects (bidPutObjects , isEventsEnabled , biddersAllowingVastUpdate , accountId , integration );
212227
213- updateCreativeMetrics (accountId , cachedCreatives );
228+ updateCreativeMetrics (
229+ cachedCreatives ,
230+ (ttl , type ) -> metrics .updateVtrackCacheCreativeTtl (accountId , ttl , type ),
231+ (size , type ) -> metrics .updateVtrackCacheCreativeSize (accountId , size , type ));
214232
215233 return makeRequest (toBidCacheRequest (cachedCreatives ), cachedCreatives .size (), timeout , accountId );
216234 }
@@ -309,7 +327,10 @@ private Future<CacheServiceResult> doCacheOpenrtb(List<CacheBid> bids,
309327
310328 final BidCacheRequest bidCacheRequest = toBidCacheRequest (cachedCreatives );
311329
312- updateCreativeMetrics (accountId , cachedCreatives );
330+ updateCreativeMetrics (
331+ cachedCreatives ,
332+ (ttl , type ) -> metrics .updateCacheCreativeTtl (accountId , ttl , type ),
333+ (size , type ) -> metrics .updateCacheCreativeSize (accountId , size , type ));
313334
314335 final String url = ObjectUtils .firstNonNull (internalEndpointUrl , externalEndpointUrl ).toString ();
315336 final String body = mapper .encodeToString (bidCacheRequest );
@@ -343,8 +364,8 @@ private CacheServiceResult processResponseOpenrtb(HttpClientResponse response,
343364 externalEndpointUrl .toString (), httpRequest , httpResponse , startTime );
344365 final BidCacheResponse bidCacheResponse ;
345366 try {
346- bidCacheResponse = toBidCacheResponse (
347- responseStatusCode , response . getBody (), bidCount , accountId , startTime );
367+ bidCacheResponse = toBidCacheResponse (responseStatusCode , response . getBody (), bidCount );
368+ metrics . updateAuctionCacheRequestTime ( accountId , clock . millis () - startTime , MetricName . ok );
348369 } catch (PreBidException e ) {
349370 return CacheServiceResult .of (httpCall , e , Collections .emptyMap ());
350371 }
@@ -361,7 +382,7 @@ private CacheServiceResult failResponseOpenrtb(Throwable exception,
361382 logger .warn ("Error occurred while interacting with cache service: {}" , exception .getMessage ());
362383 logger .debug ("Error occurred while interacting with cache service" , exception );
363384
364- metrics .updateCacheRequestFailedTime (accountId , clock .millis () - startTime );
385+ metrics .updateAuctionCacheRequestTime (accountId , clock .millis () - startTime , MetricName . err );
365386
366387 final DebugHttpCall httpCall = makeDebugHttpCall (externalEndpointUrl .toString (), request , null , startTime );
367388 return CacheServiceResult .of (httpCall , exception , Collections .emptyMap ());
@@ -460,9 +481,7 @@ private String generateWinUrl(String bidId,
460481
461482 private BidCacheResponse toBidCacheResponse (int statusCode ,
462483 String responseBody ,
463- int bidCount ,
464- String accountId ,
465- long startTime ) {
484+ int bidCount ) {
466485
467486 if (statusCode != 200 ) {
468487 throw new PreBidException ("HTTP status code " + statusCode );
@@ -480,7 +499,6 @@ private BidCacheResponse toBidCacheResponse(int statusCode,
480499 throw new PreBidException ("The number of response cache objects doesn't match with bids" );
481500 }
482501
483- metrics .updateCacheRequestSuccessTime (accountId , clock .millis () - startTime );
484502 return bidCacheResponse ;
485503 }
486504
@@ -538,17 +556,20 @@ private static String resolveVideoBidUuid(String uuid, String hbCacheId) {
538556 return hbCacheId != null && uuid .endsWith (hbCacheId ) ? hbCacheId : uuid ;
539557 }
540558
541- private void updateCreativeMetrics (String accountId , List <CachedCreative > cachedCreatives ) {
559+ private void updateCreativeMetrics (List <CachedCreative > cachedCreatives ,
560+ BiConsumer <Integer , MetricName > updateCreativeTtlMetric ,
561+ BiConsumer <Integer , MetricName > updateCreativeSiseMetric ) {
562+
542563 for (CachedCreative cachedCreative : cachedCreatives ) {
543564 final BidPutObject payload = cachedCreative .getPayload ();
544565 final MetricName creativeType = resolveCreativeTypeName (payload );
545566 final Integer creativeTtl = ObjectUtils .defaultIfNull (payload .getTtlseconds (), payload .getExpiry ());
546567
547568 if (creativeTtl != null ) {
548- metrics . updateCacheCreativeTtl ( accountId , creativeTtl , creativeType );
569+ updateCreativeTtlMetric . accept ( creativeTtl , creativeType );
549570 }
550571
551- metrics . updateCacheCreativeSize ( accountId , cachedCreative .getSize (), creativeType );
572+ updateCreativeSiseMetric . accept ( cachedCreative .getSize (), creativeType );
552573 }
553574 }
554575
@@ -627,4 +648,55 @@ private static String normalizeDatacenterRegion(String datacenterRegion) {
627648 ? trimmedDatacenterRegion .substring (0 , MAX_DATACENTER_REGION_LENGTH )
628649 : trimmedDatacenterRegion ;
629650 }
651+
652+ public Future <HttpClientResponse > getCachedObject (String key , String ch , Timeout timeout ) {
653+ final long remainingTimeout = timeout .remaining ();
654+ if (remainingTimeout <= 0 ) {
655+ return Future .failedFuture (new TimeoutException ("Timeout has been exceeded" ));
656+ }
657+
658+ final URL endpointUrl = ObjectUtils .firstNonNull (internalEndpointUrl , externalEndpointUrl );
659+ final String url ;
660+ try {
661+ final URIBuilder uriBuilder = new URIBuilder (endpointUrl .toString ());
662+ uriBuilder .addParameter (UUID_QUERY_PARAMETER , key );
663+ if (StringUtils .isNotBlank (ch )) {
664+ uriBuilder .addParameter (CH_QUERY_PARAMETER , ch );
665+ }
666+ url = uriBuilder .build ().toString ();
667+ } catch (URISyntaxException e ) {
668+ return Future .failedFuture (new IllegalArgumentException ("Configured cache url is malformed" , e ));
669+ }
670+
671+ final long startTime = clock .millis ();
672+ return httpClient .get (url , cacheHeaders , remainingTimeout )
673+ .map (response -> processVtrackReadResponse (response , startTime ))
674+ .recover (CoreCacheService ::failResponse );
675+ }
676+
677+ private HttpClientResponse processVtrackReadResponse (HttpClientResponse response , long startTime ) {
678+ final int statusCode = response .getStatusCode ();
679+ final String body = response .getBody ();
680+
681+ if (statusCode == 200 ) {
682+ metrics .updateVtrackCacheReadRequestTime (clock .millis () - startTime , MetricName .ok );
683+ return response ;
684+ }
685+
686+ metrics .updateVtrackCacheReadRequestTime (clock .millis () - startTime , MetricName .err );
687+
688+ try {
689+ final CacheErrorResponse errorResponse = mapper .decodeValue (body , CacheErrorResponse .class );
690+ return HttpClientResponse .of (statusCode , response .getHeaders (), errorResponse .getMessage ());
691+ } catch (DecodeException e ) {
692+ throw new PreBidException ("Cannot parse response: " + body , e );
693+ }
694+ }
695+
696+ private static <T > Future <T > failResponse (Throwable exception ) {
697+ logger .warn ("Error occurred while interacting with cache service: {}" , exception .getMessage ());
698+ logger .debug ("Error occurred while interacting with cache service" , exception );
699+
700+ return Future .failedFuture (exception );
701+ }
630702}
0 commit comments