Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 40 additions & 25 deletions src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import org.prebid.server.floors.PriceFloorResolver;
import org.prebid.server.floors.model.PriceFloorResult;
import org.prebid.server.floors.model.PriceFloorRules;
import org.prebid.server.identity.IdGenerator;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.log.ConditionalLogger;
Expand Down Expand Up @@ -127,7 +128,6 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
Expand Down Expand Up @@ -190,6 +190,7 @@ public class RubiconBidder implements Bidder<BidRequest> {
private final CurrencyConversionService currencyConversionService;
private final PriceFloorResolver floorResolver;
private final PrebidVersionProvider versionProvider;
private final IdGenerator idGenerator;
private final JacksonMapper mapper;

private final MultiMap headers;
Expand All @@ -205,6 +206,7 @@ public RubiconBidder(String bidderName,
CurrencyConversionService currencyConversionService,
PriceFloorResolver floorResolver,
PrebidVersionProvider versionProvider,
IdGenerator idGenerator,
JacksonMapper mapper) {

this.bidderName = Objects.requireNonNull(bidderName);
Expand All @@ -217,6 +219,7 @@ public RubiconBidder(String bidderName,
this.currencyConversionService = Objects.requireNonNull(currencyConversionService);
this.floorResolver = Objects.requireNonNull(floorResolver);
this.versionProvider = Objects.requireNonNull(versionProvider);
this.idGenerator = Objects.requireNonNull(idGenerator);
this.mapper = Objects.requireNonNull(mapper);

headers = headers(Objects.requireNonNull(xapiUsername), Objects.requireNonNull(xapiPassword));
Expand All @@ -241,9 +244,10 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest bidRequ
try {
final Imp imp = impToExt.getKey();
final ExtImpRubicon impExt = impToExt.getValue();
final String pbBidId = generateBidId ? idGenerator.generateId() : null;
final List<BidRequest> impBidRequests = isMultiformatEnabled(impExt)
? createMultiFormatRequests(bidRequest, imp, impExt, language, errors)
: List.of(createSingleRequest(bidRequest, imp, impExt, null, language, errors));
? createMultiFormatRequests(bidRequest, imp, impExt, pbBidId, language, errors)
: List.of(createSingleRequest(bidRequest, imp, impExt, pbBidId, null, language, errors));

httpRequests.addAll(createImpHttpRequests(imp, impBidRequests, uri));
} catch (PreBidException e) {
Expand All @@ -257,20 +261,22 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest bidRequ
private List<BidRequest> createMultiFormatRequests(BidRequest bidRequest,
Imp imp,
ExtImpRubicon impExt,
String pbBidId,
String language,
List<BidderError> errors) {

final Map<ImpMediaType, Imp> impByType = splitByMediaType(imp);
final Set<ImpMediaType> formats = impByType.keySet();
if (formats.size() == 1) {
return Collections.singletonList(
createSingleRequest(bidRequest, imp, impExt, null, language, errors));
createSingleRequest(bidRequest, imp, impExt, pbBidId, null, language, errors));
}

final List<BidRequest> bidRequests = new ArrayList<>();
for (Imp singleFormatImp : impByType.values()) {
try {
bidRequests.add(createSingleRequest(bidRequest, singleFormatImp, impExt, formats, language, errors));
bidRequests.add(
createSingleRequest(bidRequest, singleFormatImp, impExt, pbBidId, formats, language, errors));
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
Expand Down Expand Up @@ -426,12 +432,13 @@ private static String firstImpExtLanguage(Collection<ExtImpRubicon> rubiconImpEx
private BidRequest createSingleRequest(BidRequest bidRequest,
Imp imp,
ExtImpRubicon extImpRubicon,
String pbBidId,
Set<ImpMediaType> formats,
String impLanguage,
List<BidderError> errors) {

return bidRequest.toBuilder()
.imp(Collections.singletonList(makeImp(imp, extImpRubicon, bidRequest, formats, errors)))
.imp(Collections.singletonList(makeImp(imp, extImpRubicon, bidRequest, pbBidId, formats, errors)))
.user(downgradeUserConsent(makeUser(bidRequest.getUser(), extImpRubicon)))
.device(makeDevice(bidRequest.getDevice()))
.site(makeSite(bidRequest.getSite(), impLanguage, extImpRubicon))
Expand Down Expand Up @@ -483,6 +490,7 @@ private RubiconExtPrebidBiddersBidder extPrebidBiddersRubicon(ExtRequest extRequ
private Imp makeImp(Imp imp,
ExtImpRubicon extImpRubicon,
BidRequest bidRequest,
String pbImpId,
Set<ImpMediaType> formats,
List<BidderError> errors) {

Expand All @@ -507,7 +515,7 @@ private Imp makeImp(Imp imp,
final Imp.ImpBuilder builder = imp.toBuilder()
.metric(makeMetrics(imp))
.ext(mapper.mapper().valueToTree(
makeImpExt(imp, extImpRubicon, resolvedFormats, site, app, extRequest)));
makeImpExt(imp, extImpRubicon, resolvedFormats, site, app, extRequest, pbImpId)));

final BigDecimal resolvedBidFloor = ipfFloor != null
? convertToXAPICurrency(ipfFloor, ipfCurrency, imp, bidRequest)
Expand Down Expand Up @@ -667,7 +675,8 @@ private RubiconImpExt makeImpExt(Imp imp,
Set<ImpMediaType> formats,
Site site,
App app,
ExtRequest extRequest) {
ExtRequest extRequest,
String pbBidId) {

final RubiconImpExtRpRtb rubiconImpExtRpRtb = CollectionUtils.isNotEmpty(formats)
? RubiconImpExtRpRtb.of(formats)
Expand All @@ -677,7 +686,8 @@ private RubiconImpExt makeImpExt(Imp imp,
rubiconImpExt.getZoneId(),
makeTarget(imp, rubiconImpExt, site, app),
RubiconImpExtRpTrack.of("", ""),
rubiconImpExtRpRtb);
rubiconImpExtRpRtb,
pbBidId);

return RubiconImpExt.builder()
.rp(rubiconImpExtRp)
Expand Down Expand Up @@ -1540,8 +1550,12 @@ private ObjectNode modifyRubiconImpExt(ObjectNode impExtNode, ExtRequest extRequ
? mapper.mapper().createObjectNode() : (ObjectNode) impExtRp.getTarget();

final ObjectNode modifiedTargetNode = targetNode.put("line_item", extLineItemId);
final RubiconImpExtRp modifiedImpExtRp = RubiconImpExtRp.of(impExtRp.getZoneId(), modifiedTargetNode,
impExtRp.getTrack(), impExtRp.getRtb());
final RubiconImpExtRp modifiedImpExtRp = RubiconImpExtRp.of(
impExtRp.getZoneId(),
modifiedTargetNode,
impExtRp.getTrack(),
impExtRp.getRtb(),
impExtRp.getPbBidId());

return mapper.mapper().valueToTree(rubiconImpExt.toBuilder()
.rp(modifiedImpExtRp)
Expand All @@ -1564,6 +1578,7 @@ private List<BidderBid> bidsFromResponse(BidRequest prebidRequest,
BidRequest bidRequest,
RubiconBidResponse bidResponse,
List<BidderError> errors) {

final Map<String, Imp> idToImp = prebidRequest.getImp().stream()
.collect(Collectors.toMap(Imp::getId, Function.identity()));
final Map<String, Imp> idToRubiconImp = bidRequest.getImp().stream()
Expand All @@ -1581,10 +1596,10 @@ private List<BidderBid> bidsFromResponse(BidRequest prebidRequest,
bid,
seatBid,
idToImp.get(bid.getImpid()),
idToRubiconImp.get(bid.getImpid()),
bidType,
cpmOverrideFromRequest,
hasApexRenderer,
bidResponse,
errors))
.filter(Objects::nonNull)
.map(bid -> createBidderBid(
Expand All @@ -1600,10 +1615,10 @@ private List<BidderBid> bidsFromResponse(BidRequest prebidRequest,
private Bid updateBid(RubiconBid bid,
RubiconSeatBid seatBid,
Imp imp,
Imp rubiconImp,
BidType bidType,
Float cpmOverrideFromRequest,
boolean hasApexRenderer,
RubiconBidResponse bidResponse,
List<BidderError> errors) {

final ObjectNode updateBidExt;
Expand All @@ -1614,25 +1629,14 @@ private Bid updateBid(RubiconBid bid,
return null;
}

String bidId = bid.getId();
if (generateBidId) {
// Since Rubicon XAPI returns openrtb_response.seatbid.bid.id not unique enough
// generate new value for it
bidId = UUID.randomUUID().toString();
} else if (Objects.equals(bid.getId(), "0")) {
// Since Rubicon XAPI returns only one bid per response
// copy bidResponse.bidid to openrtb_response.seatbid.bid.id
bidId = bidResponse.getBidid();
}

// Unconditionally set price if coming from CPM override
final Float cpmOverride = ObjectUtils.defaultIfNull(cpmOverrideFromImp(imp), cpmOverrideFromRequest);
final BigDecimal bidPrice = cpmOverride != null
? new BigDecimal(String.valueOf(cpmOverride))
: bid.getPrice();

final RubiconBid updatedRubiconBid = bid.toBuilder()
.id(bidId)
.id(resolveBidId(rubiconImp, bid))
.adm(resolveAdm(bid.getAdm(), bid.getAdmNative()))
.price(bidPrice)
.ext(updateBidExt)
Expand Down Expand Up @@ -1712,6 +1716,17 @@ private static Boolean isVideoMetaMediaType(ExtBidPrebidMeta meta) {
.orElse(false);
}

private String resolveBidId(Imp rubiconImp, RubiconBid bid) {
return generateBidId
? Optional.ofNullable(rubiconImp)
.map(Imp::getExt)
.map(ext -> ext.get("rp"))
.map(rp -> rp.get("pb_bid_id"))
.map(JsonNode::asText)
.orElse(bid.getId())
: bid.getId();
}

private String resolveAdm(String bidAdm, ObjectNode admobject) {
if (StringUtils.isNotBlank(bidAdm)) {
return bidAdm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public class RubiconImpExtRp {
RubiconImpExtRpTrack track;

RubiconImpExtRpRtb rtb;

String pbBidId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.prebid.server.bidder.rubicon.RubiconBidder;
import org.prebid.server.currency.CurrencyConversionService;
import org.prebid.server.floors.PriceFloorResolver;
import org.prebid.server.identity.UUIDIdGenerator;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties;
import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler;
Expand Down Expand Up @@ -55,11 +56,12 @@ BidderDeps rubiconBidderDeps(RubiconConfigurationProperties rubiconConfiguration
config.getXapi().getUsername(),
config.getXapi().getPassword(),
config.getMetaInfo().getSupportedVendors(),
config.getGenerateBidId(),
config.getGenerateBidId() == null || config.getGenerateBidId(),
config.getApexRendererUrl(),
currencyConversionService,
floorResolver,
versionProvider,
new UUIDIdGenerator(),
mapper))
.assemble();
}
Expand All @@ -74,7 +76,6 @@ private static class RubiconConfigurationProperties extends BidderConfigurationP
@NotNull
private XAPI xapi = new XAPI();

@NotNull
private Boolean generateBidId;

@NotNull
Expand Down
1 change: 0 additions & 1 deletion src/main/resources/bidder-config/rubicon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ adapters:
redirect:
url: GET_FROM_globalsupport@magnite.com
support-cors: false
generate-bid-id: false
apex-renderer-url: "https://video-outstream.rubiconproject.com/apex-2.2.1.js"
XAPI:
Username: GET_FROM_globalsupport@magnite.com
Expand Down
Loading
Loading