Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Bidder Codes #3799

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
28 changes: 18 additions & 10 deletions src/main/java/org/prebid/server/auction/BidResponseCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,15 @@ private List<BidderResponseInfo> toBidderResponseInfos(CategoryMappingResult cat
final BidderSeatBid seatBid = bidderResponse.getSeatBid();

for (final BidderBid bidderBid : seatBid.getBids()) {
final Bid bid = bidderBid.getBid();
final BidType type = bidderBid.getType();
final BidInfo bidInfo = toBidInfo(bid, type, imps, bidder, categoryMappingResult, cacheInfo, account);
final BidInfo bidInfo = toBidInfo(
bidderBid.getBid(),
bidderBid.getType(),
bidderBid.getSeat(),
imps,
bidder,
categoryMappingResult,
cacheInfo,
account);
bidInfos.add(bidInfo);
}

Expand All @@ -453,6 +459,7 @@ private List<BidderResponseInfo> toBidderResponseInfos(CategoryMappingResult cat

private BidInfo toBidInfo(Bid bid,
BidType type,
String seat,
List<Imp> imps,
String bidder,
CategoryMappingResult categoryMappingResult,
Expand All @@ -464,6 +471,7 @@ private BidInfo toBidInfo(Bid bid,
.bid(bid)
.bidType(type)
.bidder(bidder)
.seat(seat)
.correspondingImp(correspondingImp)
.ttl(resolveTtl(bid, type, correspondingImp, cacheInfo, account))
.vastTtl(type == BidType.video ? resolveVastTtl(bid, correspondingImp, cacheInfo, account) : null)
Expand Down Expand Up @@ -1429,12 +1437,6 @@ private SeatBid toSeatBid(List<BidInfo> bidInfos,
Map<String, List<ExtBidderError>> bidErrors,
Map<String, List<ExtBidderError>> bidWarnings) {

final String bidder = bidInfos.stream()
.map(BidInfo::getBidder)
.findFirst()
// Should never occur
.orElseThrow(() -> new IllegalArgumentException("Bidder was not defined for bidInfo"));

final List<Bid> bids = bidInfos.stream()
.map(bidInfo -> injectAdmWithCacheInfo(
bidInfo,
Expand All @@ -1451,8 +1453,14 @@ private SeatBid toSeatBid(List<BidInfo> bidInfos,
.filter(Objects::nonNull)
.toList();

final String seat = bidInfos.stream()
.map(BidInfo::getSeat)
.findFirst()
// Should never occur
.orElseThrow(() -> new IllegalArgumentException("BidderCode was not defined for bidInfo"));

return SeatBid.builder()
.seat(bidder)
.seat(seat)
.bid(bids)
.group(0) // prebid cannot support roadblocking
.build();
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/org/prebid/server/auction/BidsAdjuster.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.prebid.server.bidder.model.BidderError;
import org.prebid.server.bidder.model.BidderSeatBid;
import org.prebid.server.floors.PriceFloorEnforcer;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidAlternateBidderCodes;
import org.prebid.server.util.ObjectUtil;
import org.prebid.server.validation.ResponseBidValidator;
import org.prebid.server.validation.model.ValidationResult;
Expand Down Expand Up @@ -40,10 +41,15 @@ public BidsAdjuster(ResponseBidValidator responseBidValidator,

public List<AuctionParticipation> validateAndAdjustBids(List<AuctionParticipation> auctionParticipations,
AuctionContext auctionContext,
BidderAliases aliases) {
BidderAliases aliases,
ExtRequestPrebidAlternateBidderCodes alternateBidderCodes) {

return auctionParticipations.stream()
.map(auctionParticipation -> validBidderResponse(auctionParticipation, auctionContext, aliases))
.map(auctionParticipation -> validBidderResponse(
auctionParticipation,
auctionContext,
aliases,
alternateBidderCodes))

.map(auctionParticipation -> bidAdjustmentsProcessor.enrichWithAdjustedBids(
auctionParticipation,
Expand All @@ -65,7 +71,8 @@ public List<AuctionParticipation> validateAndAdjustBids(List<AuctionParticipatio

private AuctionParticipation validBidderResponse(AuctionParticipation auctionParticipation,
AuctionContext auctionContext,
BidderAliases aliases) {
BidderAliases aliases,
ExtRequestPrebidAlternateBidderCodes alternateBidderCodes) {

if (auctionParticipation.isRequestBlocked()) {
return auctionParticipation;
Expand All @@ -92,7 +99,8 @@ private AuctionParticipation validBidderResponse(AuctionParticipation auctionPar
bid,
bidderResponse.getBidder(),
auctionContext,
aliases);
aliases,
alternateBidderCodes);

if (validationResult.hasWarnings() || validationResult.hasErrors()) {
errors.add(makeValidationBidderError(bid.getBid(), validationResult));
Expand Down
68 changes: 66 additions & 2 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.server.auction;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iab.openrtb.request.App;
Expand Down Expand Up @@ -73,12 +74,14 @@
import org.prebid.server.metric.Metrics;
import org.prebid.server.model.CaseInsensitiveMultiMap;
import org.prebid.server.model.UpdateResult;
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
import org.prebid.server.proto.openrtb.ext.ExtPrebidBidders;
import org.prebid.server.proto.openrtb.ext.request.ExtApp;
import org.prebid.server.proto.openrtb.ext.request.ExtBidderConfigOrtb;
import org.prebid.server.proto.openrtb.ext.request.ExtDooh;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidAlternateBidderCodes;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidBidderConfig;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidCache;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidData;
Expand All @@ -88,6 +91,8 @@
import org.prebid.server.proto.openrtb.ext.request.ExtRequestTargeting;
import org.prebid.server.proto.openrtb.ext.request.ExtSite;
import org.prebid.server.proto.openrtb.ext.request.ExtUser;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta;
import org.prebid.server.settings.model.Account;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.util.ListUtil;
Expand Down Expand Up @@ -124,6 +129,9 @@ public class ExchangeService {
private static final BigDecimal THOUSAND = BigDecimal.valueOf(1000);
private static final Set<String> BIDDER_FIELDS_EXCEPTION_LIST = Set.of(
"adunitcode", "storedrequest", "options", "is_rewarded_inventory");
private static final TypeReference<ExtPrebid<ExtBidPrebid, ObjectNode>> EXT_PREBID_TYPE_REFERENCE =
new TypeReference<>() {
};

private final double logSamplingRate;
private final BidderCatalog bidderCatalog;
Expand Down Expand Up @@ -238,6 +246,8 @@ private Future<AuctionContext> runAuction(AuctionContext receivedContext) {
final Map<String, MultiBidConfig> bidderToMultiBid = bidderToMultiBids(bidRequest, debugWarnings);
receivedContext.getBidRejectionTrackers().putAll(makeBidRejectionTrackers(bidRequest, aliases));

final ExtRequestPrebidAlternateBidderCodes alternateBidderCodes = getAlternateBidderCodes(bidRequest, account);

final boolean debugEnabled = receivedContext.getDebugContext().isDebugEnabled();
metrics.updateDebugRequestMetrics(debugEnabled);
metrics.updateAccountDebugRequestMetrics(account, debugEnabled);
Expand Down Expand Up @@ -268,8 +278,11 @@ private Future<AuctionContext> runAuction(AuctionContext receivedContext) {
context.getBidRejectionTrackers()))
.map(auctionParticipations -> dropZeroNonDealBids(
auctionParticipations, debugWarnings, debugEnabled))
.map(auctionParticipations ->
bidsAdjuster.validateAndAdjustBids(auctionParticipations, context, aliases))
.map(auctionParticipations -> bidsAdjuster.validateAndAdjustBids(
auctionParticipations,
context,
aliases,
alternateBidderCodes))
.map(auctionParticipations -> updateResponsesMetrics(auctionParticipations, account, aliases))
.map(context::with))
// produce response from bidder results
Expand All @@ -291,6 +304,15 @@ private BidderAliases aliases(BidRequest bidRequest) {
return BidderAliases.of(aliases, aliasgvlids, bidderCatalog);
}

private static ExtRequestPrebidAlternateBidderCodes getAlternateBidderCodes(BidRequest bidRequest,
Account account) {

return Optional.ofNullable(bidRequest.getExt())
.map(ExtRequest::getPrebid)
.map(ExtRequestPrebid::getAlternateBidderCodes)
.orElse(account.getAlternateBidderCodes());
}

private static ExtRequestTargeting targeting(BidRequest bidRequest) {
final ExtRequestPrebid prebid = PbsUtil.extRequestPrebid(bidRequest);
return prebid != null ? prebid.getTargeting() : null;
Expand Down Expand Up @@ -1225,9 +1247,51 @@ private Future<BidderResponse> requestBids(BidderRequest bidderRequest,
requestHeaders,
aliases,
debugResolver.resolveDebugForBidder(auctionContext, resolvedBidderName)))
.map(seatBid -> populateBidderCode(seatBid, bidderName, resolvedBidderName))
.map(seatBid -> BidderResponse.of(bidderName, seatBid, responseTime(bidderRequestStartTime)));
}

private BidderSeatBid populateBidderCode(BidderSeatBid seatBid, String bidderName, String resolvedBidderName) {
return seatBid.with(seatBid.getBids().stream()
.map(bidderBid -> bidderBid.toBuilder()
.seat(bidderBid.getSeat() == null ? bidderName : bidderBid.getSeat())
.bid(bidderBid.getBid().toBuilder()
.ext(prepareBidExt(bidderBid.getBid(), resolvedBidderName))
.build())
.build())
.toList());
}

private ObjectNode prepareBidExt(Bid bid, String bidderName) {
final ObjectNode bidExt = bid.getExt();
final ExtPrebid<ExtBidPrebid, ObjectNode> extPrebid = getExtPrebid(bidExt);
final ExtBidPrebid extBidPrebid = extPrebid != null ? extPrebid.getPrebid() : null;
final ExtBidPrebidMeta meta = extBidPrebid != null ? extBidPrebid.getMeta() : null;

final ExtBidPrebidMeta updatedMeta = Optional.ofNullable(meta)
.map(ExtBidPrebidMeta::toBuilder)
.orElseGet(ExtBidPrebidMeta::builder)
.adapterCode(bidderName)
.build();

final ExtBidPrebid modifiedExtBidPrebid = extBidPrebid != null
? extBidPrebid.toBuilder().meta(updatedMeta).build()
: ExtBidPrebid.builder().meta(updatedMeta).build();

final ObjectNode updatedBidExt = bidExt != null ? bidExt : mapper.mapper().createObjectNode();
updatedBidExt.set(PREBID_EXT, mapper.mapper().valueToTree(modifiedExtBidPrebid));

return updatedBidExt;
}

private ExtPrebid<ExtBidPrebid, ObjectNode> getExtPrebid(ObjectNode bidExt) {
try {
return bidExt != null ? mapper.mapper().convertValue(bidExt, EXT_PREBID_TYPE_REFERENCE) : null;
} catch (IllegalArgumentException e) {
return null;
}
}

private BidRequest adjustTmax(BidRequest bidRequest,
long startTime,
int adjustmentFactor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,41 @@ public class BidAdjustmentFactorResolver {

public BigDecimal resolve(ImpMediaType impMediaType,
ExtRequestBidAdjustmentFactors adjustmentFactors,
String bidder) {
String bidder,
String seat) {

final EnumMap<ImpMediaType, Map<String, BigDecimal>> adjustmentFactorsByMediaTypes =
adjustmentFactors.getMediatypes();
final Map<String, BigDecimal> adjustmentsFactors = adjustmentFactors.getAdjustments();

final BigDecimal effectiveBidderAdjustmentFactor = Optional.ofNullable(adjustmentFactors.getAdjustments())
.map(factors -> factors.get(bidder))
return resolveFromMediaTypes(impMediaType, seat, adjustmentFactorsByMediaTypes)
.or(() -> resolveFromAdjustments(seat, adjustmentsFactors))
.or(() -> resolveFromMediaTypes(impMediaType, bidder, adjustmentFactorsByMediaTypes))
.or(() -> resolveFromAdjustments(bidder, adjustmentsFactors))
.orElse(BigDecimal.ONE);
}

private static Optional<BigDecimal> resolveFromMediaTypes(
ImpMediaType mediaType,
String bidderCode,
EnumMap<ImpMediaType, Map<String, BigDecimal>> adjustmentFactors) {

if (MapUtils.isEmpty(adjustmentFactorsByMediaTypes)) {
return effectiveBidderAdjustmentFactor;
if (MapUtils.isEmpty(adjustmentFactors)) {
return Optional.empty();
}

return Optional.ofNullable(impMediaType)
.map(adjustmentFactorsByMediaTypes::get)
return Optional.ofNullable(mediaType)
.map(adjustmentFactors::get)
.flatMap(factors -> factors.entrySet().stream()
.filter(entry -> StringUtils.equalsIgnoreCase(entry.getKey(), bidder))
.filter(entry -> StringUtils.equalsIgnoreCase(entry.getKey(), bidderCode))
.map(Map.Entry::getValue)
.findFirst())
.orElse(effectiveBidderAdjustmentFactor);
.findFirst());
}

private static Optional<BigDecimal> resolveFromAdjustments(String bidderCode,
Map<String, BigDecimal> adjustmentFactors) {

return Optional.ofNullable(adjustmentFactors)
.map(factors -> factors.get(bidderCode));
}
}
2 changes: 2 additions & 0 deletions src/main/java/org/prebid/server/auction/model/BidInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class BidInfo {

String bidder;

String seat;

BidType bidType;

CacheInfo cacheInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,14 @@ private BidderBid applyBidAdjustments(BidderBid bidderBid,
final Price priceWithFactorsApplied = applyBidAdjustmentFactors(
originalPrice,
bidder,
bidderBid.getSeat(),
bidRequest,
mediaType);

final Price priceWithAdjustmentsApplied = applyBidAdjustmentRules(
priceWithFactorsApplied,
bidder,
bidderBid.getSeat(),
bidRequest,
bidAdjustments,
mediaType,
Expand Down Expand Up @@ -154,26 +156,31 @@ private Price getOriginalPrice(BidderBid bidderBid) {

private Price applyBidAdjustmentFactors(Price bidPrice,
String bidder,
String seat,
BidRequest bidRequest,
ImpMediaType mediaType) {

final String bidCurrency = bidPrice.getCurrency();
final BigDecimal price = bidPrice.getValue();

final BigDecimal priceAdjustmentFactor = bidAdjustmentForBidder(bidder, bidRequest, mediaType);
final BigDecimal priceAdjustmentFactor = bidAdjustmentForBidder(bidder, seat, bidRequest, mediaType);
final BigDecimal adjustedPrice = adjustPrice(priceAdjustmentFactor, price);

return Price.of(bidCurrency, adjustedPrice.compareTo(price) != 0 ? adjustedPrice : price);
}

private BigDecimal bidAdjustmentForBidder(String bidder, BidRequest bidRequest, ImpMediaType mediaType) {
private BigDecimal bidAdjustmentForBidder(String bidder,
String seat,
BidRequest bidRequest,
ImpMediaType mediaType) {

final ExtRequestBidAdjustmentFactors adjustmentFactors = extBidAdjustmentFactors(bidRequest);
if (adjustmentFactors == null) {
return null;
}

final ImpMediaType targetMediaType = mediaType == ImpMediaType.video_instream ? ImpMediaType.video : mediaType;
return bidAdjustmentFactorResolver.resolve(targetMediaType, adjustmentFactors, bidder);
return bidAdjustmentFactorResolver.resolve(targetMediaType, adjustmentFactors, bidder, seat);
}

private static ExtRequestBidAdjustmentFactors extBidAdjustmentFactors(BidRequest bidRequest) {
Expand All @@ -189,6 +196,7 @@ private static BigDecimal adjustPrice(BigDecimal priceAdjustmentFactor, BigDecim

private Price applyBidAdjustmentRules(Price bidPrice,
String bidder,
String seat,
BidRequest bidRequest,
BidAdjustments bidAdjustments,
ImpMediaType mediaType,
Expand All @@ -200,6 +208,7 @@ private Price applyBidAdjustmentRules(Price bidPrice,
bidAdjustments,
mediaType,
bidder,
seat,
dealId);
}
}
Loading
Loading