Skip to content

Commit ab462db

Browse files
committed
Merge branch 'refs/heads/master' into feature/extend-eid-permissions
# Conflicts: # src/test/java/org/prebid/server/auction/ExchangeServiceTest.java
2 parents e49d0ff + 39b8abe commit ab462db

55 files changed

Lines changed: 1700 additions & 1069 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/org/prebid/server/auction/ExchangeService.java

Lines changed: 32 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import io.vertx.core.CompositeFuture;
2020
import io.vertx.core.Future;
2121
import org.apache.commons.collections4.CollectionUtils;
22-
import org.apache.commons.collections4.ListUtils;
2322
import org.apache.commons.collections4.map.CaseInsensitiveMap;
2423
import org.apache.commons.lang3.ObjectUtils;
2524
import org.apache.commons.lang3.StringUtils;
@@ -32,9 +31,9 @@
3231
import org.prebid.server.activity.infrastructure.payload.impl.BidRequestActivityInvocationPayload;
3332
import org.prebid.server.auction.aliases.AlternateBidderCodesConfig;
3433
import org.prebid.server.auction.aliases.BidderAliases;
34+
import org.prebid.server.auction.bidderrequestpostprocessor.BidderRequestPostProcessor;
35+
import org.prebid.server.auction.bidderrequestpostprocessor.BidderRequestRejectedException;
3536
import org.prebid.server.auction.externalortb.StoredResponseProcessor;
36-
import org.prebid.server.auction.mediatypeprocessor.MediaTypeProcessingResult;
37-
import org.prebid.server.auction.mediatypeprocessor.MediaTypeProcessor;
3837
import org.prebid.server.auction.model.AuctionContext;
3938
import org.prebid.server.auction.model.AuctionParticipation;
4039
import org.prebid.server.auction.model.BidRejectionReason;
@@ -52,7 +51,6 @@
5251
import org.prebid.server.auction.versionconverter.OrtbVersion;
5352
import org.prebid.server.bidder.Bidder;
5453
import org.prebid.server.bidder.BidderCatalog;
55-
import org.prebid.server.bidder.BidderInfo;
5654
import org.prebid.server.bidder.HttpBidderRequester;
5755
import org.prebid.server.bidder.Usersyncer;
5856
import org.prebid.server.bidder.model.BidderBid;
@@ -143,7 +141,7 @@ public class ExchangeService {
143141
private final ImpAdjuster impAdjuster;
144142
private final SupplyChainResolver supplyChainResolver;
145143
private final DebugResolver debugResolver;
146-
private final MediaTypeProcessor mediaTypeProcessor;
144+
private final BidderRequestPostProcessor bidderRequestPostProcessor;
147145
private final UidUpdater uidUpdater;
148146
private final TimeoutResolver timeoutResolver;
149147
private final TimeoutFactory timeoutFactory;
@@ -170,7 +168,7 @@ public ExchangeService(double logSamplingRate,
170168
ImpAdjuster impAdjuster,
171169
SupplyChainResolver supplyChainResolver,
172170
DebugResolver debugResolver,
173-
MediaTypeProcessor mediaTypeProcessor,
171+
BidderRequestPostProcessor bidderRequestPostProcessor,
174172
UidUpdater uidUpdater,
175173
TimeoutResolver timeoutResolver,
176174
TimeoutFactory timeoutFactory,
@@ -197,7 +195,7 @@ public ExchangeService(double logSamplingRate,
197195
this.impAdjuster = Objects.requireNonNull(impAdjuster);
198196
this.supplyChainResolver = Objects.requireNonNull(supplyChainResolver);
199197
this.debugResolver = Objects.requireNonNull(debugResolver);
200-
this.mediaTypeProcessor = Objects.requireNonNull(mediaTypeProcessor);
198+
this.bidderRequestPostProcessor = Objects.requireNonNull(bidderRequestPostProcessor);
201199
this.uidUpdater = Objects.requireNonNull(uidUpdater);
202200
this.timeoutResolver = Objects.requireNonNull(timeoutResolver);
203201
this.timeoutFactory = Objects.requireNonNull(timeoutFactory);
@@ -491,13 +489,12 @@ private Future<List<AuctionParticipation>> extractAuctionParticipations(
491489
.filter(bidder -> isBidderCallActivityAllowed(bidder, context))
492490
.distinct()
493491
.toList();
494-
final Map<String, Map<String, String>> impBidderToStoredBidResponse =
495-
storedResponseResult.getImpBidderToStoredBidResponse();
492+
496493
return makeAuctionParticipation(
497494
bidders,
498495
context,
499496
aliases,
500-
impBidderToStoredBidResponse,
497+
storedResponseResult.getImpBidderToStoredBidResponse(),
501498
imps,
502499
bidderToMultiBid);
503500
}
@@ -538,7 +535,7 @@ private Future<List<AuctionParticipation>> makeAuctionParticipation(
538535

539536
final BidRequest bidRequest = context.getBidRequest();
540537
final ExtRequest requestExt = bidRequest.getExt();
541-
final ExtRequestPrebid prebid = requestExt == null ? null : requestExt.getPrebid();
538+
final ExtRequestPrebid prebid = requestExt != null ? requestExt.getPrebid() : null;
542539
final Map<String, ExtBidderConfigOrtb> biddersToConfigs = getBiddersToConfigs(prebid);
543540
final EidPermissionHolder eidPermissionHolder = getEidPermissions(prebid);
544541
final Map<String, Pair<User, Device>> bidderToUserAndDevice =
@@ -1154,69 +1151,39 @@ private Future<BidderResponse> processAndRequestBids(AuctionContext auctionConte
11541151
Timeout timeout,
11551152
BidderAliases aliases) {
11561153

1157-
final String bidderName = bidderRequest.getBidder();
1158-
final MediaTypeProcessingResult mediaTypeProcessingResult = mediaTypeProcessor.process(
1159-
bidderRequest.getBidRequest(), bidderName, aliases, auctionContext.getAccount());
1160-
final List<BidderError> mediaTypeProcessingErrors = mediaTypeProcessingResult.getErrors();
1161-
if (mediaTypeProcessingResult.isRejected()) {
1162-
return processReject(
1163-
auctionContext,
1164-
BidRejectionReason.REQUEST_BLOCKED_UNSUPPORTED_MEDIA_TYPE,
1165-
mediaTypeProcessingErrors,
1166-
bidderName);
1167-
}
1168-
if (isUnacceptableCurrency(auctionContext, aliases.resolveBidder(bidderName))) {
1169-
return processReject(
1170-
auctionContext,
1171-
BidRejectionReason.REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY,
1172-
List.of(BidderError.generic("No match between the configured currencies and bidRequest.cur")),
1173-
bidderName);
1174-
}
1175-
1176-
return Future.succeededFuture(mediaTypeProcessingResult.getBidRequest())
1177-
.map(bidderRequest::with)
1178-
.compose(modifiedBidderRequest -> invokeHooksAndRequestBids(
1179-
auctionContext, modifiedBidderRequest, timeout, aliases))
1180-
.map(bidderResponse -> bidderResponse.with(
1181-
addWarnings(bidderResponse.getSeatBid(), mediaTypeProcessingErrors)));
1182-
}
1183-
1184-
private boolean isUnacceptableCurrency(AuctionContext auctionContext, String originalBidderName) {
1185-
final List<String> requestCurrencies = auctionContext.getBidRequest().getCur();
1186-
final List<String> bidAcceptableCurrencies =
1187-
Optional.ofNullable(bidderCatalog.bidderInfoByName(originalBidderName))
1188-
.map(BidderInfo::getCurrencyAccepted)
1189-
.orElse(null);
1190-
1191-
if (CollectionUtils.isEmpty(requestCurrencies) || CollectionUtils.isEmpty(bidAcceptableCurrencies)) {
1192-
return false;
1193-
}
1194-
1195-
return !CollectionUtils.containsAny(requestCurrencies, bidAcceptableCurrencies);
1196-
}
1197-
1198-
private static Future<BidderResponse> processReject(AuctionContext auctionContext,
1199-
BidRejectionReason bidRejectionReason,
1200-
List<BidderError> warnings,
1201-
String bidderName) {
1202-
1203-
auctionContext.getBidRejectionTrackers()
1204-
.get(bidderName)
1205-
.rejectAll(bidRejectionReason);
1206-
final BidderSeatBid bidderSeatBid = BidderSeatBid.builder()
1207-
.warnings(warnings)
1208-
.build();
1209-
return Future.succeededFuture(BidderResponse.of(bidderName, bidderSeatBid, 0));
1154+
return bidderRequestPostProcessor.process(bidderRequest, aliases, auctionContext)
1155+
.compose(result -> invokeHooksAndRequestBids(auctionContext, result.getValue(), timeout, aliases)
1156+
.map(response -> response.with(addWarnings(response.getSeatBid(), result.getErrors()))))
1157+
.recover(throwable -> recoverBidderRequestRejection(
1158+
auctionContext, bidderRequest.getBidder(), throwable));
12101159
}
12111160

12121161
private static BidderSeatBid addWarnings(BidderSeatBid seatBid, List<BidderError> warnings) {
12131162
return CollectionUtils.isNotEmpty(warnings)
12141163
? seatBid.toBuilder()
1215-
.warnings(ListUtils.union(warnings, seatBid.getWarnings()))
1164+
.warnings(ListUtil.union(warnings, seatBid.getWarnings()))
12161165
.build()
12171166
: seatBid;
12181167
}
12191168

1169+
private static Future<BidderResponse> recoverBidderRequestRejection(AuctionContext auctionContext,
1170+
String bidderName,
1171+
Throwable throwable) {
1172+
1173+
if (throwable instanceof BidderRequestRejectedException rejection) {
1174+
auctionContext.getBidRejectionTrackers()
1175+
.get(bidderName)
1176+
.rejectAll(rejection.getRejectionReason());
1177+
final BidderSeatBid bidderSeatBid = BidderSeatBid.builder()
1178+
.warnings(rejection.getErrors())
1179+
.build();
1180+
1181+
return Future.succeededFuture(BidderResponse.of(bidderName, bidderSeatBid, 0));
1182+
}
1183+
1184+
return Future.failedFuture(throwable);
1185+
}
1186+
12201187
private Future<BidderResponse> invokeHooksAndRequestBids(AuctionContext auctionContext,
12211188
BidderRequest bidderRequest,
12221189
Timeout timeout,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.prebid.server.auction.bidderrequestpostprocessor;
2+
3+
import com.fasterxml.jackson.databind.node.ObjectNode;
4+
import com.iab.openrtb.request.BidRequest;
5+
import io.vertx.core.Future;
6+
import org.prebid.server.auction.aliases.BidderAliases;
7+
import org.prebid.server.auction.model.AuctionContext;
8+
import org.prebid.server.auction.model.BidderRequest;
9+
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
10+
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
11+
12+
public class BidderRequestCleaner implements BidderRequestPostProcessor {
13+
14+
@Override
15+
public Future<BidderRequestPostProcessingResult> process(BidderRequest bidderRequest,
16+
BidderAliases aliases,
17+
AuctionContext auctionContext) {
18+
19+
final BidRequest bidRequest = bidderRequest.getBidRequest();
20+
final ExtRequest ext = bidRequest.getExt();
21+
final ExtRequestPrebid extPrebid = ext != null ? ext.getPrebid() : null;
22+
final ObjectNode bidderControls = extPrebid != null ? extPrebid.getBiddercontrols() : null;
23+
24+
if (bidderControls == null) {
25+
return resultOf(bidderRequest);
26+
}
27+
28+
final ExtRequest cleanedExt = ExtRequest.of(extPrebid.toBuilder().biddercontrols(null).build());
29+
cleanedExt.addProperties(ext.getProperties());
30+
31+
return resultOf(bidderRequest.with(bidRequest.toBuilder().ext(cleanedExt).build()));
32+
}
33+
34+
private static Future<BidderRequestPostProcessingResult> resultOf(BidderRequest bidderRequest) {
35+
return Future.succeededFuture(BidderRequestPostProcessingResult.withValue(bidderRequest));
36+
}
37+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.prebid.server.auction.bidderrequestpostprocessor;
2+
3+
import com.iab.openrtb.request.BidRequest;
4+
import io.vertx.core.Future;
5+
import org.apache.commons.collections4.CollectionUtils;
6+
import org.prebid.server.auction.aliases.BidderAliases;
7+
import org.prebid.server.auction.model.AuctionContext;
8+
import org.prebid.server.auction.model.BidRejectionReason;
9+
import org.prebid.server.auction.model.BidderRequest;
10+
import org.prebid.server.bidder.BidderCatalog;
11+
import org.prebid.server.bidder.BidderInfo;
12+
import org.prebid.server.bidder.model.BidderError;
13+
14+
import java.util.Collections;
15+
import java.util.List;
16+
import java.util.Objects;
17+
import java.util.Optional;
18+
import java.util.Set;
19+
20+
public class BidderRequestCurrencyBlocker implements BidderRequestPostProcessor {
21+
22+
private final BidderCatalog bidderCatalog;
23+
24+
public BidderRequestCurrencyBlocker(BidderCatalog bidderCatalog) {
25+
this.bidderCatalog = Objects.requireNonNull(bidderCatalog);
26+
}
27+
28+
@Override
29+
public Future<BidderRequestPostProcessingResult> process(BidderRequest bidderRequest,
30+
BidderAliases aliases,
31+
AuctionContext auctionContext) {
32+
33+
if (isAcceptableCurrency(bidderRequest.getBidRequest(), aliases.resolveBidder(bidderRequest.getBidder()))) {
34+
return Future.succeededFuture(BidderRequestPostProcessingResult.withValue(bidderRequest));
35+
}
36+
37+
return Future.failedFuture(new BidderRequestRejectedException(
38+
BidRejectionReason.REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY,
39+
Collections.singletonList(
40+
BidderError.generic("No match between the configured currencies and bidRequest.cur"))));
41+
}
42+
43+
private boolean isAcceptableCurrency(BidRequest bidRequest, String originalBidderName) {
44+
final List<String> requestCurrencies = bidRequest.getCur();
45+
final Set<String> bidAcceptableCurrencies =
46+
Optional.ofNullable(bidderCatalog.bidderInfoByName(originalBidderName))
47+
.map(BidderInfo::getCurrencyAccepted)
48+
.orElse(null);
49+
50+
return CollectionUtils.isEmpty(requestCurrencies)
51+
|| CollectionUtils.isEmpty(bidAcceptableCurrencies)
52+
|| requestCurrencies.stream().anyMatch(bidAcceptableCurrencies::contains);
53+
}
54+
}

0 commit comments

Comments
 (0)