From a5561642aa38a06dce089c7e2e7e96afb27fa87b Mon Sep 17 00:00:00 2001 From: antonbabak Date: Tue, 6 May 2025 10:44:57 +0200 Subject: [PATCH] TheTradeDesk: Dynamically construct endpoint using supplySourceId --- .../thetradedesk/TheTradeDeskBidder.java | 22 ++++---- .../thetradedesk/ExtImpTheTradeDesk.java | 3 ++ .../static/bidder-params/thetradedesk.json | 10 ++-- .../thetradedesk/TheTradeDeskBidderTest.java | 50 ++++++++++++++++--- .../test-auction-thetradedesk-request.json | 3 +- .../test-thetradedesk-bid-request.json | 3 +- .../server/it/test-application.properties | 1 - 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidder.java b/src/main/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidder.java index 94913a36213..99f5eda1ec2 100644 --- a/src/main/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidder.java +++ b/src/main/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidder.java @@ -11,8 +11,8 @@ import com.iab.openrtb.response.Bid; import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; -import io.vertx.core.MultiMap; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.prebid.server.bidder.Bidder; import org.prebid.server.bidder.model.BidderBid; @@ -42,11 +42,6 @@ public class TheTradeDeskBidder implements Bidder { new TypeReference<>() { }; - private static final String PREBID_INTEGRATION_TYPE_HEADER = "x-integration-type"; - private static final String PREBID_INTEGRATION_TYPE = "1"; - private static final MultiMap HEADERS = HttpUtil.headers() - .add(PREBID_INTEGRATION_TYPE_HEADER, PREBID_INTEGRATION_TYPE); - private static final String SUPPLY_ID_MACRO = "{{SupplyId}}"; private static final Pattern SUPPLY_ID_PATTERN = Pattern.compile("([a-z]+)$"); @@ -73,6 +68,7 @@ public Result>> makeHttpRequests(BidRequest request final List modifiedImps = new ArrayList<>(); String publisherId = null; + String sourceSupplyId = null; for (Imp imp : request.getImp()) { try { final ExtImpTheTradeDesk extImp = parseImpExt(imp); @@ -82,6 +78,11 @@ public Result>> makeHttpRequests(BidRequest request ? extImpPublisherId : publisherId; + final String extImpSourceSupplyId = extImp.getSupplySourceId(); + sourceSupplyId = sourceSupplyId == null && StringUtils.isNotBlank(extImpSourceSupplyId) + ? extImpSourceSupplyId + : sourceSupplyId; + modifiedImps.add(modifyImp(imp)); } catch (PreBidException e) { return Result.withError(BidderError.badInput(e.getMessage())); @@ -91,8 +92,7 @@ public Result>> makeHttpRequests(BidRequest request final BidRequest outgoingRequest = modifyRequest(request, modifiedImps, publisherId); final HttpRequest httpRequest = BidderUtil.defaultRequest( outgoingRequest, - HEADERS, - resolveEndpoint(), + resolveEndpoint(sourceSupplyId), mapper); return Result.withValue(httpRequest); @@ -165,8 +165,10 @@ private static App modifyApp(BidRequest request, String publisherId) { .build(); } - private String resolveEndpoint() { - return endpointUrl.replace(SUPPLY_ID_MACRO, HttpUtil.encodeUrl(StringUtils.defaultString(supplyId))); + private String resolveEndpoint(String sourceSupplyId) { + return endpointUrl.replace( + SUPPLY_ID_MACRO, + HttpUtil.encodeUrl(StringUtils.defaultString(ObjectUtils.defaultIfNull(sourceSupplyId, supplyId)))); } @Override diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/thetradedesk/ExtImpTheTradeDesk.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/thetradedesk/ExtImpTheTradeDesk.java index ee3b9cc7d83..91a3b8e14b2 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/thetradedesk/ExtImpTheTradeDesk.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/thetradedesk/ExtImpTheTradeDesk.java @@ -8,4 +8,7 @@ public class ExtImpTheTradeDesk { @JsonProperty("publisherId") String publisherId; + + @JsonProperty("supplySourceId") + String supplySourceId; } diff --git a/src/main/resources/static/bidder-params/thetradedesk.json b/src/main/resources/static/bidder-params/thetradedesk.json index d0b305a5a1e..566e7e556e6 100644 --- a/src/main/resources/static/bidder-params/thetradedesk.json +++ b/src/main/resources/static/bidder-params/thetradedesk.json @@ -6,10 +6,14 @@ "properties": { "publisherId": { "type": "string", + "minLength": 1, "description": "An ID which identifies the publisher" + }, + "supplySourceId": { + "type":"string", + "minLength": 1, + "description": "An ID provided by TheTradeDesk used to determine which endpoint to use" } }, - "required": [ - "publisherId" - ] + "required": ["publisherId"] } diff --git a/src/test/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidderTest.java b/src/test/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidderTest.java index 4fee1810ad3..021bca5617a 100644 --- a/src/test/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/thetradedesk/TheTradeDeskBidderTest.java @@ -95,14 +95,12 @@ public void makeHttpRequestsShouldReturnExpectedHeaders() { .satisfies(headers -> assertThat(headers.get(CONTENT_TYPE_HEADER)) .isEqualTo(APPLICATION_JSON_CONTENT_TYPE)) .satisfies(headers -> assertThat(headers.get(ACCEPT_HEADER)) - .isEqualTo(APPLICATION_JSON_VALUE)) - .satisfies(headers -> assertThat(headers.get("x-integration-type")) - .isEqualTo("1")); + .isEqualTo(APPLICATION_JSON_VALUE)); assertThat(result.getErrors()).isEmpty(); } @Test - public void makeHttpRequestsShouldUseCorrectUri() { + public void makeHttpRequestsShouldUseConfiguredSupplyIdWhenImpExtSupplyIdIsNotProvided() { // given final BidRequest bidRequest = givenBidRequest(identity(), identity()); @@ -116,6 +114,42 @@ public void makeHttpRequestsShouldUseCorrectUri() { .containsExactly("https://test.endpoint.com/supplyid"); } + @Test + public void makeHttpRequestsShouldUseImpExtSupplyIdWhenProvided() { + // given + final BidRequest bidRequest = givenBidRequest( + identity(), + imp -> imp.ext(impExt("publisher", "supplySourceId"))); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly("https://test.endpoint.com/supplySourceId"); + } + + @Test + public void makeHttpRequestsShouldUseFirstFoundSupplySourceId() { + // given + final BidRequest bidRequest = givenBidRequest( + identity(), + imp -> imp.ext(impExt("publisher", null)), + imp -> imp.ext(impExt("publisher", "supplySourceId1")), + imp -> imp.ext(impExt("publisher", "supplySourceId2"))); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly("https://test.endpoint.com/supplySourceId1"); + } + @Test public void makeHttpRequestsShouldHaveImpIds() { // given @@ -259,7 +293,7 @@ public void makeHttpRequestsShouldReturnAppWithExtImpPublisherWhenAppWithoutPubl } @Test - public void makeHttpRequestsShouldReturnAppWithPublisherOfTheFirsrExtImp() { + public void makeHttpRequestsShouldReturnAppWithPublisherOfTheFirstExtImp() { final BidRequest bidRequest = givenBidRequest( request -> request.app(App.builder().build()), imp -> imp.ext(impExt("newPublisher")), @@ -453,7 +487,11 @@ private static Imp givenImp(UnaryOperator impCustomizer) { } private static ObjectNode impExt(String publisherId) { - return mapper.valueToTree(ExtPrebid.of(null, ExtImpTheTradeDesk.of(publisherId))); + return impExt(publisherId, null); + } + + private static ObjectNode impExt(String publisherId, String supplySourceId) { + return mapper.valueToTree(ExtPrebid.of(null, ExtImpTheTradeDesk.of(publisherId, supplySourceId))); } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-auction-thetradedesk-request.json b/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-auction-thetradedesk-request.json index 2f1bdf270d1..e3fba9cb248 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-auction-thetradedesk-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-auction-thetradedesk-request.json @@ -9,7 +9,8 @@ }, "ext": { "thetradedesk": { - "publisherId": "publisherId" + "publisherId": "publisherId", + "supplySourceId": "somesupplyid" } } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-thetradedesk-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-thetradedesk-bid-request.json index fde2176c406..cdcce478087 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-thetradedesk-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/thetradedesk/test-thetradedesk-bid-request.json @@ -11,7 +11,8 @@ "ext": { "tid": "${json-unit.any-string}", "bidder": { - "publisherId": "publisherId" + "publisherId": "publisherId", + "supplySourceId": "somesupplyid" } } } diff --git a/src/test/resources/org/prebid/server/it/test-application.properties b/src/test/resources/org/prebid/server/it/test-application.properties index bf0af8f2c13..fa3c8462770 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -505,7 +505,6 @@ adapters.tradplus.enabled=true adapters.tradplus.endpoint=http://{{ZoneID}}localhost:8090/{{AccountID}}/tradplus-exchange adapters.thetradedesk.enabled=true adapters.thetradedesk.endpoint=http://localhost:8090/thetradedesk-exchange/{{SupplyId}} -adapters.thetradedesk.extra-info.supply-id=somesupplyid adapters.triplelift.enabled=true adapters.triplelift.endpoint=http://localhost:8090/triplelift-exchange adapters.tripleliftnative.enabled=true