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

Support fledge for Pubmatic adapter #2732

Merged
merged 2 commits into from
Nov 14, 2023
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
51 changes: 40 additions & 11 deletions src/main/java/org/prebid/server/bidder/pubmatic/PubmaticBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.iab.openrtb.request.Publisher;
import com.iab.openrtb.request.Site;
import com.iab.openrtb.response.Bid;
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
Expand All @@ -20,13 +19,16 @@
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderCall;
import org.prebid.server.bidder.model.BidderError;
import org.prebid.server.bidder.model.CompositeBidderResponse;
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.pubmatic.model.request.PubmaticBidderImpExt;
import org.prebid.server.bidder.pubmatic.model.request.PubmaticExtData;
import org.prebid.server.bidder.pubmatic.model.request.PubmaticExtDataAdServer;
import org.prebid.server.bidder.pubmatic.model.request.PubmaticWrapper;
import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidExt;
import org.prebid.server.bidder.pubmatic.model.response.PubmaticBidResponse;
import org.prebid.server.bidder.pubmatic.model.response.PubmaticExtBidResponse;
import org.prebid.server.bidder.pubmatic.model.response.VideoCreativeInfo;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
Expand All @@ -37,6 +39,7 @@
import org.prebid.server.proto.openrtb.ext.response.BidType;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo;
import org.prebid.server.proto.openrtb.ext.response.FledgeAuctionConfig;
import org.prebid.server.util.BidderUtil;
import org.prebid.server.util.HttpUtil;

Expand All @@ -61,6 +64,7 @@ public class PubmaticBidder implements Bidder<BidRequest> {
private static final String ACAT_EXT_REQUEST = "acat";
private static final String WRAPPER_EXT_REQUEST = "wrapper";
private static final String BIDDER_NAME = "pubmatic";
private static final String AE = "ae";

private final String endpointUrl;
private final JacksonMapper mapper;
Expand Down Expand Up @@ -180,17 +184,20 @@ private PubmaticBidderImpExt parseImpExt(Imp imp) {

private Imp modifyImp(Imp imp, PubmaticBidderImpExt impExt) {
final Banner banner = imp.getBanner();
final ObjectNode keywordsNode = makeKeywords(impExt);
final ExtImpPubmatic impExtBidder = impExt.getBidder();

final ObjectNode modifiedExt = makeKeywords(impExt);
if (impExt.getAe() != null) {
modifiedExt.put(AE, impExt.getAe());
}

final Imp.ImpBuilder impBuilder = imp.toBuilder()
.banner(banner != null ? assignSizesIfMissing(banner) : null)
.ext(!keywordsNode.isEmpty() ? keywordsNode : null)
.ext(!modifiedExt.isEmpty() ? modifiedExt : null)
.bidfloor(resolveBidFloor(impExtBidder.getKadfloor(), imp.getBidfloor()))
.audio(null);

return enrichWithAdSlotParameters(impBuilder, impExtBidder.getAdSlot(), banner)
.build();
return enrichWithAdSlotParameters(impBuilder, impExtBidder.getAdSlot(), banner).build();
}

private BigDecimal resolveBidFloor(String kadfloor, BigDecimal existingFloor) {
Expand Down Expand Up @@ -365,24 +372,35 @@ private static Publisher modifyPublisher(Publisher publisher, String publisherId
: Publisher.builder().id(publisherId).build();
}

/**
* @deprecated for this bidder in favor of @link{makeBidderResponse} which supports additional response data
*/
@Override
public final Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
@Deprecated(forRemoval = true)
public Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
return Result.withError(BidderError.generic("Deprecated adapter method invoked"));
}

@Override
public CompositeBidderResponse makeBidderResponse(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final List<BidderError> bidderErrors = new ArrayList<>();
final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
return Result.of(extractBids(bidResponse, bidderErrors), Collections.emptyList());
final PubmaticBidResponse bidResponse = mapper.decodeValue(
httpCall.getResponse().getBody(),
PubmaticBidResponse.class);
return CompositeBidderResponse.withBids(extractBids(bidResponse, bidderErrors), extractFledge(bidResponse));
} catch (DecodeException | PreBidException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
return CompositeBidderResponse.withError(BidderError.badServerResponse(e.getMessage()));
}
}

private List<BidderBid> extractBids(BidResponse bidResponse, List<BidderError> bidderErrors) {
private List<BidderBid> extractBids(PubmaticBidResponse bidResponse, List<BidderError> bidderErrors) {
return bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())
? Collections.emptyList()
: bidsFromResponse(bidResponse, bidderErrors);
}

private List<BidderBid> bidsFromResponse(BidResponse bidResponse, List<BidderError> bidderErrors) {
private List<BidderBid> bidsFromResponse(PubmaticBidResponse bidResponse, List<BidderError> bidderErrors) {
return bidResponse.getSeatbid().stream()
.filter(Objects::nonNull)
.map(SeatBid::getBid)
Expand Down Expand Up @@ -473,4 +491,15 @@ private static Integer getDealPriority(PubmaticBidExt bidExt) {
.map(PubmaticBidExt::getPrebidDealPriority)
.orElse(null);
}

private static List<FledgeAuctionConfig> extractFledge(PubmaticBidResponse bidResponse) {
return Optional.ofNullable(bidResponse)
.map(PubmaticBidResponse::getExt)
.map(PubmaticExtBidResponse::getFledgeAuctionConfigs)
.orElse(Collections.emptyMap())
.entrySet()
.stream()
.map(e -> FledgeAuctionConfig.builder().impId(e.getKey()).config(e.getValue()).build())
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.prebid.server.bidder.pubmatic.model.request;

import lombok.AllArgsConstructor;
import lombok.Value;
import org.prebid.server.proto.openrtb.ext.request.pubmatic.ExtImpPubmatic;

@AllArgsConstructor(staticName = "of")
@Value
@Value(staticConstructor = "of")
public class PubmaticBidderImpExt {

ExtImpPubmatic bidder;

PubmaticExtData data;

Integer ae;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.prebid.server.bidder.pubmatic.model.response;

import com.iab.openrtb.response.SeatBid;
import lombok.Builder;
import lombok.Value;

import java.util.List;

@Builder(toBuilder = true)
@Value
public class PubmaticBidResponse {

String id;

List<SeatBid> seatbid;

String bidid;

String cur;

String customdata;

Integer nbr;

PubmaticExtBidResponse ext;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.prebid.server.bidder.pubmatic.model.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Value;

import java.util.Map;

@Value(staticConstructor = "of")
public class PubmaticExtBidResponse {

@JsonProperty("fledge_auction_configs")
Map<String, ObjectNode> fledgeAuctionConfigs;

}
Loading
Loading