Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
52 changes: 50 additions & 2 deletions src/main/java/org/prebid/server/bidder/openx/OpenxBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.openx.model.OpenxImpType;
import org.prebid.server.bidder.openx.proto.OpenxBidExt;
import org.prebid.server.bidder.openx.proto.OpenxBidResponse;
import org.prebid.server.bidder.openx.proto.OpenxBidResponseExt;
import org.prebid.server.bidder.openx.proto.OpenxRequestExt;
Expand All @@ -29,6 +30,8 @@
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.openx.ExtImpOpenx;
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.ExtBidPrebidMeta;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidVideo;
import org.prebid.server.proto.openrtb.ext.response.ExtIgi;
import org.prebid.server.proto.openrtb.ext.response.ExtIgiIgs;
Expand Down Expand Up @@ -270,13 +273,13 @@ private ObjectNode makeImpExt(ObjectNode impExt, boolean addCustomParams) {
return openxImpExt;
}

private static List<BidderBid> extractBids(BidRequest bidRequest, OpenxBidResponse bidResponse) {
private List<BidderBid> extractBids(BidRequest bidRequest, OpenxBidResponse bidResponse) {
return bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())
? Collections.emptyList()
: bidsFromResponse(bidRequest, bidResponse);
}

private static List<BidderBid> bidsFromResponse(BidRequest bidRequest, OpenxBidResponse bidResponse) {
private List<BidderBid> bidsFromResponse(BidRequest bidRequest, OpenxBidResponse bidResponse) {
final Map<String, BidType> impIdToBidType = impIdToBidType(bidRequest);

final String bidCurrency = StringUtils.isNotBlank(bidResponse.getCur())
Expand All @@ -288,6 +291,7 @@ private static List<BidderBid> bidsFromResponse(BidRequest bidRequest, OpenxBidR
.map(SeatBid::getBid)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(bid -> bid.toBuilder().ext(getBidExt(bid)).build())
.map(bid -> toBidderBid(bid, impIdToBidType, bidCurrency))
.toList();
}
Expand Down Expand Up @@ -334,4 +338,48 @@ private static List<ExtIgi> extractIgi(OpenxBidResponse bidResponse) {

return igs.isEmpty() ? null : Collections.singletonList(ExtIgi.builder().igs(igs).build());
}

private ObjectNode getBidExt(Bid bid) {
final ObjectNode ext = bid.getExt();
if (ext == null) {
return null;
}

final OpenxBidExt openxBidExt = parseOpenxBidExt(ext);
final Integer buyerId = parseStringToInt(openxBidExt.getBuyerId());
final Integer dspId = parseStringToInt(openxBidExt.getDspId());
final Integer brandId = parseStringToInt(openxBidExt.getBrandId());

if (buyerId == null && dspId == null && brandId == null) {
return ext;
}

final ExtBidPrebidMeta meta = ExtBidPrebidMeta.builder()
.networkId(dspId)
.advertiserId(buyerId)
.brandId(brandId)
.build();

final ExtBidPrebid extBidPrebid = ExtBidPrebid.builder().meta(meta).build();

ext.set(PREBID_EXT, mapper.mapper().valueToTree(extBidPrebid));

return ext;
}

private OpenxBidExt parseOpenxBidExt(ObjectNode ext) {
try {
return mapper.mapper().convertValue(ext, OpenxBidExt.class);
} catch (IllegalArgumentException e) {
return new OpenxBidExt();
}
}

private static Integer parseStringToInt(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.prebid.server.bidder.openx.proto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OpenxBidExt {

@JsonProperty("dsp_id")
String dspId;
@JsonProperty("buyer_id")
String buyerId;
@JsonProperty("brand_id")
String brandId;
}
100 changes: 100 additions & 0 deletions src/test/java/org/prebid/server/bidder/openx/OpenxBidderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.prebid.server.VertxTest;
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderCall;
Expand All @@ -23,6 +26,7 @@
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.HttpResponse;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.openx.proto.OpenxBidExt;
import org.prebid.server.bidder.openx.proto.OpenxBidResponse;
import org.prebid.server.bidder.openx.proto.OpenxBidResponseExt;
import org.prebid.server.bidder.openx.proto.OpenxRequestExt;
Expand All @@ -42,6 +46,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
Expand Down Expand Up @@ -990,4 +995,99 @@ private static Map<String, JsonNode> givenCustomParams(String key, Object values
private static BidderCall<BidRequest> givenHttpCall(String body) {
return BidderCall.succeededHttp(null, HttpResponse.of(200, null, body), null);
}

private static Stream<Arguments> bidWithExtTestCases() throws JsonProcessingException {
final ObjectNode allBuyerExt = mapper.valueToTree(OpenxBidExt.builder()
.dspId("1")
.buyerId("2")
.brandId("3")
.build());
final ObjectNode onlyBrandExt = mapper.valueToTree(OpenxBidExt.builder()
.brandId("4")
.build());
final ObjectNode badExt = mapper.valueToTree(OpenxBidExt.builder()
.dspId("abc")
.brandId("cba")
.build());

final ObjectNode allBuyerExpectedExt = (ObjectNode) mapper.readTree("""
{
"dsp_id": "1",
"buyer_id": "2",
"brand_id": "3",
"prebid": {
"meta": {
"advertiserId":2,
"brandId":3,
"networkId":1
}
}
}
""");
final ObjectNode onlyBrandExpectedExt = (ObjectNode) mapper.readTree("""
{
"brand_id": "4",
"prebid": {
"meta": {
"brandId":4
}
}
}
""");
final ObjectNode badExpectedExt = (ObjectNode) mapper.readTree("""
{
"dsp_id": "abc",
"brand_id": "cba"
}
""");

return Stream.of(
Arguments.of(allBuyerExt, allBuyerExpectedExt),
Arguments.of(onlyBrandExt, onlyBrandExpectedExt),
Arguments.of(badExt, badExpectedExt),
Arguments.of(null, null)
);
}

@ParameterizedTest
@MethodSource("bidWithExtTestCases")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParameterizedTest are prohibited in the repository, please split it into separate unit tests

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the tests should be above private static factory methods, please place the tests in the correct order

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed - tests are separated and moved above private static factory methods.

public void makeBidsShouldReturnBidWithExt(
ObjectNode bidExt,
ObjectNode expectedExtWithBidMeta) throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(mapper.writeValueAsString(
BidResponse.builder()
.seatbid(singletonList(SeatBid.builder()
.bid(List.of(
Bid.builder()
.w(200)
.h(150)
.price(BigDecimal.ONE)
.impid("impId1")
.dealid("dealid")
.adm("<div>This is an Ad</div>")
.ext(bidExt)
.build()))
.build()))
.build()));

final BidRequest bidRequest = BidRequest.builder()
.id("bidRequestId")
.imp(List.of(
Imp.builder()
.id("impId1")
.banner(Banner.builder().build())
.build()))
.build();

// when
final CompositeBidderResponse result = target.makeBidderResponse(httpCall, bidRequest);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getBids()).hasSize(1)
.extracting(BidderBid::getBid)
.extracting(Bid::getExt)
.containsExactly(expectedExtWithBidMeta);
}
}
Loading