From 741390c4c4b372dbdbba22687774a2bf37f72bdf Mon Sep 17 00:00:00 2001 From: "Timothy M. Ace" Date: Fri, 19 May 2023 10:01:18 -0400 Subject: [PATCH 1/4] Synacormedia: Renames to "imds" to mirror golang prebid-server and marks as a deprecated alias for later removal. Core: Fixes deprecated-names feature to correctly evaluate bidder names from request.imp[].ext.prebid.bidder.* instead of request.imp[].ext.*. --- .../server/auction/BidResponseCreator.java | 9 ++- .../ImdsBidder.java} | 40 +++++++----- .../ExtImpImds.java} | 6 +- .../ExtRequestImds.java} | 4 +- ...figuration.java => ImdsConfiguration.java} | 24 +++---- src/main/resources/bidder-config/imds.yaml | 28 +++++++++ .../resources/bidder-config/synacormedia.yaml | 19 ------ .../{synacormedia.json => imds.json} | 6 +- .../auction/BidResponseCreatorTest.java | 7 ++- .../ImdsBidderTest.java} | 62 ++++++++++++------- .../{SynacormediaTest.java => ImdsTest.java} | 16 ++--- .../test-auction-imds-request.json} | 2 +- .../test-auction-imds-response.json} | 4 +- .../test-imds-bid-request.json} | 0 .../test-imds-bid-response.json} | 2 +- .../server/it/test-application.properties | 4 +- 16 files changed, 137 insertions(+), 96 deletions(-) rename src/main/java/org/prebid/server/bidder/{synacormedia/SynacormediaBidder.java => imds/ImdsBidder.java} (76%) rename src/main/java/org/prebid/server/proto/openrtb/ext/request/{synacormedia/ExtImpSynacormedia.java => imds/ExtImpImds.java} (61%) rename src/main/java/org/prebid/server/proto/openrtb/ext/request/{synacormedia/ExtRequestSynacormedia.java => imds/ExtRequestImds.java} (71%) rename src/main/java/org/prebid/server/spring/config/bidder/{SynacormediaConfiguration.java => ImdsConfiguration.java} (56%) create mode 100644 src/main/resources/bidder-config/imds.yaml delete mode 100644 src/main/resources/bidder-config/synacormedia.yaml rename src/main/resources/static/bidder-params/{synacormedia.json => imds.json} (84%) rename src/test/java/org/prebid/server/bidder/{synacormedia/SynacormediaBidderTest.java => imds/ImdsBidderTest.java} (79%) rename src/test/java/org/prebid/server/it/{SynacormediaTest.java => ImdsTest.java} (57%) rename src/test/resources/org/prebid/server/it/openrtb2/{synacormedia/test-auction-synacormedia-request.json => imds/test-auction-imds-request.json} (91%) rename src/test/resources/org/prebid/server/it/openrtb2/{synacormedia/test-auction-synacormedia-response.json => imds/test-auction-imds-response.json} (87%) rename src/test/resources/org/prebid/server/it/openrtb2/{synacormedia/test-synacormedia-bid-request.json => imds/test-imds-bid-request.json} (100%) rename src/test/resources/org/prebid/server/it/openrtb2/{synacormedia/test-synacormedia-bid-response.json => imds/test-imds-bid-response.json} (91%) diff --git a/src/main/java/org/prebid/server/auction/BidResponseCreator.java b/src/main/java/org/prebid/server/auction/BidResponseCreator.java index c00fb873b5b..e8ba23f669a 100644 --- a/src/main/java/org/prebid/server/auction/BidResponseCreator.java +++ b/src/main/java/org/prebid/server/auction/BidResponseCreator.java @@ -1052,8 +1052,13 @@ private static List errorsDetails(List errors) { */ private Map> extractDeprecatedBiddersErrors(BidRequest bidRequest) { return bidRequest.getImp().stream() - .filter(imp -> imp.getExt() != null) - .flatMap(imp -> StreamUtil.asStream(imp.getExt().fieldNames())) + .flatMap(imp -> Optional.ofNullable(imp.getExt()) + .flatMap(ext -> getExtPrebid(ext, ExtImpPrebid.class)) + .map(ExtImpPrebid::getBidder) + .map(ObjectNode::fieldNames) + .map(StreamUtil::asStream) + .orElseGet(Stream::empty) + ) .distinct() .filter(bidderCatalog::isDeprecatedName) .collect(Collectors.toMap(Function.identity(), diff --git a/src/main/java/org/prebid/server/bidder/synacormedia/SynacormediaBidder.java b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java similarity index 76% rename from src/main/java/org/prebid/server/bidder/synacormedia/SynacormediaBidder.java rename to src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java index 33f6fe168ee..8cfc45164eb 100644 --- a/src/main/java/org/prebid/server/bidder/synacormedia/SynacormediaBidder.java +++ b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java @@ -1,4 +1,4 @@ -package org.prebid.server.bidder.synacormedia; +package org.prebid.server.bidder.imds; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -20,29 +20,34 @@ import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.ExtPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtRequest; -import org.prebid.server.proto.openrtb.ext.request.synacormedia.ExtImpSynacormedia; -import org.prebid.server.proto.openrtb.ext.request.synacormedia.ExtRequestSynacormedia; +import org.prebid.server.proto.openrtb.ext.request.imds.ExtImpImds; +import org.prebid.server.proto.openrtb.ext.request.imds.ExtRequestImds; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; +import org.prebid.server.version.PrebidVersionProvider; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; -public class SynacormediaBidder implements Bidder { +public class ImdsBidder implements Bidder { - private static final TypeReference> SYNACORMEDIA_EXT_TYPE_REFERENCE = + private static final TypeReference> IMDS_EXT_TYPE_REFERENCE = new TypeReference<>() { }; private final String endpointUrl; + private final String prebidVersion; private final JacksonMapper mapper; - public SynacormediaBidder(String endpointUrl, JacksonMapper mapper) { + public ImdsBidder(String endpointUrl, PrebidVersionProvider prebidVersionProvider, JacksonMapper mapper) { this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); + this.prebidVersion = Objects.requireNonNull(prebidVersionProvider.getNameVersionRecord()); this.mapper = Objects.requireNonNull(mapper); } @@ -50,22 +55,22 @@ public SynacormediaBidder(String endpointUrl, JacksonMapper mapper) { public Result>> makeHttpRequests(BidRequest bidRequest) { final List errors = new ArrayList<>(); final List validImps = new ArrayList<>(); - ExtImpSynacormedia firstExtImp = null; + ExtImpImds firstExtImp = null; for (Imp imp : bidRequest.getImp()) { - final ExtImpSynacormedia extImpSynacormedia; + final ExtImpImds extImpImds; try { - extImpSynacormedia = parseAndValidateExtImp(imp.getExt()); + extImpImds = parseAndValidateExtImp(imp.getExt()); } catch (PreBidException e) { errors.add(BidderError.badInput("Invalid Impression: " + e.getMessage())); continue; } - final Imp updatedImp = imp.toBuilder().tagid(extImpSynacormedia.getTagId()).build(); + final Imp updatedImp = imp.toBuilder().tagid(extImpImds.getTagId()).build(); validImps.add(updatedImp); if (firstExtImp == null) { - firstExtImp = extImpSynacormedia; + firstExtImp = extImpImds; } } @@ -75,19 +80,20 @@ public Result>> makeHttpRequests(BidRequest bidRequ final BidRequest outgoingRequest = bidRequest.toBuilder() .imp(validImps) - .ext(mapper.fillExtension(ExtRequest.empty(), ExtRequestSynacormedia.of(firstExtImp.getSeatId()))) + .ext(mapper.fillExtension(ExtRequest.empty(), ExtRequestImds.of(firstExtImp.getSeatId()))) .build(); return Result.of(Collections.singletonList( BidderUtil.defaultRequest( outgoingRequest, - endpointUrl.replaceAll("\\{\\{Host}}", firstExtImp.getSeatId()), + endpointUrl.replaceAll("\\{\\{AccountID}}", URLEncoder.encode(firstExtImp.getSeatId(), StandardCharsets.UTF_8)) + .replaceAll("\\{\\{SourceId}}", URLEncoder.encode(prebidVersion, StandardCharsets.UTF_8)), mapper)), errors); } - private ExtImpSynacormedia parseAndValidateExtImp(ObjectNode impExt) { - final ExtImpSynacormedia extImp = parseExtImp(impExt); + private ExtImpImds parseAndValidateExtImp(ObjectNode impExt) { + final ExtImpImds extImp = parseExtImp(impExt); if (StringUtils.isBlank(extImp.getSeatId()) || StringUtils.isBlank(extImp.getTagId())) { throw new PreBidException("imp.ext has no seatId or tagId"); @@ -96,9 +102,9 @@ private ExtImpSynacormedia parseAndValidateExtImp(ObjectNode impExt) { return extImp; } - private ExtImpSynacormedia parseExtImp(ObjectNode impExt) { + private ExtImpImds parseExtImp(ObjectNode impExt) { try { - return mapper.mapper().convertValue(impExt, SYNACORMEDIA_EXT_TYPE_REFERENCE).getBidder(); + return mapper.mapper().convertValue(impExt, IMDS_EXT_TYPE_REFERENCE).getBidder(); } catch (IllegalArgumentException e) { throw new PreBidException(e.getMessage()); } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtImpSynacormedia.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtImpImds.java similarity index 61% rename from src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtImpSynacormedia.java rename to src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtImpImds.java index 3bab4f413ab..1cf9158cd79 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtImpSynacormedia.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtImpImds.java @@ -1,15 +1,15 @@ -package org.prebid.server.proto.openrtb.ext.request.synacormedia; +package org.prebid.server.proto.openrtb.ext.request.imds; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Value; /** - * Defines the contract for bidRequest.imp[i].ext.synacormedia + * Defines the contract for bidRequest.imp[i].ext.imds */ @AllArgsConstructor(staticName = "of") @Value -public class ExtImpSynacormedia { +public class ExtImpImds { @JsonProperty("seatId") String seatId; diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtRequestSynacormedia.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtRequestImds.java similarity index 71% rename from src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtRequestSynacormedia.java rename to src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtRequestImds.java index e8357f08d15..55d7875e7e2 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/synacormedia/ExtRequestSynacormedia.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/imds/ExtRequestImds.java @@ -1,4 +1,4 @@ -package org.prebid.server.proto.openrtb.ext.request.synacormedia; +package org.prebid.server.proto.openrtb.ext.request.imds; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -9,7 +9,7 @@ */ @AllArgsConstructor(staticName = "of") @Value -public class ExtRequestSynacormedia { +public class ExtRequestImds { @JsonProperty("seatId") String seatId; diff --git a/src/main/java/org/prebid/server/spring/config/bidder/SynacormediaConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java similarity index 56% rename from src/main/java/org/prebid/server/spring/config/bidder/SynacormediaConfiguration.java rename to src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java index 437a2abe5db..19b1e74abee 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/SynacormediaConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java @@ -1,12 +1,13 @@ package org.prebid.server.spring.config.bidder; import org.prebid.server.bidder.BidderDeps; -import org.prebid.server.bidder.synacormedia.SynacormediaBidder; +import org.prebid.server.bidder.imds.ImdsBidder; import org.prebid.server.json.JacksonMapper; import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties; import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler; import org.prebid.server.spring.config.bidder.util.UsersyncerCreator; import org.prebid.server.spring.env.YamlPropertySourceFactory; +import org.prebid.server.version.PrebidVersionProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -16,26 +17,27 @@ import javax.validation.constraints.NotBlank; @Configuration -@PropertySource(value = "classpath:/bidder-config/synacormedia.yaml", factory = YamlPropertySourceFactory.class) -public class SynacormediaConfiguration { +@PropertySource(value = "classpath:/bidder-config/imds.yaml", factory = YamlPropertySourceFactory.class) +public class ImdsConfiguration { - private static final String BIDDER_NAME = "synacormedia"; + private static final String BIDDER_NAME = "imds"; - @Bean("synacormediaConfigurationProperties") - @ConfigurationProperties("adapters.synacormedia") + @Bean("imdsConfigurationProperties") + @ConfigurationProperties("adapters.imds") BidderConfigurationProperties configurationProperties() { return new BidderConfigurationProperties(); } @Bean - BidderDeps synacormediaBidderDeps(BidderConfigurationProperties synacormediaConfigurationProperties, - @NotBlank @Value("${external-url}") String externalUrl, - JacksonMapper mapper) { + BidderDeps imdsBidderDeps(BidderConfigurationProperties imdsConfigurationProperties, + @NotBlank @Value("${external-url}") String externalUrl, + PrebidVersionProvider prebidVersionProvider, + JacksonMapper mapper) { return BidderDepsAssembler.forBidder(BIDDER_NAME) - .withConfig(synacormediaConfigurationProperties) + .withConfig(imdsConfigurationProperties) .usersyncerCreator(UsersyncerCreator.create(externalUrl)) - .bidderCreator(config -> new SynacormediaBidder(config.getEndpoint(), mapper)) + .bidderCreator(config -> new ImdsBidder(config.getEndpoint(), prebidVersionProvider, mapper)) .assemble(); } } diff --git a/src/main/resources/bidder-config/imds.yaml b/src/main/resources/bidder-config/imds.yaml new file mode 100644 index 00000000000..48d0b695ca0 --- /dev/null +++ b/src/main/resources/bidder-config/imds.yaml @@ -0,0 +1,28 @@ +adapters: + imds: + deprecated-names: synacormedia + aliases: + synacormedia: + deprecated-names: null # Must re-declare as empty or the deprecation error in the response is incorrect + endpoint: "https://pbs.technoratimedia.com/openrtb/bids/{{AccountID}}?src={{SourceId}}&adapter=synacormedia" + endpoint: "https://pbs.technoratimedia.com/openrtb/bids/{{AccountID}}?src={{SourceId}}&adapter=imds" + meta-info: + maintainer-email: eng-demand@imds.tv + app-media-types: + - banner + - video + site-media-types: + - banner + - video + supported-vendors: + vendor-id: 0 + usersync: + cookie-family-name: "imds" + iframe: + url: "https://ad-cdn.technoratimedia.com/html/usersync.html?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&cb={{redirect_url}}" + support-cors: true + uid-macro: '[USER_ID]' + redirect: + url: "https://sync.technoratimedia.com/services?srv=cs&gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&cb={{redirect_url}}" + support-cors: true + uid-macro: '[USER_ID]' diff --git a/src/main/resources/bidder-config/synacormedia.yaml b/src/main/resources/bidder-config/synacormedia.yaml deleted file mode 100644 index 60e5580d201..00000000000 --- a/src/main/resources/bidder-config/synacormedia.yaml +++ /dev/null @@ -1,19 +0,0 @@ -adapters: - synacormedia: - endpoint: http://{{Host}}.technoratimedia.com/openrtb/bids/{{Host}} - meta-info: - maintainer-email: eng-demand@imds.tv - app-media-types: - - banner - - video - site-media-types: - - banner - - video - supported-vendors: - vendor-id: 0 - usersync: - cookie-family-name: synacormedia - iframe: - url: https://ad-cdn.technoratimedia.com/html/usersync.html?cb={{redirect_url}} - support-cors: false - uid-macro: '[USER_ID]' diff --git a/src/main/resources/static/bidder-params/synacormedia.json b/src/main/resources/static/bidder-params/imds.json similarity index 84% rename from src/main/resources/static/bidder-params/synacormedia.json rename to src/main/resources/static/bidder-params/imds.json index a5ba863999a..8a71229fba7 100644 --- a/src/main/resources/static/bidder-params/synacormedia.json +++ b/src/main/resources/static/bidder-params/imds.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Synacormedia Adapter Params", - "description": "A schema which validates params accepted by the Synacormedia adapter", + "title": "iMDS Adapter Params", + "description": "A schema which validates params accepted by the iMDS adapter", "type": "object", "properties": { "seatId": { @@ -16,4 +16,4 @@ "required": [ "seatId" ] -} \ No newline at end of file +} diff --git a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java index 27e7e82aab6..f8d7aa9ba19 100644 --- a/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java +++ b/src/test/java/org/prebid/server/auction/BidResponseCreatorTest.java @@ -2916,7 +2916,12 @@ public void shouldProcessRequestAndAddErrorAboutDeprecatedBidder() { final String invalidBidderName = "invalid"; final BidRequest bidRequest = givenBidRequest(Imp.builder() - .ext(mapper.valueToTree(singletonMap(invalidBidderName, 0))) + .ext(mapper.valueToTree( + ExtImp.of(ExtImpPrebid.builder() + .bidder(mapper.valueToTree(singletonMap(invalidBidderName, 0))) + .build(), + null) + )) .build()); final List bidderResponses = singletonList(BidderResponse.of("bidder1", givenSeatBid(), 100)); diff --git a/src/test/java/org/prebid/server/bidder/synacormedia/SynacormediaBidderTest.java b/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java similarity index 79% rename from src/test/java/org/prebid/server/bidder/synacormedia/SynacormediaBidderTest.java rename to src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java index 0e9a43cc8b0..e217ef0c6c9 100644 --- a/src/test/java/org/prebid/server/bidder/synacormedia/SynacormediaBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java @@ -1,4 +1,4 @@ -package org.prebid.server.bidder.synacormedia; +package org.prebid.server.bidder.imds; import com.fasterxml.jackson.core.JsonProcessingException; import com.iab.openrtb.request.Audio; @@ -11,7 +11,11 @@ import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.prebid.server.VertxTest; import org.prebid.server.bidder.model.BidderBid; import org.prebid.server.bidder.model.BidderCall; @@ -21,8 +25,9 @@ import org.prebid.server.bidder.model.Result; import org.prebid.server.proto.openrtb.ext.ExtPrebid; import org.prebid.server.proto.openrtb.ext.request.ExtRequest; -import org.prebid.server.proto.openrtb.ext.request.synacormedia.ExtImpSynacormedia; -import org.prebid.server.proto.openrtb.ext.request.synacormedia.ExtRequestSynacormedia; +import org.prebid.server.proto.openrtb.ext.request.imds.ExtImpImds; +import org.prebid.server.proto.openrtb.ext.request.imds.ExtRequestImds; +import org.prebid.server.version.PrebidVersionProvider; import java.util.List; import java.util.function.Function; @@ -32,23 +37,32 @@ import static java.util.function.Function.identity; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.Mockito.when; import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; import static org.prebid.server.proto.openrtb.ext.response.BidType.video; -public class SynacormediaBidderTest extends VertxTest { +public class ImdsBidderTest extends VertxTest { - private static final String ENDPOINT_URL = "https://{{Host}}.endpoint.com/{{Host}}"; + private static final String ENDPOINT_URL = "https://pbs.endpoint.com/{{AccountID}}?src={{SourceId}}&adapter=imds"; - private SynacormediaBidder synacormediaBidder; + private ImdsBidder imdsBidder; + + @Rule + public final MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private PrebidVersionProvider prebidVersionProvider; @Before public void setUp() { - synacormediaBidder = new SynacormediaBidder(ENDPOINT_URL, jacksonMapper); + when(prebidVersionProvider.getNameVersionRecord()).thenReturn("pbs-java/0.1.2"); + imdsBidder = new ImdsBidder(ENDPOINT_URL, prebidVersionProvider, jacksonMapper); } @Test public void creationShouldFailOnInvalidEndpointUrl() { - assertThatIllegalArgumentException().isThrownBy(() -> new SynacormediaBidder("invalid_url", jacksonMapper)); + assertThatIllegalArgumentException().isThrownBy( + () -> new ImdsBidder("invalid_url", prebidVersionProvider, jacksonMapper)); } @Test @@ -59,7 +73,7 @@ public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed() { identity()); // when - final Result>> result = synacormediaBidder.makeHttpRequests(bidRequest); + final Result>> result = imdsBidder.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).hasSize(1) @@ -79,7 +93,7 @@ public void makeHttpRequestsShouldExcludeInvalidImpAndReturnExpectedResult() { .build(); // when - final Result>> result = synacormediaBidder.makeHttpRequests(bidRequest); + final Result>> result = imdsBidder.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).hasSize(1); @@ -87,7 +101,7 @@ public void makeHttpRequestsShouldExcludeInvalidImpAndReturnExpectedResult() { .extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class)) .containsOnly(BidRequest.builder() .imp(singletonList(givenImp(identity()).toBuilder().tagid("tagId").build())) - .ext(jacksonMapper.fillExtension(ExtRequest.empty(), ExtRequestSynacormedia.of("seatId"))) + .ext(jacksonMapper.fillExtension(ExtRequest.empty(), ExtRequestImds.of("seatId"))) .build()); } @@ -96,11 +110,11 @@ public void makeHttpRequestsShouldReturnErrorIfFirstValidImpHasEmptySeatId() { // given final BidRequest bidRequest = givenBidRequest( impBuilder -> impBuilder.ext(mapper.valueToTree( - ExtPrebid.of(null, ExtImpSynacormedia.of(" ", "tagId")))), + ExtPrebid.of(null, ExtImpImds.of(" ", "tagId")))), identity()); // when - final Result>> result = synacormediaBidder.makeHttpRequests(bidRequest); + final Result>> result = imdsBidder.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).hasSize(1) @@ -114,11 +128,11 @@ public void makeHttpRequestsShouldReturnErrorIfFirstValidImpHasEmptyTagId() { // given final BidRequest bidRequest = givenBidRequest( impBuilder -> impBuilder.ext(mapper.valueToTree( - ExtPrebid.of(null, ExtImpSynacormedia.of("seadId", " ")))), + ExtPrebid.of(null, ExtImpImds.of("seadId", " ")))), identity()); // when - final Result>> result = synacormediaBidder.makeHttpRequests(bidRequest); + final Result>> result = imdsBidder.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).hasSize(1) @@ -133,13 +147,13 @@ public void makeHttpRequestsShouldReturnSingleHttpRequestWithExpectedUri() { final BidRequest bidRequest = givenBidRequest(identity(), identity()); // when - final Result>> result = synacormediaBidder.makeHttpRequests(bidRequest); + final Result>> result = imdsBidder.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()).hasSize(1) .extracting(HttpRequest::getUri) - .containsOnly("https://seatId.endpoint.com/seatId"); + .containsOnly("https://pbs.endpoint.com/seatId?src=pbs-java%2F0.1.2&adapter=imds"); } @Test @@ -148,7 +162,7 @@ public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { final BidderCall httpCall = givenHttpCall(null, "invalid"); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).hasSize(1) @@ -164,7 +178,7 @@ public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProces mapper.writeValueAsString(null)); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -178,7 +192,7 @@ public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws Jso mapper.writeValueAsString(BidResponse.builder().build())); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -199,7 +213,7 @@ public void makeBidsShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessi givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -221,7 +235,7 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentAndNoBanner() throws Jso givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -243,7 +257,7 @@ public void makeBidsShouldReturnEmptyListIfFoundNotVideoOrBannerObject() givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); // when - final Result> result = synacormediaBidder.makeBids(httpCall, null); + final Result> result = imdsBidder.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); @@ -260,7 +274,7 @@ private static BidRequest givenBidRequest( private static Imp givenImp(Function impCustomizer) { return impCustomizer.apply(Imp.builder() - .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpSynacormedia.of("seatId", "tagId"))))) + .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpImds.of("seatId", "tagId"))))) .build(); } diff --git a/src/test/java/org/prebid/server/it/SynacormediaTest.java b/src/test/java/org/prebid/server/it/ImdsTest.java similarity index 57% rename from src/test/java/org/prebid/server/it/SynacormediaTest.java rename to src/test/java/org/prebid/server/it/ImdsTest.java index ee480eb15dc..38cf0c7c715 100644 --- a/src/test/java/org/prebid/server/it/SynacormediaTest.java +++ b/src/test/java/org/prebid/server/it/ImdsTest.java @@ -16,22 +16,22 @@ import static java.util.Collections.singletonList; @RunWith(SpringRunner.class) -public class SynacormediaTest extends IntegrationTest { +public class ImdsTest extends IntegrationTest { @Test - public void openrtb2AuctionShouldRespondWithBidsFromSynacorMedia() throws IOException, JSONException { + public void openrtb2AuctionShouldRespondWithBidsFromImds() throws IOException, JSONException { // given - WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/synacormedia-exchange/seat_id")) - .withRequestBody(equalToJson(jsonFrom("openrtb2/synacormedia/test-synacormedia-bid-request.json"))) + WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/imds-exchange")) + .withRequestBody(equalToJson(jsonFrom("openrtb2/imds/test-imds-bid-request.json"))) .willReturn(aResponse().withBody( - jsonFrom("openrtb2/synacormedia/test-synacormedia-bid-response.json")))); + jsonFrom("openrtb2/imds/test-imds-bid-response.json")))); // when - final Response response = responseFor("openrtb2/synacormedia/test-auction-synacormedia-request.json", + final Response response = responseFor("openrtb2/imds/test-auction-imds-request.json", Endpoint.openrtb2_auction); // then - assertJsonEquals("openrtb2/synacormedia/test-auction-synacormedia-response.json", response, - singletonList("synacormedia")); + assertJsonEquals("openrtb2/imds/test-auction-imds-response.json", response, + singletonList("imds")); } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-request.json b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-request.json similarity index 91% rename from src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-request.json rename to src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-request.json index 34ec6de658f..905bb0deaba 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-request.json @@ -8,7 +8,7 @@ "h": 250 }, "ext": { - "synacormedia": { + "imds": { "seatId": "seat_id", "tagId": "tag_id" } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-response.json b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-response.json similarity index 87% rename from src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-response.json rename to src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-response.json index 1f7ce402a5d..42b87323685 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-auction-synacormedia-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-auction-imds-response.json @@ -21,14 +21,14 @@ } } ], - "seat": "synacormedia", + "seat": "imds", "group": 0 } ], "cur": "USD", "ext": { "responsetimemillis": { - "synacormedia": "{{ synacormedia.response_time_ms }}" + "imds": "{{ imds.response_time_ms }}" }, "prebid": { "auctiontimestamp": 0 diff --git a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-synacormedia-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-imds-bid-request.json similarity index 100% rename from src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-synacormedia-bid-request.json rename to src/test/resources/org/prebid/server/it/openrtb2/imds/test-imds-bid-request.json diff --git a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-synacormedia-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-imds-bid-response.json similarity index 91% rename from src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-synacormedia-bid-response.json rename to src/test/resources/org/prebid/server/it/openrtb2/imds/test-imds-bid-response.json index d9ae07cf3a9..0a9f1073cf4 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/synacormedia/test-synacormedia-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/imds/test-imds-bid-response.json @@ -15,7 +15,7 @@ "w": 300 } ], - "seat": "synacormedia" + "seat": "imds" } ] } 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 2461b2e11ad..b8199eaa079 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -171,6 +171,8 @@ adapters.grid.enabled=true adapters.grid.endpoint=http://localhost:8090/grid-exchange adapters.gumgum.enabled=true adapters.gumgum.endpoint=http://localhost:8090/gumgum-exchange +adapters.imds.enabled=true +adapters.imds.endpoint=http://localhost:8090/imds-exchange adapters.impactify.enabled=true adapters.impactify.endpoint=http://localhost:8090/impactify-exchange adapters.improvedigital.enabled=true @@ -299,8 +301,6 @@ adapters.sovrn.enabled=true adapters.sovrn.endpoint=http://localhost:8090/sovrn-exchange adapters.sspbc.enabled=true adapters.sspbc.endpoint=http://localhost:8090/sspbc-exchange -adapters.synacormedia.enabled=true -adapters.synacormedia.endpoint=http://localhost:8090/synacormedia-exchange/{{Host}} adapters.sharethrough.enabled=true adapters.sharethrough.endpoint=http://localhost:8090/sharethrough-exchange adapters.silvermob.enabled=true From f78703225c37472a32aafb80edb586d7233c733b Mon Sep 17 00:00:00 2001 From: "Timothy M. Ace" Date: Wed, 7 Jun 2023 11:59:30 -0400 Subject: [PATCH 2/4] imds: shorten some lines longer than 120 characters to get builds to pass --- .../java/org/prebid/server/bidder/imds/ImdsBidder.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java index 8cfc45164eb..20dcc5499c4 100644 --- a/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java +++ b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java @@ -86,8 +86,11 @@ public Result>> makeHttpRequests(BidRequest bidRequ return Result.of(Collections.singletonList( BidderUtil.defaultRequest( outgoingRequest, - endpointUrl.replaceAll("\\{\\{AccountID}}", URLEncoder.encode(firstExtImp.getSeatId(), StandardCharsets.UTF_8)) - .replaceAll("\\{\\{SourceId}}", URLEncoder.encode(prebidVersion, StandardCharsets.UTF_8)), + endpointUrl + .replaceAll("\\{\\{AccountID}}", + URLEncoder.encode(firstExtImp.getSeatId(), StandardCharsets.UTF_8)) + .replaceAll("\\{\\{SourceId}}", + URLEncoder.encode(prebidVersion, StandardCharsets.UTF_8)), mapper)), errors); } From 0c8f799794f46178038ed9f201d3fa731b6db687 Mon Sep 17 00:00:00 2001 From: "Timothy M. Ace" Date: Mon, 26 Jun 2023 19:19:00 -0400 Subject: [PATCH 3/4] CAPT-787: Add gpp macros to imds usersync --- src/main/resources/bidder-config/imds.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/bidder-config/imds.yaml b/src/main/resources/bidder-config/imds.yaml index 48d0b695ca0..c4fe20a882c 100644 --- a/src/main/resources/bidder-config/imds.yaml +++ b/src/main/resources/bidder-config/imds.yaml @@ -19,10 +19,10 @@ adapters: usersync: cookie-family-name: "imds" iframe: - url: "https://ad-cdn.technoratimedia.com/html/usersync.html?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&cb={{redirect_url}}" + url: "https://ad-cdn.technoratimedia.com/html/usersync.html?gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gppsid={{gpp_sid}}&cb={{redirect_url}}" support-cors: true uid-macro: '[USER_ID]' redirect: - url: "https://sync.technoratimedia.com/services?srv=cs&gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&cb={{redirect_url}}" + url: "https://sync.technoratimedia.com/services?srv=cs&gdpr={{gdpr}}&consent={{gdpr_consent}}&us_privacy={{us_privacy}}&gpp={{gpp}}&gppsid={{gpp_sid}}&cb={{redirect_url}}" support-cors: true uid-macro: '[USER_ID]' From b9d61cc1ba88476ad299dbdb4b9a53664ee3078d Mon Sep 17 00:00:00 2001 From: "Timothy M. Ace" Date: Fri, 30 Jun 2023 10:20:40 -0400 Subject: [PATCH 4/4] imds: Break out endpoint generation into new method and change to passing version as string rather than object. --- .../prebid/server/bidder/imds/ImdsBidder.java | 33 +++++++++++-------- .../config/bidder/ImdsConfiguration.java | 6 +++- .../server/bidder/imds/ImdsBidderTest.java | 7 ++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java index 20dcc5499c4..6261679a753 100644 --- a/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java +++ b/src/main/java/org/prebid/server/bidder/imds/ImdsBidder.java @@ -25,7 +25,6 @@ import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; -import org.prebid.server.version.PrebidVersionProvider; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -45,9 +44,9 @@ public class ImdsBidder implements Bidder { private final String prebidVersion; private final JacksonMapper mapper; - public ImdsBidder(String endpointUrl, PrebidVersionProvider prebidVersionProvider, JacksonMapper mapper) { + public ImdsBidder(String endpointUrl, String prebidVersion, JacksonMapper mapper) { this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); - this.prebidVersion = Objects.requireNonNull(prebidVersionProvider.getNameVersionRecord()); + this.prebidVersion = Objects.requireNonNull(prebidVersion); this.mapper = Objects.requireNonNull(mapper); } @@ -83,16 +82,24 @@ public Result>> makeHttpRequests(BidRequest bidRequ .ext(mapper.fillExtension(ExtRequest.empty(), ExtRequestImds.of(firstExtImp.getSeatId()))) .build(); - return Result.of(Collections.singletonList( + return Result.of( + Collections.singletonList( BidderUtil.defaultRequest( - outgoingRequest, - endpointUrl - .replaceAll("\\{\\{AccountID}}", - URLEncoder.encode(firstExtImp.getSeatId(), StandardCharsets.UTF_8)) - .replaceAll("\\{\\{SourceId}}", - URLEncoder.encode(prebidVersion, StandardCharsets.UTF_8)), - mapper)), - errors); + outgoingRequest, + generateEndpointUrl(firstExtImp), + mapper + ) + ), + errors + ); + } + + private String generateEndpointUrl(ExtImpImds firstExtImp) { + final String accountId = URLEncoder.encode(firstExtImp.getSeatId(), StandardCharsets.UTF_8); + final String sourceId = URLEncoder.encode(prebidVersion, StandardCharsets.UTF_8); + return endpointUrl + .replaceAll("\\{\\{AccountID}}", accountId) + .replaceAll("\\{\\{SourceId}}", sourceId); } private ExtImpImds parseAndValidateExtImp(ObjectNode impExt) { @@ -149,7 +156,7 @@ private static BidderBid mapBidToBidderBid(Bid bid, List imps, String curre } private static BidType getBidType(String impId, List imps) { - for (Imp imp : imps) { + for (final Imp imp : imps) { if (imp.getId().equals(impId)) { if (imp.getBanner() != null) { return BidType.banner; diff --git a/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java index 19b1e74abee..3128eab5de9 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/ImdsConfiguration.java @@ -37,7 +37,11 @@ BidderDeps imdsBidderDeps(BidderConfigurationProperties imdsConfigurationPropert return BidderDepsAssembler.forBidder(BIDDER_NAME) .withConfig(imdsConfigurationProperties) .usersyncerCreator(UsersyncerCreator.create(externalUrl)) - .bidderCreator(config -> new ImdsBidder(config.getEndpoint(), prebidVersionProvider, mapper)) + .bidderCreator(config -> new ImdsBidder( + config.getEndpoint(), + prebidVersionProvider.getNameVersionRecord(), + mapper) + ) .assemble(); } } diff --git a/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java b/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java index e217ef0c6c9..c7aa682442a 100644 --- a/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/imds/ImdsBidderTest.java @@ -37,13 +37,13 @@ import static java.util.function.Function.identity; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.when; import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; import static org.prebid.server.proto.openrtb.ext.response.BidType.video; public class ImdsBidderTest extends VertxTest { private static final String ENDPOINT_URL = "https://pbs.endpoint.com/{{AccountID}}?src={{SourceId}}&adapter=imds"; + private static final String PREBID_VERSION = "pbs-java/0.1.2"; private ImdsBidder imdsBidder; @@ -55,14 +55,13 @@ public class ImdsBidderTest extends VertxTest { @Before public void setUp() { - when(prebidVersionProvider.getNameVersionRecord()).thenReturn("pbs-java/0.1.2"); - imdsBidder = new ImdsBidder(ENDPOINT_URL, prebidVersionProvider, jacksonMapper); + imdsBidder = new ImdsBidder(ENDPOINT_URL, PREBID_VERSION, jacksonMapper); } @Test public void creationShouldFailOnInvalidEndpointUrl() { assertThatIllegalArgumentException().isThrownBy( - () -> new ImdsBidder("invalid_url", prebidVersionProvider, jacksonMapper)); + () -> new ImdsBidder("invalid_url", PREBID_VERSION, jacksonMapper)); } @Test