Skip to content

Commit

Permalink
Add request context to ExchangeService (prebid#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
rpanchyk authored and schernysh committed Jul 4, 2019
1 parent 69c9577 commit 5f7c8b7
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 202 deletions.
12 changes: 9 additions & 3 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.model.BidderRequest;
import org.prebid.server.auction.model.BidderResponse;
import org.prebid.server.auction.model.RequestContext;
import org.prebid.server.auction.model.Tuple2;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.BidderCatalog;
Expand Down Expand Up @@ -150,8 +151,13 @@ public ExchangeService(BidderCatalog bidderCatalog, HttpBidderRequester httpBidd
* Runs an auction: delegates request to applicable bidders, gathers responses from them and constructs final
* response containing returned bids and additional information in extensions.
*/
public Future<BidResponse> holdAuction(BidRequest bidRequest, UidsCookie uidsCookie, Timeout timeout,
MetricsContext metricsContext, RoutingContext context) {
public Future<BidResponse> holdAuction(RequestContext context) {
final RoutingContext routingContext = context.getRoutingContext();
final UidsCookie uidsCookie = context.getUidsCookie();
final BidRequest bidRequest = context.getBidRequest();
final Timeout timeout = context.getTimeout();
final MetricsContext metricsContext = context.getMetricsContext();

final ExtBidRequest requestExt;
try {
requestExt = requestExt(bidRequest);
Expand Down Expand Up @@ -188,7 +194,7 @@ public Future<BidResponse> holdAuction(BidRequest bidRequest, UidsCookie uidsCoo
toBidResponse(result.getLeft(), bidRequest, keywordsCreator, keywordsCreatorByBidType,
cacheInfo, publisherId, timeout, result.getRight(), debugEnabled))
.compose(bidResponse ->
bidResponsePostProcessor.postProcess(context, uidsCookie, bidRequest, bidResponse));
bidResponsePostProcessor.postProcess(routingContext, uidsCookie, bidRequest, bidResponse));
}

/**
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/org/prebid/server/auction/model/RequestContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.prebid.server.auction.model;

import com.iab.openrtb.request.BidRequest;
import io.vertx.ext.web.RoutingContext;
import lombok.Builder;
import lombok.Value;
import org.prebid.server.cookie.UidsCookie;
import org.prebid.server.execution.Timeout;
import org.prebid.server.metric.model.MetricsContext;
import org.prebid.server.settings.model.Account;

@Builder
@Value
public class RequestContext {

RoutingContext routingContext;

UidsCookie uidsCookie;

BidRequest bidRequest;

Timeout timeout;

MetricsContext metricsContext;

Account account;
}
44 changes: 27 additions & 17 deletions src/main/java/org/prebid/server/handler/openrtb2/AmpHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.prebid.server.auction.AmpResponsePostProcessor;
import org.prebid.server.auction.ExchangeService;
import org.prebid.server.auction.TimeoutResolver;
import org.prebid.server.auction.model.RequestContext;
import org.prebid.server.auction.model.Tuple2;
import org.prebid.server.auction.model.Tuple3;
import org.prebid.server.bidder.BidderCatalog;
Expand Down Expand Up @@ -103,37 +104,46 @@ public AmpHandler(AmpRequestFactory ampRequestFactory, ExchangeService exchangeS
}

@Override
public void handle(RoutingContext context) {
public void handle(RoutingContext routingContext) {
// Prebid Server interprets request.tmax to be the maximum amount of time that a caller is willing to wait
// for bids. However, tmax may be defined in the Stored Request data.
// If so, then the trip to the backend might use a significant amount of this time. We can respect timeouts
// more accurately if we note the real start time, and use it to compute the auction timeout.
final long startTime = clock.millis();

final boolean isSafari = HttpUtil.isSafari(context.request().headers().get(HttpUtil.USER_AGENT_HEADER));
final boolean isSafari = HttpUtil.isSafari(routingContext.request().headers().get(HttpUtil.USER_AGENT_HEADER));
metrics.updateSafariRequestsMetric(isSafari);

final UidsCookie uidsCookie = uidsCookieService.parseFromRequest(context);
final UidsCookie uidsCookie = uidsCookieService.parseFromRequest(routingContext);

final AmpEvent.AmpEventBuilder ampEventBuilder = AmpEvent.builder()
.httpContext(HttpContext.from(context));
.httpContext(HttpContext.from(routingContext));

ampRequestFactory.fromRequest(context)
ampRequestFactory.fromRequest(routingContext)
.map(bidRequest -> addToEvent(bidRequest, ampEventBuilder::bidRequest, bidRequest))
.map(bidRequest -> updateAppAndNoCookieAndImpsRequestedMetrics(bidRequest, uidsCookie, isSafari))
.compose(bidRequest ->
exchangeService.holdAuction(bidRequest, uidsCookie, timeout(bidRequest, startTime),
METRICS_CONTEXT, context)
.map(bidResponse -> Tuple2.of(bidRequest, bidResponse)))
.map((Tuple2<BidRequest, BidResponse> result) ->
addToEvent(result.getRight(), ampEventBuilder::bidResponse, result))
.map((Tuple2<BidRequest, BidResponse> result) -> Tuple3.of(result.getLeft(), result.getRight(),
toAmpResponse(result.getLeft(), result.getRight())))
.compose((Tuple3<BidRequest, BidResponse, AmpResponse> result) ->
ampResponsePostProcessor.postProcess(result.getLeft(), result.getMiddle(), result.getRight(),
context))

.map(bidRequest -> RequestContext.builder()
.routingContext(routingContext)
.uidsCookie(uidsCookie)
.bidRequest(bidRequest)
.timeout(timeout(bidRequest, startTime))
.metricsContext(METRICS_CONTEXT)
.build())

.compose(context ->
exchangeService.holdAuction(context)
.map(bidResponse -> Tuple2.of(bidResponse, context)))

.map(result -> addToEvent(result.getLeft(), ampEventBuilder::bidResponse, result))
.map(result -> Tuple3.of(result.getLeft(), result.getRight(),
toAmpResponse(result.getRight().getBidRequest(), result.getLeft())))
.compose(result ->
ampResponsePostProcessor.postProcess(result.getMiddle().getBidRequest(), result.getLeft(),
result.getRight(), routingContext))

.map(ampResponse -> addToEvent(ampResponse.getTargeting(), ampEventBuilder::targeting, ampResponse))
.setHandler(responseResult -> handleResult(responseResult, ampEventBuilder, context, startTime));
.setHandler(responseResult -> handleResult(responseResult, ampEventBuilder, routingContext, startTime));
}

private static <T, R> R addToEvent(T field, Consumer<T> consumer, R result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.prebid.server.auction.AuctionRequestFactory;
import org.prebid.server.auction.ExchangeService;
import org.prebid.server.auction.TimeoutResolver;
import org.prebid.server.auction.model.RequestContext;
import org.prebid.server.auction.model.Tuple2;
import org.prebid.server.cookie.UidsCookie;
import org.prebid.server.cookie.UidsCookieService;
Expand Down Expand Up @@ -61,32 +62,38 @@ public AuctionHandler(ExchangeService exchangeService, AuctionRequestFactory auc
}

@Override
public void handle(RoutingContext context) {
public void handle(RoutingContext routingContext) {
// Prebid Server interprets request.tmax to be the maximum amount of time that a caller is willing to wait
// for bids. However, tmax may be defined in the Stored Request data.
// If so, then the trip to the backend might use a significant amount of this time. We can respect timeouts
// more accurately if we note the real start time, and use it to compute the auction timeout.
final long startTime = clock.millis();

final boolean isSafari = HttpUtil.isSafari(context.request().headers().get(HttpUtil.USER_AGENT_HEADER));
final boolean isSafari = HttpUtil.isSafari(routingContext.request().headers().get(HttpUtil.USER_AGENT_HEADER));
metrics.updateSafariRequestsMetric(isSafari);

final UidsCookie uidsCookie = uidsCookieService.parseFromRequest(context);
final UidsCookie uidsCookie = uidsCookieService.parseFromRequest(routingContext);

final AuctionEvent.AuctionEventBuilder auctionEventBuilder = AuctionEvent.builder()
.httpContext(HttpContext.from(context));
.httpContext(HttpContext.from(routingContext));

auctionRequestFactory.fromRequest(context)
auctionRequestFactory.fromRequest(routingContext)
.map(bidRequest -> addToEvent(bidRequest, auctionEventBuilder::bidRequest, bidRequest))
.map(bidRequest -> updateAppAndNoCookieAndImpsRequestedMetrics(bidRequest, uidsCookie, isSafari))
.map(bidRequest -> Tuple2.of(bidRequest, toMetricsContext(bidRequest)))
.compose((Tuple2<BidRequest, MetricsContext> result) ->
exchangeService.holdAuction(result.getLeft(), uidsCookie, timeout(result.getLeft(), startTime),
result.getRight(), context)
.map(bidResponse -> Tuple2.of(bidResponse, result.getRight())))
.map((Tuple2<BidResponse, MetricsContext> result) ->
addToEvent(result.getLeft(), auctionEventBuilder::bidResponse, result))
.setHandler(responseResult -> handleResult(responseResult, auctionEventBuilder, context, startTime));

.map(bidRequest -> RequestContext.builder()
.routingContext(routingContext)
.uidsCookie(uidsCookie)
.bidRequest(bidRequest)
.timeout(timeout(bidRequest, startTime))
.metricsContext(toMetricsContext(bidRequest))
.build())

.compose(context -> exchangeService.holdAuction(context)
.map(bidResponse -> Tuple2.of(bidResponse, context)))

.map(result -> addToEvent(result.getLeft(), auctionEventBuilder::bidResponse, result))
.setHandler(result -> handleResult(result, auctionEventBuilder, routingContext, startTime));
}

private static <T, R> R addToEvent(T field, Consumer<T> consumer, R result) {
Expand All @@ -110,13 +117,13 @@ private Timeout timeout(BidRequest bidRequest, long startTime) {
return timeoutFactory.create(startTime, timeout);
}

private void handleResult(AsyncResult<Tuple2<BidResponse, MetricsContext>> responseResult,
private void handleResult(AsyncResult<Tuple2<BidResponse, RequestContext>> responseResult,
AuctionEvent.AuctionEventBuilder auctionEventBuilder, RoutingContext context,
long startTime) {
final boolean responseSucceeded = responseResult.succeeded();

final MetricName requestType = responseSucceeded
? responseResult.result().getRight().getRequestType()
? responseResult.result().getRight().getMetricsContext().getRequestType()
: MetricName.openrtb2web;

// don't send the response if client has gone
Expand Down
Loading

0 comments on commit 5f7c8b7

Please sign in to comment.