From eb3ca3b6c2bbb90ff128cb9219db1324f33aac59 Mon Sep 17 00:00:00 2001 From: ym-prasanth <80693980+ym-prasanth@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:26:19 -0500 Subject: [PATCH 1/3] Provide support for media type per impression (#1) --- .../server/bidder/yieldmo/YieldmoBidder.java | 23 +++++++++++------- .../bidder/yieldmo/proto/YieldmoBidExt.java | 15 ++++++++++++ .../bidder/yieldmo/YieldmoBidderTest.java | 24 +++++++++++++------ .../test-auction-yieldmo-response.json | 3 ++- .../yieldmo/test-yieldmo-bid-response.json | 7 ++++-- 5 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/prebid/server/bidder/yieldmo/proto/YieldmoBidExt.java diff --git a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java index 9030a7de9fb..194ce9308db 100644 --- a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java +++ b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java @@ -16,6 +16,7 @@ import org.prebid.server.bidder.model.BidderError; import org.prebid.server.bidder.model.HttpRequest; import org.prebid.server.bidder.model.Result; +import org.prebid.server.bidder.yieldmo.proto.YieldmoBidExt; import org.prebid.server.bidder.yieldmo.proto.YieldmoImpExt; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.DecodeException; @@ -97,13 +98,13 @@ private HttpRequest makeRequest(BidRequest bidRequest) { public Result> makeBids(BidderCall httpCall, BidRequest bidRequest) { try { final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class); - return Result.withValues(extractBids(httpCall.getRequest().getPayload(), bidResponse)); + return Result.withValues(extractBids(bidResponse)); } catch (DecodeException e) { return Result.withError(BidderError.badServerResponse(e.getMessage())); } } - private static List extractBids(BidRequest bidRequest, BidResponse bidResponse) { + private List extractBids(BidResponse bidResponse) { if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) { return Collections.emptyList(); } @@ -114,16 +115,20 @@ private static List extractBids(BidRequest bidRequest, BidResponse bi .filter(Objects::nonNull) .flatMap(Collection::stream) .filter(Objects::nonNull) - .map(bid -> BidderBid.of(bid, resolveBidType(bid, bidRequest.getImp()), bidResponse.getCur())) + .map(bid -> { + final BidType bidType = resolveBidType(bid); + return bidType != null ? BidderBid.of(bid, bidType, bidResponse.getCur()) : null; + }) + .filter(Objects::nonNull) .toList(); } - private static BidType resolveBidType(Bid bid, List imps) { - for (Imp imp : imps) { - if (Objects.equals(imp.getId(), bid.getImpid())) { - return imp.getBanner() != null ? BidType.banner : BidType.video; - } + private BidType resolveBidType(Bid bid) { + try { + final YieldmoBidExt bidExt = mapper.mapper().treeToValue(bid.getExt(), YieldmoBidExt.class); + return BidType.fromString(bidExt.getMediaType()); + } catch (Exception e) { + return null; } - return BidType.video; } } diff --git a/src/main/java/org/prebid/server/bidder/yieldmo/proto/YieldmoBidExt.java b/src/main/java/org/prebid/server/bidder/yieldmo/proto/YieldmoBidExt.java new file mode 100644 index 00000000000..54742a92d24 --- /dev/null +++ b/src/main/java/org/prebid/server/bidder/yieldmo/proto/YieldmoBidExt.java @@ -0,0 +1,15 @@ +package org.prebid.server.bidder.yieldmo.proto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Value; + +/** + * Defines the contract for bidresponse.seatbid[i].bid[i].ext + */ +@Value(staticConstructor = "of") +public class YieldmoBidExt { + + @JsonProperty("mediatype") + String mediaType; +} + diff --git a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java index 3b27bcb5acf..f0e76b2425b 100644 --- a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java @@ -1,6 +1,8 @@ package org.prebid.server.bidder.yieldmo; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import com.iab.openrtb.request.Banner; @@ -199,7 +201,7 @@ public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws Jso } @Test - public void makeBidsShouldReturnVideoBidByDefault() throws JsonProcessingException { + public void makeBidsShouldReturnEmptyListIfBidExtHasNoMediaType() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( BidRequest.builder() @@ -213,8 +215,7 @@ public void makeBidsShouldReturnVideoBidByDefault() throws JsonProcessingExcepti // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), video, "USD")); + assertThat(result.getValue()).isEmpty(); } @Test @@ -225,7 +226,7 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws .imp(singletonList(Imp.builder().banner(Banner.builder().build()).id("123").build())) .build(), mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("banner"))))); // when final Result> result = target.makeBids(httpCall, null); @@ -233,7 +234,8 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), banner, "USD")); + .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("banner")).build(), + banner, "USD")); } @Test @@ -244,7 +246,7 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js .imp(singletonList(Imp.builder().video(Video.builder().build()).id("123").build())) .build(), mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("video"))))); // when final Result> result = target.makeBids(httpCall, null); @@ -252,7 +254,8 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), video, "USD")); + .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("video")).build(), + video, "USD")); } private static BidRequest givenBidRequest( @@ -291,4 +294,11 @@ private static BidderCall givenHttpCall(BidRequest bidRequest, Strin HttpResponse.of(200, null, body), null); } + + private ObjectNode toObjectNode(String mediaType) { + final ObjectMapper mapper = new ObjectMapper(); + final ObjectNode root = mapper.createObjectNode(); + root.set("mediatype", mapper.convertValue(mediaType, JsonNode.class)); + return root; + } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json index 1a0e67d6d93..15089c43484 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json @@ -17,7 +17,8 @@ "prebid": { "type": "banner" }, - "origbidcpm": 3.33 + "origbidcpm": 3.33, + "mediatype": "banner" } } ], diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json index 8901429253e..9679171d65e 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json @@ -12,9 +12,12 @@ "cid": "cid", "adm": "adm001", "h": 250, - "w": 300 + "w": 300, + "ext" : { + "mediatype" : "banner" + } } ] } ] -} \ No newline at end of file +} From c4e0fcd0a77f4e73670b09496975eda12cab919f Mon Sep 17 00:00:00 2001 From: ym-prasanth <80693980+ym-prasanth@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:26:15 -0500 Subject: [PATCH 2/3] CR feedback. Set mtype in bid response. (#2) --- .../server/bidder/yieldmo/YieldmoBidder.java | 27 +++++++++++++++---- .../bidder/yieldmo/YieldmoBidderTest.java | 23 +++++++++++----- .../test-auction-yieldmo-response.json | 1 + .../yieldmo/test-yieldmo-bid-response.json | 1 + 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java index 194ce9308db..6be9caaa09c 100644 --- a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java +++ b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonPointer; 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.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.response.Bid; @@ -116,17 +117,33 @@ private List extractBids(BidResponse bidResponse) { .flatMap(Collection::stream) .filter(Objects::nonNull) .map(bid -> { - final BidType bidType = resolveBidType(bid); - return bidType != null ? BidderBid.of(bid, bidType, bidResponse.getCur()) : null; + final Bid.BidBuilder bidBuilder = bid.toBuilder(); + final BidType bidType = resolveBidType(bidBuilder, bid.getExt()); + return bidType != null ? BidderBid.of(bidBuilder.build(), bidType, bidResponse.getCur()) : null; }) .filter(Objects::nonNull) .toList(); } - private BidType resolveBidType(Bid bid) { + // Retrieve the media type corresponding to the bid from the bid.ext object and set it in the response + private BidType resolveBidType(Bid.BidBuilder bidBuilder, ObjectNode extFromResponse) { try { - final YieldmoBidExt bidExt = mapper.mapper().treeToValue(bid.getExt(), YieldmoBidExt.class); - return BidType.fromString(bidExt.getMediaType()); + final YieldmoBidExt bidExt = mapper.mapper().treeToValue(extFromResponse, YieldmoBidExt.class); + switch (bidExt.getMediaType()) { + case "banner" -> { + bidBuilder.mtype(1); + return BidType.banner; + } + case "video" -> { + bidBuilder.mtype(2); + return BidType.video; + } + case "native" -> { + bidBuilder.mtype(4); + return BidType.xNative; + } + default -> throw new IllegalArgumentException("Invalid media type " + bidExt.getMediaType()); + } } catch (Exception e) { return null; } diff --git a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java index f0e76b2425b..6b42611fb84 100644 --- a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java @@ -225,8 +225,8 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws BidRequest.builder() .imp(singletonList(Imp.builder().banner(Banner.builder().build()).id("123").build())) .build(), - mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("banner"))))); + mapper.writeValueAsString(givenBidResponse(bidBuilder -> + bidBuilder.impid("123").ext(toObjectNode("banner")).mtype(1)))); // when final Result> result = target.makeBids(httpCall, null); @@ -234,8 +234,12 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("banner")).build(), - banner, "USD")); + .containsExactly(BidderBid.of(Bid.builder() + .impid("123") + .ext(toObjectNode("banner")) + .mtype(1) + .build(), + banner, "USD")); } @Test @@ -246,7 +250,10 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js .imp(singletonList(Imp.builder().video(Video.builder().build()).id("123").build())) .build(), mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("video"))))); + givenBidResponse(bidBuilder -> bidBuilder + .impid("123") + .ext(toObjectNode("video")) + .mtype(2)))); // when final Result> result = target.makeBids(httpCall, null); @@ -254,7 +261,11 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("video")).build(), + .containsExactly(BidderBid.of(Bid.builder() + .impid("123") + .ext(toObjectNode("video")) + .mtype(2) + .build(), video, "USD")); } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json index 15089c43484..2a0db948273 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json @@ -13,6 +13,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json index 9679171d65e..c4e2607745a 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json @@ -13,6 +13,7 @@ "adm": "adm001", "h": 250, "w": 300, + "mtype": 1, "ext" : { "mediatype" : "banner" } From 6957b0e87611533db01e3f481be0133a3993a59f Mon Sep 17 00:00:00 2001 From: prasanth Date: Mon, 27 Nov 2023 09:26:47 -0500 Subject: [PATCH 3/3] Revert "CR feedback. Set mtype in bid response. (#2)" This reverts commit c4e0fcd0a77f4e73670b09496975eda12cab919f. --- .../server/bidder/yieldmo/YieldmoBidder.java | 27 ++++--------------- .../bidder/yieldmo/YieldmoBidderTest.java | 23 +++++----------- .../test-auction-yieldmo-response.json | 1 - .../yieldmo/test-yieldmo-bid-response.json | 1 - 4 files changed, 11 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java index 6be9caaa09c..194ce9308db 100644 --- a/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java +++ b/src/main/java/org/prebid/server/bidder/yieldmo/YieldmoBidder.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.core.JsonPointer; 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.BidRequest; import com.iab.openrtb.request.Imp; import com.iab.openrtb.response.Bid; @@ -117,33 +116,17 @@ private List extractBids(BidResponse bidResponse) { .flatMap(Collection::stream) .filter(Objects::nonNull) .map(bid -> { - final Bid.BidBuilder bidBuilder = bid.toBuilder(); - final BidType bidType = resolveBidType(bidBuilder, bid.getExt()); - return bidType != null ? BidderBid.of(bidBuilder.build(), bidType, bidResponse.getCur()) : null; + final BidType bidType = resolveBidType(bid); + return bidType != null ? BidderBid.of(bid, bidType, bidResponse.getCur()) : null; }) .filter(Objects::nonNull) .toList(); } - // Retrieve the media type corresponding to the bid from the bid.ext object and set it in the response - private BidType resolveBidType(Bid.BidBuilder bidBuilder, ObjectNode extFromResponse) { + private BidType resolveBidType(Bid bid) { try { - final YieldmoBidExt bidExt = mapper.mapper().treeToValue(extFromResponse, YieldmoBidExt.class); - switch (bidExt.getMediaType()) { - case "banner" -> { - bidBuilder.mtype(1); - return BidType.banner; - } - case "video" -> { - bidBuilder.mtype(2); - return BidType.video; - } - case "native" -> { - bidBuilder.mtype(4); - return BidType.xNative; - } - default -> throw new IllegalArgumentException("Invalid media type " + bidExt.getMediaType()); - } + final YieldmoBidExt bidExt = mapper.mapper().treeToValue(bid.getExt(), YieldmoBidExt.class); + return BidType.fromString(bidExt.getMediaType()); } catch (Exception e) { return null; } diff --git a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java index 6b42611fb84..f0e76b2425b 100644 --- a/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yieldmo/YieldmoBidderTest.java @@ -225,8 +225,8 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws BidRequest.builder() .imp(singletonList(Imp.builder().banner(Banner.builder().build()).id("123").build())) .build(), - mapper.writeValueAsString(givenBidResponse(bidBuilder -> - bidBuilder.impid("123").ext(toObjectNode("banner")).mtype(1)))); + mapper.writeValueAsString( + givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("banner"))))); // when final Result> result = target.makeBids(httpCall, null); @@ -234,12 +234,8 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder() - .impid("123") - .ext(toObjectNode("banner")) - .mtype(1) - .build(), - banner, "USD")); + .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("banner")).build(), + banner, "USD")); } @Test @@ -250,10 +246,7 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js .imp(singletonList(Imp.builder().video(Video.builder().build()).id("123").build())) .build(), mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder - .impid("123") - .ext(toObjectNode("video")) - .mtype(2)))); + givenBidResponse(bidBuilder -> bidBuilder.impid("123").ext(toObjectNode("video"))))); // when final Result> result = target.makeBids(httpCall, null); @@ -261,11 +254,7 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws Js // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder() - .impid("123") - .ext(toObjectNode("video")) - .mtype(2) - .build(), + .containsExactly(BidderBid.of(Bid.builder().impid("123").ext(toObjectNode("video")).build(), video, "USD")); } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json index 2a0db948273..15089c43484 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-auction-yieldmo-response.json @@ -13,7 +13,6 @@ "crid": "crid", "w": 300, "h": 250, - "mtype": 1, "ext": { "prebid": { "type": "banner" diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json index c4e2607745a..9679171d65e 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yieldmo/test-yieldmo-bid-response.json @@ -13,7 +13,6 @@ "adm": "adm001", "h": 250, "w": 300, - "mtype": 1, "ext" : { "mediatype" : "banner" }