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

Pubmatic: Bidder Updates #3652

Merged
merged 2 commits into from
Jan 2, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderCall;
Expand All @@ -32,6 +33,9 @@
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.proto.openrtb.ext.FlexibleExtension;
import org.prebid.server.proto.openrtb.ext.request.ExtApp;
import org.prebid.server.proto.openrtb.ext.request.ExtAppPrebid;
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.pubmatic.ExtImpPubmatic;
Expand Down Expand Up @@ -90,9 +94,12 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
String publisherId = null;
PubmaticWrapper wrapper;
final List<String> acat;
final Pair<String, String> displayManagerFields;

try {
acat = extractAcat(request);
wrapper = extractWrapper(request);
displayManagerFields = extractDisplayManagerFields(request.getApp());
} catch (IllegalArgumentException e) {
return Result.withError(BidderError.badInput(e.getMessage()));
}
Expand All @@ -110,7 +117,7 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request

wrapper = merge(wrapper, extImpPubmatic.getWrapper());

validImps.add(modifyImp(imp, impExt));
validImps.add(modifyImp(imp, impExt, displayManagerFields.getLeft(), displayManagerFields.getRight()));
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
Expand Down Expand Up @@ -151,6 +158,34 @@ private static JsonNode getExtRequestPrebidBidderparams(BidRequest request) {
return bidderParams != null ? bidderParams.get(BIDDER_NAME) : null;
}

private Pair<String, String> extractDisplayManagerFields(App app) {
String source;
String version;

final ExtApp extApp = app != null ? app.getExt() : null;
final ExtAppPrebid extAppPrebid = extApp != null ? extApp.getPrebid() : null;

source = extAppPrebid != null ? extAppPrebid.getSource() : null;
version = extAppPrebid != null ? extAppPrebid.getVersion() : null;
if (StringUtils.isNoneBlank(source, version)) {
return Pair.of(source, version);
}

source = getPropertyValue(extApp, "source");
version = getPropertyValue(extApp, "version");
return StringUtils.isNoneBlank(source, version)
? Pair.of(source, version)
: Pair.of(null, null);
}

private static String getPropertyValue(FlexibleExtension flexibleExtension, String propertyName) {
return Optional.ofNullable(flexibleExtension)
.map(ext -> ext.getProperty(propertyName))
.filter(JsonNode::isValueNode)
.map(JsonNode::asText)
.orElse(null);
}

