Skip to content

Commit 5ca717c

Browse files
committed
Refactor MediaTypeProcessor
1 parent 01acd95 commit 5ca717c

22 files changed

+1028
-690
lines changed

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

Lines changed: 33 additions & 66 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;
@@ -51,7 +50,6 @@
5150
import org.prebid.server.auction.versionconverter.OrtbVersion;
5251
import org.prebid.server.bidder.Bidder;
5352
import org.prebid.server.bidder.BidderCatalog;
54-
import org.prebid.server.bidder.BidderInfo;
5553
import org.prebid.server.bidder.HttpBidderRequester;
5654
import org.prebid.server.bidder.Usersyncer;
5755
import org.prebid.server.bidder.model.BidderBid;
@@ -144,7 +142,7 @@ public class ExchangeService {
144142
private final ImpAdjuster impAdjuster;
145143
private final SupplyChainResolver supplyChainResolver;
146144
private final DebugResolver debugResolver;
147-
private final MediaTypeProcessor mediaTypeProcessor;
145+
private final BidderRequestPostProcessor bidderRequestPostProcessor;
148146
private final UidUpdater uidUpdater;
149147
private final TimeoutResolver timeoutResolver;
150148
private final TimeoutFactory timeoutFactory;
@@ -171,7 +169,7 @@ public ExchangeService(double logSamplingRate,
171169
ImpAdjuster impAdjuster,
172170
SupplyChainResolver supplyChainResolver,
173171
DebugResolver debugResolver,
174-
MediaTypeProcessor mediaTypeProcessor,
172+
BidderRequestPostProcessor bidderRequestPostProcessor,
175173
UidUpdater uidUpdater,
176174
TimeoutResolver timeoutResolver,
177175
TimeoutFactory timeoutFactory,
@@ -198,7 +196,7 @@ public ExchangeService(double logSamplingRate,
198196
this.impAdjuster = Objects.requireNonNull(impAdjuster);
199197
this.supplyChainResolver = Objects.requireNonNull(supplyChainResolver);
200198
this.debugResolver = Objects.requireNonNull(debugResolver);
201-
this.mediaTypeProcessor = Objects.requireNonNull(mediaTypeProcessor);
199+
this.bidderRequestPostProcessor = Objects.requireNonNull(bidderRequestPostProcessor);
202200
this.uidUpdater = Objects.requireNonNull(uidUpdater);
203201
this.timeoutResolver = Objects.requireNonNull(timeoutResolver);
204202
this.timeoutFactory = Objects.requireNonNull(timeoutFactory);
@@ -435,7 +433,7 @@ private void removeInvalidBidRejectionTrackers(Map<String, BidRejectionTracker>
435433
BidderAliases aliases) {
436434

437435
final Set<String> bidderNames = new HashSet<>(bidRejectionTrackers.keySet());
438-
for (String bidder: bidderNames) {
436+
for (String bidder : bidderNames) {
439437
if (!isValidBidder(bidder, aliases)) {
440438
bidRejectionTrackers.remove(bidder);
441439
logger.warn("Pre-rejected impressions of the bidder {} have been removed. "
@@ -492,13 +490,12 @@ private Future<List<AuctionParticipation>> extractAuctionParticipations(
492490
.filter(bidder -> isBidderCallActivityAllowed(bidder, context))
493491
.distinct()
494492
.toList();
495-
final Map<String, Map<String, String>> impBidderToStoredBidResponse =
496-
storedResponseResult.getImpBidderToStoredBidResponse();
493+
497494
return makeAuctionParticipation(
498495
bidders,
499496
context,
500497
aliases,
501-
impBidderToStoredBidResponse,
498+
storedResponseResult.getImpBidderToStoredBidResponse(),
502499
imps,
503500
bidderToMultiBid);
504501
}
@@ -539,7 +536,7 @@ private Future<List<AuctionParticipation>> makeAuctionParticipation(
539536

540537
final BidRequest bidRequest = context.getBidRequest();
541538
final ExtRequest requestExt = bidRequest.getExt();
542-
final ExtRequestPrebid prebid = requestExt == null ? null : requestExt.getPrebid();
539+
final ExtRequestPrebid prebid = requestExt != null ? requestExt.getPrebid() : null;
543540
final Map<String, ExtBidderConfigOrtb> biddersToConfigs = getBiddersToConfigs(prebid);
544541
final Map<String, List<String>> eidPermissions = getEidPermissions(prebid);
545542
final Map<String, Pair<User, Device>> bidderToUserAndDevice =
@@ -1157,69 +1154,39 @@ private Future<BidderResponse> processAndRequestBids(AuctionContext auctionConte
11571154
Timeout timeout,
11581155
BidderAliases aliases) {
11591156

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

12151164
private static BidderSeatBid addWarnings(BidderSeatBid seatBid, List<BidderError> warnings) {
12161165
return CollectionUtils.isNotEmpty(warnings)
12171166
? seatBid.toBuilder()
1218-
.warnings(ListUtils.union(warnings, seatBid.getWarnings()))
1167+
.warnings(ListUtil.union(warnings, seatBid.getWarnings()))
12191168
.build()
12201169
: seatBid;
12211170
}
12221171

1172+
private static Future<BidderResponse> recoverBidderRequestRejection(AuctionContext auctionContext,
1173+
String bidderName,
1174+
Throwable throwable) {
1175+
1176+
if (throwable instanceof BidderRequestRejectedException rejection) {
1177+
auctionContext.getBidRejectionTrackers()
1178+
.get(bidderName)
1179+
.rejectAll(rejection.getRejectionReason());
1180+
final BidderSeatBid bidderSeatBid = BidderSeatBid.builder()
1181+
.warnings(rejection.getErrors())
1182+
.build();
1183+
1184+
return Future.succeededFuture(BidderResponse.of(bidderName, bidderSeatBid, 0));
1185+
}
1186+
1187+
return Future.failedFuture(throwable);
1188+
}
1189+
12231190
private Future<BidderResponse> invokeHooksAndRequestBids(AuctionContext auctionContext,
12241191
BidderRequest bidderRequest,
12251192
Timeout timeout,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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.bidder.model.Result;
10+
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
11+
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
12+
13+
import java.util.Collections;
14+
15+
public class BidderRequestCleaner implements BidderRequestPostProcessor {
16+
17+
@Override
18+
public Future<Result<BidderRequest>> process(BidderRequest bidderRequest,
19+
BidderAliases aliases,
20+
AuctionContext auctionContext) {
21+
22+
final BidRequest bidRequest = bidderRequest.getBidRequest();
23+
final ExtRequest ext = bidRequest.getExt();
24+
final ExtRequestPrebid extPrebid = ext != null ? ext.getPrebid() : null;
25+
final ObjectNode bidderControls = extPrebid != null ? extPrebid.getBiddercontrols() : null;
26+
27+
if (bidderControls == null) {
28+
return resultOf(bidderRequest);
29+
}
30+
31+
final ExtRequest cleanedExt = ExtRequest.of(extPrebid.toBuilder().biddercontrols(null).build());
32+
cleanedExt.addProperties(ext.getProperties());
33+
34+
return resultOf(bidderRequest.with(bidRequest.toBuilder().ext(cleanedExt).build()));
35+
}
36+
37+
private static Future<Result<BidderRequest>> resultOf(BidderRequest bidderRequest) {
38+
return Future.succeededFuture(Result.of(bidderRequest, Collections.emptyList()));
39+
}
40+
}
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+
import org.prebid.server.bidder.model.Result;
14+
15+
import java.util.Collections;
16+
import java.util.List;
17+
import java.util.Objects;
18+
import java.util.Optional;
19+
import java.util.Set;
20+
21+
public class BidderRequestCurrencyBlocker implements BidderRequestPostProcessor {
22+
23+
private final BidderCatalog bidderCatalog;
24+
25+
public BidderRequestCurrencyBlocker(BidderCatalog bidderCatalog) {
26+
this.bidderCatalog = Objects.requireNonNull(bidderCatalog);
27+
}
28+
29+
@Override
30+
public Future<Result<BidderRequest>> process(BidderRequest bidderRequest,
31+
BidderAliases aliases,
32+
AuctionContext auctionContext) {
33+
34+
if (isAcceptableCurrency(bidderRequest.getBidRequest(), aliases.resolveBidder(bidderRequest.getBidder()))) {
35+
return Future.succeededFuture(Result.of(bidderRequest, Collections.emptyList()));
36+
}
37+
38+
return Future.failedFuture(new BidderRequestRejectedException(
39+
BidRejectionReason.REQUEST_BLOCKED_UNACCEPTABLE_CURRENCY,
40+
List.of(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)