Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/config-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ There are several typical keys:
- `adapters.<BIDDER_NAME>.usersync.type` - usersync type (i.e. redirect, iframe).
- `adapters.<BIDDER_NAME>.usersync.support-cors` - flag signals if CORS supported by usersync.
- `adapters.<BIDDER_NAME>.debug.allow` - enables debug output in the auction response for the given bidder. Default `true`.
- `adapters.<BIDDER_NAME>.tmax-deduction-ms` - adjusts the tmax sent to the bidder by deducting the provided value (ms). Default `0 ms` - no deduction.

In addition, each bidder could have arbitrary aliases configured that will look and act very much the same as the bidder itself.
Aliases are configured by adding child configuration object at `adapters.<BIDDER_NAME>.aliases.<BIDDER_ALIAS>.`, aliases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ private static BidderInfo bidderInfo(OrtbVersion ortbVersion) {
false,
false,
null,
Ortb.of(false));
Ortb.of(false),
0L);
}

private static BidRequest emptyRequest() {
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,7 @@ private Future<BidderResponse> requestBids(BidderRequest bidderRequest,
final String bidderName = bidderRequest.getBidder();
final String resolvedBidderName = aliases.resolveBidder(bidderName);
final Bidder<?> bidder = bidderCatalog.bidderByName(resolvedBidderName);
final long bidderTmaxDeductionMs = bidderCatalog.bidderInfoByName(resolvedBidderName).getTmaxDeductionMs();
final BidRejectionTracker bidRejectionTracker = auctionContext.getBidRejectionTrackers().get(bidderName);

final TimeoutContext timeoutContext = auctionContext.getTimeoutContext();
Expand All @@ -1225,7 +1226,8 @@ private Future<BidderResponse> requestBids(BidderRequest bidderRequest,
final long bidderRequestStartTime = clock.millis();

return Future.succeededFuture(bidderRequest.getBidRequest())
.map(bidRequest -> adjustTmax(bidRequest, auctionStartTime, adjustmentFactor, bidderRequestStartTime))
.map(bidRequest -> adjustTmax(
bidRequest, auctionStartTime, adjustmentFactor, bidderRequestStartTime, bidderTmaxDeductionMs))
.map(bidRequest -> ortbVersionConversionManager.convertFromAuctionSupportedVersion(
bidRequest, bidderRequest.getOrtbVersion()))
.map(bidderRequest::with)
Expand All @@ -1240,9 +1242,16 @@ private Future<BidderResponse> requestBids(BidderRequest bidderRequest,
.map(seatBid -> BidderResponse.of(bidderName, seatBid, responseTime(bidderRequestStartTime)));
}

private BidRequest adjustTmax(BidRequest bidRequest, long startTime, int adjustmentFactor, long currentTime) {
private BidRequest adjustTmax(BidRequest bidRequest,
long startTime,
int adjustmentFactor,
long currentTime,
long bidderTmaxDeductionMs) {

final long tmax = timeoutResolver.limitToMax(bidRequest.getTmax());
final long adjustedTmax = timeoutResolver.adjustForBidder(tmax, adjustmentFactor, currentTime - startTime);
final long adjustedTmax = timeoutResolver.adjustForBidder(
tmax, adjustmentFactor, currentTime - startTime, bidderTmaxDeductionMs);

return tmax != adjustedTmax
? bidRequest.toBuilder().tmax(adjustedTmax).build()
: bidRequest;
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/prebid/server/auction/TimeoutResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ public long limitToMax(Long timeout) {
: Math.min(timeout, maxTimeout);
}

public long adjustForBidder(long timeout, int adjustFactor, long spentTime) {
return adjustWithFactor(timeout, adjustFactor / 100.0, spentTime);
public long adjustForBidder(long timeout, int adjustFactor, long spentTime, long bidderTmaxDeductionMs) {
return adjustWithFactor(timeout, adjustFactor / 100.0, spentTime, bidderTmaxDeductionMs);
}

public long adjustForRequest(long timeout, long spentTime) {
return adjustWithFactor(timeout, 1.0, spentTime);
return adjustWithFactor(timeout, 1.0, spentTime, 0L);
}

private long adjustWithFactor(long timeout, double adjustFactor, long spentTime) {
return limitToMin((long) (timeout * adjustFactor) - spentTime - upstreamResponseTime);
private long adjustWithFactor(long timeout, double adjustFactor, long spentTime, long deductionTime) {
return limitToMin((long) (timeout * adjustFactor) - spentTime - deductionTime - upstreamResponseTime);
}

private long limitToMin(long timeout) {
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/prebid/server/bidder/BidderInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class BidderInfo {

Ortb ortb;

long tmaxDeductionMs;

public static BidderInfo create(boolean enabled,
OrtbVersion ortbVersion,
boolean debugAllowed,
Expand All @@ -55,7 +57,8 @@ public static BidderInfo create(boolean enabled,
boolean ccpaEnforced,
boolean modifyingVastXmlAllowed,
CompressionType compressionType,
org.prebid.server.spring.config.bidder.model.Ortb ortb) {
org.prebid.server.spring.config.bidder.model.Ortb ortb,
long tmaxDeductionMs) {

return of(
enabled,
Expand All @@ -74,7 +77,8 @@ public static BidderInfo create(boolean enabled,
ccpaEnforced,
modifyingVastXmlAllowed,
compressionType,
Ortb.of(ortb.getMultiFormatSupported()));
Ortb.of(ortb.getMultiFormatSupported()),
tmaxDeductionMs);
}

private static PlatformInfo platformInfo(List<MediaType> mediaTypes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class BidderConfigurationProperties {

private Ortb ortb;

private long tmaxDeductionMs;

private final Class<? extends BidderConfigurationProperties> selfClass;

public BidderConfigurationProperties() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static BidderInfo create(BidderConfigurationProperties configurationPrope
configurationProperties.getPbsEnforcesCcpa(),
configurationProperties.getModifyingVastXmlAllowed(),
configurationProperties.getEndpointCompression(),
configurationProperties.getOrtb());
configurationProperties.getOrtb(),
configurationProperties.getTmaxDeductionMs());
}
}
37 changes: 29 additions & 8 deletions src/test/java/org/prebid/server/auction/ExchangeServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ public void setUp() {
false,
false,
CompressionType.NONE,
Ortb.of(false)));
Ortb.of(false),
0L));

given(privacyEnforcementService.mask(any(), argThat(MapUtils::isNotEmpty), any()))
.willAnswer(inv ->
Expand Down Expand Up @@ -381,7 +382,7 @@ public void setUp() {
given(criteriaLogManager.traceResponse(any(), any(), any(), anyBoolean()))
.willAnswer(inv -> inv.getArgument(1));

given(timeoutResolver.adjustForBidder(anyLong(), anyInt(), anyLong()))
given(timeoutResolver.adjustForBidder(anyLong(), anyInt(), anyLong(), anyLong()))
.willAnswer(invocation -> invocation.getArgument(0));

given(timeoutResolver.adjustForRequest(anyLong(), anyLong()))
Expand Down Expand Up @@ -3774,7 +3775,9 @@ public void shouldResponseWithEmptySeatBidIfBidderNotSupportRequestCurrency() {
false,
false,
CompressionType.NONE,
Ortb.of(false)));
Ortb.of(false),
0L));

given(bidResponseCreator.create(
argThat(argument -> argument.getAuctionParticipations().getFirst()
.getBidderResponse()
Expand Down Expand Up @@ -3837,17 +3840,35 @@ public void shouldConvertBidRequestOpenRTBVersionToConfiguredByBidder() {
@Test
public void shouldPassAdjustedTimeoutToAdapterAndToBidResponseCreator() {
// given
given(timeoutResolver.adjustForBidder(anyLong(), eq(90), anyLong()))
.willReturn(400L);
given(timeoutResolver.adjustForRequest(anyLong(), anyLong()))
.willReturn(450L);
given(bidderCatalog.bidderInfoByName(anyString())).willReturn(BidderInfo.create(
true,
null,
false,
null,
null,
null,
null,
null,
null,
null,
0,
null,
false,
false,
CompressionType.NONE,
Ortb.of(false),
100L));

given(timeoutResolver.adjustForBidder(anyLong(), eq(90), eq(200L), eq(100L))).willReturn(400L);
given(timeoutResolver.adjustForRequest(anyLong(), eq(200L))).willReturn(450L);

final BidRequest bidRequest = givenBidRequest(
givenSingleImp(singletonMap("bidderName", 1)),
request -> request.source(Source.builder().tid("uniqTid").build()));

// when
target.holdAuction(givenRequestContext(bidRequest));
target.holdAuction(givenRequestContext(bidRequest).toBuilder()
.timeoutContext(TimeoutContext.of(clock.millis() - 200L, timeout, 90)).build());

// then
final ArgumentCaptor<BidderRequest> bidderRequestCaptor = ArgumentCaptor.forClass(BidderRequest.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ public void limitToMaxShouldReturnMaxTimeout() {

@Test
public void adjustForBidderShouldReturnExpectedResult() {
assertThat(timeoutResolver.adjustForBidder(200L, 70, 10L)).isEqualTo(120L);
assertThat(timeoutResolver.adjustForBidder(300L, 70, 10L, 50L)).isEqualTo(140L);
}

@Test
public void adjustForBidderShouldReturnMinTimeout() {
assertThat(timeoutResolver.adjustForBidder(200L, 50, 10L)).isEqualTo(MIN_TIMEOUT);
assertThat(timeoutResolver.adjustForBidder(200L, 50, 10L, 100L)).isEqualTo(MIN_TIMEOUT);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ private static BidderInfo givenBidderInfo(List<MediaType> appMediaTypes,
false,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);
}

private static BidRequest givenBidRequest(UnaryOperator<BidRequest.BidRequestBuilder> bidRequestCustomizer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ private static BidderInfo givenBidderInfo(boolean multiFormatSupported) {
false,
false,
CompressionType.NONE,
Ortb.of(multiFormatSupported));
Ortb.of(multiFormatSupported),
0L);
}

private static BidRequest givenBidRequest(UnaryOperator<BidRequest.BidRequestBuilder> bidRequestCustomizer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public void setUp() {
true,
false,
null,
Ortb.of(false)));
Ortb.of(false),
0L));

target = new CcpaEnforcement(userFpdCcpaMask, bidderCatalog, metrics, true);

Expand Down Expand Up @@ -222,7 +223,8 @@ public void enforceShouldSkipNoSaleBiddersAndNotEnforcedByBidderConfig() {
false,
false,
null,
Ortb.of(false)));
Ortb.of(false),
0L));

final AuctionContext auctionContext = givenAuctionContext(identity());

Expand Down
24 changes: 16 additions & 8 deletions src/test/java/org/prebid/server/bidder/BidderCatalogTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public void metaInfoByNameShouldReturnMetaInfoForKnownBidderIgnoringCase() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderDeps bidderDeps = BidderDeps.of(singletonList(BidderInstanceDeps.builder()
.name("BIDder")
Expand Down Expand Up @@ -132,7 +133,8 @@ public void isAliasShouldReturnTrueForAliasIgnoringCase() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderInstanceDeps bidderInstanceDeps = BidderInstanceDeps.builder()
.name("BIDder")
Expand All @@ -156,7 +158,8 @@ public void isAliasShouldReturnTrueForAliasIgnoringCase() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderInstanceDeps aliasInstanceDeps = BidderInstanceDeps.builder()
.name("ALIas")
Expand Down Expand Up @@ -193,7 +196,8 @@ public void resolveBaseBidderShouldReturnBaseBidderName() {
true,
false,
CompressionType.NONE,
Ortb.of(false)))
Ortb.of(false),
0L))
.deprecatedNames(emptyList())
.build()));
target = new BidderCatalog(singletonList(bidderDeps));
Expand Down Expand Up @@ -260,7 +264,8 @@ public void usersyncReadyBiddersShouldReturnBiddersThatCanSync() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderInfo infoOfBidderWithoutUsersyncConfig = BidderInfo.create(
true,
Expand All @@ -278,7 +283,8 @@ public void usersyncReadyBiddersShouldReturnBiddersThatCanSync() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderInfo infoOfDisabledBidderWithUsersyncConfig = BidderInfo.create(
false,
Expand All @@ -296,7 +302,8 @@ public void usersyncReadyBiddersShouldReturnBiddersThatCanSync() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final List<BidderDeps> bidderDeps = List.of(
BidderDeps.of(singletonList(BidderInstanceDeps.builder()
Expand Down Expand Up @@ -365,7 +372,8 @@ public void nameByVendorIdShouldReturnBidderNameForVendorId() {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);

final BidderDeps bidderDeps = BidderDeps.of(singletonList(BidderInstanceDeps.builder()
.name("BIDder")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ public void shouldAddContentEncodingHeaderIfRequiredByBidderConfig() {
false,
false,
CompressionType.GZIP,
Ortb.of(false)));
Ortb.of(false),
0L));

final CaseInsensitiveMultiMap originalHeaders = CaseInsensitiveMultiMap.builder().build();

Expand Down Expand Up @@ -212,7 +213,8 @@ public void shouldAddContentEncodingHeaderIfRequiredByBidderAliasConfig() {
false,
false,
CompressionType.GZIP,
Ortb.of(false)));
Ortb.of(false),
0L));

final CaseInsensitiveMultiMap originalHeaders = CaseInsensitiveMultiMap.builder().build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ private static BidderInfo givenBidderInfo(boolean enabled, String endpoint, Stri
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);
}

private static BidderInfo givenBidderInfo() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ private static BidderInfo givenBidderInfo(String aliasOf) {
true,
false,
CompressionType.NONE,
Ortb.of(false));
Ortb.of(false),
0L);
}

private static BidderInfo givenBidderInfo() {
Expand Down
Loading