private static void validateMediaType(Imp imp) {
if (imp.getBanner() == null && imp.getVideo() == null && imp.getXNative() == null) {
throw new PreBidException(
Expand Down Expand Up @@ -191,7 +226,7 @@ private static Integer stripToNull(Integer value) {
return value == null || value == 0 ? null : value;
}

private Imp modifyImp(Imp imp, PubmaticBidderImpExt impExt) {
private Imp modifyImp(Imp imp, PubmaticBidderImpExt impExt, String displayManager, String displayManagerVersion) {
final Banner banner = imp.getBanner();
final ExtImpPubmatic impExtBidder = impExt.getBidder();

Expand All @@ -201,6 +236,8 @@ private Imp modifyImp(Imp imp, PubmaticBidderImpExt impExt) {
.banner(banner != null ? assignSizesIfMissing(banner) : null)
.audio(null)
.bidfloor(resolveBidFloor(impExtBidder.getKadfloor(), imp.getBidfloor()))
.displaymanager(StringUtils.firstNonBlank(imp.getDisplaymanager(), displayManager))
.displaymanagerver(StringUtils.firstNonBlank(imp.getDisplaymanagerver(), displayManagerVersion))
.ext(!newExt.isEmpty() ? newExt : null);

enrichWithAdSlotParameters(impBuilder, impExtBidder.getAdSlot(), banner);
Expand Down Expand Up @@ -400,7 +437,7 @@ private BidRequest modifyBidRequest(BidRequest request,
.imp(imps)
.site(modifySite(request.getSite(), publisherId))
.app(modifyApp(request.getApp(), publisherId))
.ext(modifyExtRequest(request.getExt(), wrapper, acat))
.ext(modifyExtRequest(wrapper, acat))
.build();
}

Expand All @@ -426,7 +463,7 @@ private static Publisher modifyPublisher(Publisher publisher, String publisherId
: Publisher.builder().id(publisherId).build();
}

private ExtRequest modifyExtRequest(ExtRequest extRequest, PubmaticWrapper wrapper, List<String> acat) {
private ExtRequest modifyExtRequest(PubmaticWrapper wrapper, List<String> acat) {
final ObjectNode extNode = mapper.mapper().createObjectNode();

if (wrapper != null) {
Expand All @@ -437,9 +474,10 @@ private ExtRequest modifyExtRequest(ExtRequest extRequest, PubmaticWrapper wrapp
extNode.putPOJO(ACAT_EXT_REQUEST, acat);
}

final ExtRequest newExtRequest = ExtRequest.empty();
return extNode.isEmpty()
? extRequest
: mapper.fillExtension(extRequest == null ? ExtRequest.empty() : extRequest, extNode);
? newExtRequest
: mapper.fillExtension(newExtRequest, extNode);
}

private HttpRequest<BidRequest> makeHttpRequest(BidRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import org.prebid.server.bidder.pubmatic.model.response.PubmaticExtBidResponse;
import org.prebid.server.bidder.pubmatic.model.response.VideoCreativeInfo;
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtApp;
import org.prebid.server.proto.openrtb.ext.request.ExtAppPrebid;
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.pubmatic.ExtImpPubmatic;
Expand Down Expand Up @@ -198,9 +200,7 @@ public void makeHttpRequestsShouldReturnBidRequestExtIfAcatFieldIsValidAndTrimWh
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);

// then
final ExtRequest expectedExtRequest = ExtRequest.of(ExtRequestPrebid.builder()
.bidderparams(pubmaticNode)
.build());
final ExtRequest expectedExtRequest = ExtRequest.empty();
expectedExtRequest.addProperty("acat",
mapper.createArrayNode().add("te st Value").add("test Value").add("Value"));

Expand Down Expand Up @@ -884,6 +884,54 @@ public void makeHttpRequestsShouldSetAppPublisherIdIfSiteIsNull() {
.containsExactly("pub id");
}

@Test
public void makeHttpRequestsShouldSetDisplayManagerFieldsFromAppExtPrebid() {
// given
final ExtApp extApp = ExtApp.of(ExtAppPrebid.of("ext-prebid-source", "ext-prebid-version"), null);
extApp.addProperty("source", TextNode.valueOf("ext-source"));
extApp.addProperty("version", TextNode.valueOf("ext-version"));

final BidRequest bidRequest = givenBidRequest(
bidRequestBuilder -> bidRequestBuilder.app(App.builder().ext(extApp).build()),
identity(),
identity());

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver)
.containsExactly(tuple("ext-prebid-source", "ext-prebid-version"));
}

@Test
public void makeHttpRequestsShouldSetDisplayManagerFieldsFromAppExt() {
// given
final ExtApp extApp = ExtApp.of(ExtAppPrebid.of("ext-prebid-source", null), null);
extApp.addProperty("source", TextNode.valueOf("ext-source"));
extApp.addProperty("version", TextNode.valueOf("ext-version"));

final BidRequest bidRequest = givenBidRequest(
bidRequestBuilder -> bidRequestBuilder.app(App.builder().ext(extApp).build()),
identity(),
identity());

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver)
.containsExactly(tuple("ext-source", "ext-version"));
}

@Test
public void makeHttpRequestsShouldSUpdateAppPublisherIdExtPublisherIdIsPresent() {
// given
Expand Down Expand Up @@ -1279,7 +1327,11 @@ private static ExtRequest expectedBidRequestExt(ExtRequest originalExtRequest,
final ObjectNode wrapperNode = mapper.createObjectNode()
.set("wrapper", mapper.valueToTree(PubmaticWrapper.of(wrapperProfile, wrapperVersion)));

return jacksonMapper.fillExtension(originalExtRequest, wrapperNode);
final ExtRequest extRequestWithoutPrebid = jacksonMapper.fillExtension(
ExtRequest.empty(),
originalExtRequest.getProperties());

return jacksonMapper.fillExtension(extRequestWithoutPrebid, wrapperNode);
}

private static BidRequest givenBidRequest(UnaryOperator<BidRequest.BidRequestBuilder> bidRequestCustomizer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,6 @@
"gdpr": 0
},
"ext": {
"prebid": {
"server": {
"externalurl": "http://localhost:8080",
"gvlid": 1,
"datacenter": "local",
"endpoint": "/openrtb2/auction"
},
"bidderparams": {
"pubmatic": {
"acat": [
"testValue1",
"testValue2"
]
}
}
},
"acat": [
"testValue1",
"testValue2"
Expand Down
Loading