diff --git a/src/main/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidder.java b/src/main/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidder.java index f2228778feb..1e8c928eb48 100644 --- a/src/main/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidder.java +++ b/src/main/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidder.java @@ -186,12 +186,59 @@ private ExtImpRtbhouse parseImpExt(Imp imp) { private static Imp modifyImp(Imp imp, Price bidFloorPrice) { return imp.toBuilder() + .tagid(extractTagId(imp)) .bidfloorcur(ObjectUtil.getIfNotNull(bidFloorPrice, Price::getCurrency)) .bidfloor(ObjectUtil.getIfNotNull(bidFloorPrice, Price::getValue)) .pmp(null) .build(); } + private static String extractTagId(Imp imp) { + final String existingTagid = imp.getTagid(); + if (StringUtils.isNotBlank(existingTagid)) { + return existingTagid; + } + + return extractTagIdFromExt(imp); + } + + private static String extractTagIdFromExt(Imp imp) { + return Optional.ofNullable(imp.getExt()) + .flatMap(ext -> extractGpid(ext)) + .orElseGet(() -> extractFromData(imp)); + } + + private static Optional extractGpid(JsonNode ext) { + return Optional.ofNullable(ext.get("gpid")) + .filter(JsonNode::isTextual) + .map(JsonNode::asText) + .filter(StringUtils::isNotBlank); + } + + private static String extractFromData(Imp imp) { + return Optional.ofNullable(imp.getExt()) + .map(ext -> ext.get("data")) + .filter(JsonNode::isObject) + .flatMap(data -> extractAdslot(data).or(() -> extractPbadslot(data))) + .orElseGet(() -> Optional.ofNullable(imp.getId()).filter(StringUtils::isNotBlank).orElse(null)); + } + + private static Optional extractAdslot(JsonNode data) { + return Optional.ofNullable(data.get("adserver")) + .filter(JsonNode::isObject) + .map(adserver -> adserver.get("adslot")) + .filter(JsonNode::isTextual) + .map(JsonNode::asText) + .filter(StringUtils::isNotBlank); + } + + private static Optional extractPbadslot(JsonNode data) { + return Optional.ofNullable(data.get("pbadslot")) + .filter(JsonNode::isTextual) + .map(JsonNode::asText) + .filter(StringUtils::isNotBlank); + } + private Price resolveBidFloor(Imp imp, ExtImpRtbhouse impExt, BidRequest bidRequest) { final List brCur = bidRequest.getCur(); final Price initialBidFloorPrice = Price.of(imp.getBidfloorcur(), imp.getBidfloor()); diff --git a/src/test/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidderTest.java b/src/test/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidderTest.java index fe10dad45e3..b0f5b7a247c 100644 --- a/src/test/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/rtbhouse/RtbhouseBidderTest.java @@ -518,6 +518,147 @@ public void makeHttpRequestsShouldAlwaysRemovePmpField() { .containsOnlyNulls(); } + @Test + public void makeHttpRequestsShouldSetTagidFromGpid() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(Imp.builder() + .id("imp123") + .ext(givenRtbhouseExt(node -> node.put("gpid", "gpid_value"))) + .build())) + .id("request_id") + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("gpid_value"); + } + + @Test + public void makeHttpRequestsShouldSetTagidFromAdserverAdslot() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(Imp.builder() + .id("imp123") + .ext(givenRtbhouseExt(node -> node.set("data", mapper.createObjectNode() + .set("adserver", mapper.createObjectNode().put("adslot", "adslot_value"))))) + .build())) + .id("request_id") + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("adslot_value"); + } + + @Test + public void makeHttpRequestsShouldSetTagidFromPbadslot() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(Imp.builder() + .id("imp123") + .ext(givenRtbhouseExt(node -> node.set("data", mapper.createObjectNode() + .put("pbadslot", "pbadslot_value")))) + .build())) + .id("request_id") + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("pbadslot_value"); + } + + @Test + public void makeHttpRequestsShouldSetTagidFromImpIdWhenNoOtherFields() { + // given + final BidRequest bidRequest = givenBidRequest( + bidReq -> bidReq.id("request_id"), + imp -> imp.id("imp123"), + identity()); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("imp123"); + } + + @Test + public void makeHttpRequestsShouldSetTagidToNullWhenNoFieldsAvailable() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(Imp.builder() + .id(null) + .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpRtbhouse.builder() + .publisherId("publisherId") + .region("region") + .build()))) + .build())) + .id("request_id") + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsOnlyNulls(); + } + + @Test + public void makeHttpRequestsShouldPreserveExistingTagid() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(Imp.builder() + .id("imp123") + .tagid("existing_tagid") + .ext(givenRtbhouseExt(node -> node.put("gpid", "gpid_value"))) + .build())) + .id("request_id") + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("existing_tagid"); + } + private static BidResponse givenBidResponse(Function bidCustomizer) { return BidResponse.builder() .cur("USD") @@ -562,4 +703,12 @@ private static Imp givenImp(Function impCustomiz .build())))) .build(); } + + private static ObjectNode givenRtbhouseExt(Function extCustomizer) { + final ObjectNode extNode = (ObjectNode) mapper.valueToTree(ExtPrebid.of(null, ExtImpRtbhouse.builder() + .publisherId("publisherId") + .region("region") + .build())); + return extCustomizer.apply(extNode); + } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/rtbhouse/test-rtbhouse-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/rtbhouse/test-rtbhouse-bid-request.json index e63afde3937..28d0438942f 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/rtbhouse/test-rtbhouse-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/rtbhouse/test-rtbhouse-bid-request.json @@ -13,7 +13,8 @@ "bidder": { "publisherId": "publisherId" } - } + }, + "tagid": "imp_id" } ], "source": {