From 3157843d2bd2753e93e57a4170d82053fc21ffff Mon Sep 17 00:00:00 2001 From: Tushar Singh Date: Wed, 4 Aug 2021 21:12:36 +0530 Subject: [PATCH 01/13] Added medianet adapter (#1378) --- .../bidder/medianet/MedianetBidder.java | 18 +++ .../config/bidder/MedianetConfiguration.java | 57 +++++++ .../resources/bidder-config/medianet.yaml | 27 ++++ .../static/bidder-params/medianet.json | 20 +++ .../bidder/medianet/MedianetBidderTest.java | 145 ++++++++++++++++++ .../org/prebid/server/it/MedianetTest.java | 36 +++++ .../test-auction-medianet-request.json | 24 +++ .../test-auction-medianet-response.json | 38 +++++ .../medianet/test-medianet-bid-request.json | 42 +++++ .../medianet/test-medianet-bid-response.json | 22 +++ .../server/it/test-application.properties | 2 + 11 files changed, 431 insertions(+) create mode 100644 src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java create mode 100644 src/main/java/org/prebid/server/spring/config/bidder/MedianetConfiguration.java create mode 100644 src/main/resources/bidder-config/medianet.yaml create mode 100644 src/main/resources/static/bidder-params/medianet.json create mode 100644 src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java create mode 100644 src/test/java/org/prebid/server/it/MedianetTest.java create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-request.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-response.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-request.json create mode 100644 src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-response.json diff --git a/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java b/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java new file mode 100644 index 00000000000..90bddd0419c --- /dev/null +++ b/src/main/java/org/prebid/server/bidder/medianet/MedianetBidder.java @@ -0,0 +1,18 @@ +package org.prebid.server.bidder.medianet; + +import org.prebid.server.bidder.Bidder; +import org.prebid.server.bidder.OpenrtbBidder; +import org.prebid.server.json.JacksonMapper; + +/** + * Medianet {@link Bidder} implementation. + */ +public class MedianetBidder extends OpenrtbBidder { + + public MedianetBidder(String endpointUrl, JacksonMapper mapper) { + super(endpointUrl, + RequestCreationStrategy.SINGLE_REQUEST, + Void.class, + mapper); + } +} diff --git a/src/main/java/org/prebid/server/spring/config/bidder/MedianetConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/MedianetConfiguration.java new file mode 100644 index 00000000000..90a061c6150 --- /dev/null +++ b/src/main/java/org/prebid/server/spring/config/bidder/MedianetConfiguration.java @@ -0,0 +1,57 @@ +package org.prebid.server.spring.config.bidder; + +import org.prebid.server.bidder.BidderDeps; +import org.prebid.server.bidder.medianet.MedianetBidder; +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.util.HttpUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +import javax.validation.constraints.NotBlank; + +@Configuration +@PropertySource(value = "classpath:/bidder-config/medianet.yaml", factory = YamlPropertySourceFactory.class) +public class MedianetConfiguration { + + private static final String BIDDER_NAME = "medianet"; + private static final String EXTERNAL_URL_MACRO = "{{PREBID_SERVER_ENDPOINT}}"; + + @Value("${external-url}") + @NotBlank + private String externalUrl; + + @Autowired + private JacksonMapper mapper; + + @Autowired + @Qualifier("medianetConfigurationProperties") + private BidderConfigurationProperties configProperties; + + @Bean("medianetConfigurationProperties") + @ConfigurationProperties("adapters.medianet") + BidderConfigurationProperties configurationProperties() { + return new BidderConfigurationProperties(); + } + + @Bean + BidderDeps medianetBidderDeps() { + return BidderDepsAssembler.forBidder(BIDDER_NAME) + .withConfig(configProperties) + .usersyncerCreator(UsersyncerCreator.create(externalUrl)) + .bidderCreator(config -> new MedianetBidder(resolveEndpoint(config.getEndpoint()), mapper)) + .assemble(); + } + + private String resolveEndpoint(String configEndpoint) { + return configEndpoint.replace(EXTERNAL_URL_MACRO, HttpUtil.encodeUrl(externalUrl)); + } +} diff --git a/src/main/resources/bidder-config/medianet.yaml b/src/main/resources/bidder-config/medianet.yaml new file mode 100644 index 00000000000..af4b1310752 --- /dev/null +++ b/src/main/resources/bidder-config/medianet.yaml @@ -0,0 +1,27 @@ +adapters: + medianet: + enabled: false + endpoint: https://prebid-adapter.media.net/rtb/pb/prebids2s?src={{PREBID_SERVER_ENDPOINT}} + pbs-enforces-gdpr: true + pbs-enforces-ccpa: true + modifying-vast-xml-allowed: true + deprecated-names: + aliases: {} + meta-info: + maintainer-email: prebid@media.net + app-media-types: + - banner + - video + - native + site-media-types: + - banner + - video + - native + supported-vendors: + vendor-id: 142 + usersync: + url: https://hbx.media.net/cksync.php?cs=1&type=pbs&ovsid=setstatuscode&redirect= + redirect-url: /setuid?bidder=medianet&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&uid= + cookie-family-name: medianet + type: redirect + support-cors: false diff --git a/src/main/resources/static/bidder-params/medianet.json b/src/main/resources/static/bidder-params/medianet.json new file mode 100644 index 00000000000..d50ee049fd1 --- /dev/null +++ b/src/main/resources/static/bidder-params/medianet.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Medianet Adapter Params", + "description": "A schema which validates params accepted by the Medianet adapter", + "type": "object", + "properties": { + "cid": { + "type": "string", + "description": "The customer id provided by Media.net." + }, + "crid": { + "type": "string", + "description": "The placement id provided by Media.net." + } + }, + "required": [ + "cid", + "crid" + ] +} diff --git a/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java b/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java new file mode 100644 index 00000000000..4c14bb97729 --- /dev/null +++ b/src/test/java/org/prebid/server/bidder/medianet/MedianetBidderTest.java @@ -0,0 +1,145 @@ +package org.prebid.server.bidder.medianet; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.iab.openrtb.request.BidRequest; +import com.iab.openrtb.request.Imp; +import com.iab.openrtb.response.Bid; +import com.iab.openrtb.response.BidResponse; +import com.iab.openrtb.response.SeatBid; +import org.junit.Before; +import org.junit.Test; +import org.prebid.server.VertxTest; +import org.prebid.server.bidder.model.BidderBid; +import org.prebid.server.bidder.model.BidderError; +import org.prebid.server.bidder.model.HttpCall; +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.proto.openrtb.ext.ExtPrebid; + +import java.util.List; +import java.util.function.Function; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; + +public class MedianetBidderTest extends VertxTest { + + private static final String ENDPOINT_URL = "https://test.media.net?src=external.prebidserver.com"; + + private MedianetBidder medianetBidder; + + @Before + public void setup() { + medianetBidder = new MedianetBidder(ENDPOINT_URL, jacksonMapper); + } + + @Test + public void creationShouldFailOnInvalidEndpointUrl() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new MedianetBidder("invalid_url", jacksonMapper)); + } + + @Test + public void makeHttpRequestsShouldNotModifyIncomingRequest() { + // given + final BidRequest bidRequest = givenBidRequest(); + + // when + final Result>> result; + result = medianetBidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class)) + .containsExactly(bidRequest); + } + + @Test + public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { + // given + final HttpCall httpCall = sampleHttpCall(givenBidRequest(), "invalid response"); + + // when + final Result> result = medianetBidder.makeBids(httpCall, null); + + // then + assertThat(result.getErrors()).hasSize(1) + .allMatch(error -> error.getType() == BidderError.Type.bad_server_response + && error.getMessage().startsWith("Failed to decode: Unrecognized token")); + } + + @Test + public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProcessingException { + // given + final HttpCall httpCall; + httpCall = sampleHttpCall(givenBidRequest(), mapper.writeValueAsString(null)); + + // when + final Result> result = medianetBidder.makeBids(httpCall, null); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws JsonProcessingException { + // given + final HttpCall httpCall; + httpCall = sampleHttpCall(null, mapper.writeValueAsString(BidResponse.builder().build())); + + // when + final Result> result = medianetBidder.makeBids(httpCall, null); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeBidsShouldReturnBannerBidIfBannerIsPresent() throws JsonProcessingException { + // given + final HttpCall httpCall = sampleHttpCall( + givenBidRequest(), + mapper.writeValueAsString(sampleBidResponse(bidBuilder -> bidBuilder.impid("123")))); + + // when + final Result> result = medianetBidder.makeBids(httpCall, null); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), banner, "USD")); + } + + private static BidResponse sampleBidResponse(Function bidCustomizer) { + return BidResponse.builder() + .cur("USD") + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(bidCustomizer.apply(Bid.builder()).build())) + .build())) + .build(); + } + + private static HttpCall sampleHttpCall(BidRequest bidRequest, String body) { + return HttpCall.success( + HttpRequest.builder().payload(bidRequest).build(), + HttpResponse.of(200, null, body), + null); + } + + private static BidRequest givenBidRequest() { + return BidRequest.builder() + .id("request_id") + .imp(singletonList(Imp.builder() + .id("imp_id") + .ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createObjectNode()))) + .build())) + .build(); + } +} diff --git a/src/test/java/org/prebid/server/it/MedianetTest.java b/src/test/java/org/prebid/server/it/MedianetTest.java new file mode 100644 index 00000000000..296c65a5d52 --- /dev/null +++ b/src/test/java/org/prebid/server/it/MedianetTest.java @@ -0,0 +1,36 @@ +package org.prebid.server.it; + +import io.restassured.response.Response; +import org.json.JSONException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.prebid.server.model.Endpoint; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static java.util.Collections.singletonList; + +@RunWith(SpringRunner.class) +public class MedianetTest extends IntegrationTest { + + @Test + public void openrtb2AuctionShouldRespondWithBidsFromTheMedianet() throws IOException, JSONException { + // given + WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/medianet-exchange")) + .withRequestBody(equalToJson(jsonFrom("openrtb2/medianet/test-medianet-bid-request.json"))) + .willReturn(aResponse().withBody(jsonFrom("openrtb2/medianet/test-medianet-bid-response.json")))); + + // when + final Response response = responseFor("openrtb2/medianet/test-auction-medianet-request.json", + Endpoint.openrtb2_auction); + + // then + assertJsonEquals("openrtb2/medianet/test-auction-medianet-response.json", response, + singletonList("medianet")); + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-request.json b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-request.json new file mode 100644 index 00000000000..9f542b4e423 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-request.json @@ -0,0 +1,24 @@ +{ + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "medianet": { + "cid": "8CUTSTCID", + "crid": "999999999" + } + } + } + ], + "tmax": 5000, + "regs": { + "ext": { + "gdpr": 0 + } + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-response.json b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-response.json new file mode 100644 index 00000000000..14ebb3b62f8 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-auction-medianet-response.json @@ -0,0 +1,38 @@ +{ + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + }, + "origbidcpm": 0.5 + } + } + ], + "seat": "medianet", + "group": 0 + } + ], + "cur": "USD", + "ext": { + "responsetimemillis": { + "medianet": "{{ medianet.response_time_ms }}" + }, + "prebid": { + "auctiontimestamp": 0 + }, + "tmaxrequest": 5000 + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-request.json new file mode 100644 index 00000000000..e2fc61b9ccd --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-request.json @@ -0,0 +1,42 @@ +{ + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "cid": "8CUTSTCID", + "crid": "999999999" + } + } + } + ], + "site": { + "domain": "www.example.com", + "page": "http://www.example.com", + "publisher": { + "domain": "example.com" + }, + "ext": { + "amp": 0 + } + }, + "device": { + "ua": "userAgent", + "ip": "193.168.244.1" + }, + "at": 1, + "tmax": 5000, + "cur": [ + "USD" + ], + "regs": { + "ext": { + "gdpr": 0 + } + } +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-response.json new file mode 100644 index 00000000000..916e703c412 --- /dev/null +++ b/src/test/resources/org/prebid/server/it/openrtb2/medianet/test-medianet-bid-response.json @@ -0,0 +1,22 @@ + { + "id": "tid", + "seatbid": [ + { + "seat": "medianet", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + } + ], + "bidid": "bid01" +} 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 b5d7776d513..71093b54c59 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -137,6 +137,8 @@ adapters.madvertise.enabled=true adapters.madvertise.endpoint=http://localhost:8090/madvertise-exchange adapters.marsmedia.enabled=true adapters.marsmedia.endpoint=http://localhost:8090/marsmedia-exchange?param=testParam +adapters.medianet.enabled=true +adapters.medianet.endpoint=http://localhost:8090/medianet-exchange adapters.mgid.enabled=true adapters.mgid.endpoint=http://localhost:8090/mgid-exchange/ adapters.mobfoxpb.enabled=true From 29de0891a9411d521eba816df5648f8e12ba519b Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Thu, 5 Aug 2021 15:29:13 +0300 Subject: [PATCH 02/13] Rubicon: fix NPE caused by null deal bid price (#1395) --- .../server/bidder/rubicon/RubiconBidder.java | 6 --- .../bidder/rubicon/RubiconBidderTest.java | 48 ++----------------- 2 files changed, 3 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java index d047cbdbeec..4b2527e3ab7 100644 --- a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java +++ b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java @@ -1289,7 +1289,6 @@ private List bidsFromResponse(BidRequest prebidRequest, .filter(Objects::nonNull) .flatMap(Collection::stream) .map(bid -> updateBid(bid, idToImp.get(bid.getImpid()), cpmOverrideFromRequest, bidResponse)) - .filter(RubiconBidder::validatePrice) .map(bid -> BidderBid.of(bid, bidType, bidResponse.getCur())) .collect(Collectors.toList()); } @@ -1341,11 +1340,6 @@ private ExtPrebid getExtPrebid(ObjectNode bidExt, Stri } } - private static boolean validatePrice(Bid bid) { - final BigDecimal price = bid.getPrice(); - return bid.getDealid() != null ? price.compareTo(BigDecimal.ZERO) >= 0 : price.compareTo(BigDecimal.ZERO) > 0; - } - private Bid updateBid(Bid bid, Imp imp, Float cpmOverrideFromRequest, RubiconBidResponse bidResponse) { String bidId = bid.getId(); if (generateBidId) { diff --git a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java index 6d4bd65abce..281bfebdfda 100644 --- a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java @@ -96,7 +96,6 @@ import static java.math.BigDecimal.ONE; import static java.math.BigDecimal.TEN; -import static java.math.BigDecimal.ZERO; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -2803,48 +2802,6 @@ public void makeBidsShouldNotReduceBidderAmountForBidsWithSameImpId() throws Jso .containsExactlyInAnyOrder("firstBidId", "secondBidId"); } - @Test - public void makeBidsShouldNotReturnImpIfNonDealBidPriceLessThanZero() throws JsonProcessingException { - // given - final HttpCall httpCall = givenHttpCall(givenBidRequest(identity()), - givenBidResponse(BigDecimal.valueOf(-1))); - - // when - final Result> result = rubiconBidder.makeBids(httpCall, givenBidRequest(identity())); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).isEmpty(); - } - - @Test - public void makeBidsShouldNotReturnImpIfNonDealBidPriceEqualToZero() throws JsonProcessingException { - // given - final HttpCall httpCall = givenHttpCall(givenBidRequest(identity()), - givenBidResponse(ZERO)); - - // when - final Result> result = rubiconBidder.makeBids(httpCall, givenBidRequest(identity())); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).isEmpty(); - } - - @Test - public void makeBidsShouldNotReturnImpIfDealBidPriceLessThanZero() throws JsonProcessingException { - // given - final HttpCall httpCall = givenHttpCall(givenBidRequest(identity()), - givenBidResponse(BigDecimal.valueOf(-1))); - - // when - final Result> result = rubiconBidder.makeBids(httpCall, givenBidRequest(identity())); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).isEmpty(); - } - @Test public void makeBidsShouldReturnBidWithOverriddenCpmFromRequest() throws JsonProcessingException { // given @@ -3069,7 +3026,7 @@ private static BidRequest givenBidRequest(Function impCustomizer, Function extCustomizer) { return bidRequestCustomizer.apply(BidRequest.builder() - .imp(singletonList(givenImp(impCustomizer, extCustomizer)))) + .imp(singletonList(givenImp(impCustomizer, extCustomizer)))) .build(); } @@ -3085,7 +3042,8 @@ private static BidRequest givenBidRequest(Function impCu private static Imp givenImp(Function impCustomizer, Function extCustomizer) { return impCustomizer.apply(Imp.builder() - .ext(mapper.valueToTree(ExtPrebid.of(null, extCustomizer.apply(ExtImpRubicon.builder()).build())))) + .ext(mapper.valueToTree(ExtPrebid.of( + null, extCustomizer.apply(ExtImpRubicon.builder()).build())))) .build(); } From 422672ed24ab079ae648870a78c3f36a600e48c3 Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Thu, 5 Aug 2021 16:30:39 +0300 Subject: [PATCH 03/13] Appnexus: make AdPodId optional (#1397) --- .../bidder/appnexus/AppnexusBidder.java | 117 +++++++++--------- ...emberId.java => ImpWithExtProperties.java} | 4 +- .../ext/request/appnexus/ExtImpAppnexus.java | 2 + .../static/bidder-params/appnexus.json | 4 + .../bidder/appnexus/AppnexusBidderTest.java | 96 +++++++++++--- .../test-video-appnexus-bid-request-1.json | 92 ++++++++++++++ .../test-video-appnexus-bid-request-2.json | 92 -------------- 7 files changed, 242 insertions(+), 165 deletions(-) rename src/main/java/org/prebid/server/bidder/appnexus/model/{ImpWithMemberId.java => ImpWithExtProperties.java} (77%) diff --git a/src/main/java/org/prebid/server/bidder/appnexus/AppnexusBidder.java b/src/main/java/org/prebid/server/bidder/appnexus/AppnexusBidder.java index 701c36a14e6..883cbc29468 100644 --- a/src/main/java/org/prebid/server/bidder/appnexus/AppnexusBidder.java +++ b/src/main/java/org/prebid/server/bidder/appnexus/AppnexusBidder.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; import com.iab.openrtb.request.Banner; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Imp; @@ -11,10 +12,12 @@ import com.iab.openrtb.response.SeatBid; import io.vertx.core.http.HttpMethod; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.prebid.server.auction.model.Endpoint; import org.prebid.server.bidder.Bidder; -import org.prebid.server.bidder.appnexus.model.ImpWithMemberId; +import org.prebid.server.bidder.appnexus.model.ImpWithExtProperties; import org.prebid.server.bidder.appnexus.proto.AppnexusBidExt; import org.prebid.server.bidder.appnexus.proto.AppnexusBidExtAppnexus; import org.prebid.server.bidder.appnexus.proto.AppnexusImpExt; @@ -182,47 +185,33 @@ public AppnexusBidder(String endpointUrl, JacksonMapper mapper) { public Result>> makeHttpRequests(BidRequest bidRequest) { final List errors = new ArrayList<>(); final String defaultDisplayManagerVer = makeDefaultDisplayManagerVer(bidRequest); - final List processedImps = new ArrayList<>(); - final Set memberIds = new HashSet<>(); + final Set uniqueIds = new HashSet<>(); + Boolean generateAdPodId = null; + for (final Imp imp : bidRequest.getImp()) { try { - final ImpWithMemberId impWithMemberId = makeImpWithMemberId(imp, defaultDisplayManagerVer); - processedImps.add(impWithMemberId.getImp()); - memberIds.add(impWithMemberId.getMemberId()); - } catch (PreBidException e) { - errors.add(BidderError.badInput(e.getMessage())); - } - } + final ImpWithExtProperties impWithExtProperties = processImp(imp, defaultDisplayManagerVer); + final Boolean impGenerateAdPodId = impWithExtProperties.getGenerateAdPodId(); - final Set uniqueIds = memberIds.stream() - .filter(Objects::nonNull) - .collect(Collectors.toSet()); + generateAdPodId = ObjectUtils.defaultIfNull(generateAdPodId, impGenerateAdPodId); + if (!Objects.equals(generateAdPodId, impGenerateAdPodId)) { + return Result.withError(BidderError.badInput( + "Generate ad pod option should be same for all pods in request")); + } - final String url; - if (CollectionUtils.isNotEmpty(uniqueIds)) { - url = String.format("%s?member_id=%s", endpointUrl, uniqueIds.iterator().next()); - try { - validateMemberId(uniqueIds); + processedImps.add(impWithExtProperties.getImp()); + final String memberId = impWithExtProperties.getMemberId(); + if (memberId != null) { + uniqueIds.add(memberId); + } } catch (PreBidException e) { errors.add(BidderError.badInput(e.getMessage())); } - } else { - url = endpointUrl; } - final List> httpRequests; - if (isVideoRequest(bidRequest)) { - httpRequests = groupImpsByPod(processedImps) - .values().stream() - .map(podImps -> splitHttpRequests(bidRequest, updateRequestExtForVideo(bidRequest), podImps, url)) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } else { - httpRequests = splitHttpRequests(bidRequest, updateRequestExt(bidRequest), processedImps, url); - } - - return Result.of(httpRequests, errors); + final String url = constructUrl(uniqueIds, errors); + return Result.of(constructRequests(bidRequest, processedImps, url, generateAdPodId), errors); } private String makeDefaultDisplayManagerVer(BidRequest bidRequest) { @@ -290,6 +279,34 @@ private static boolean isIncludeBrandCategory(ExtRequest extRequest) { return includebrandcategory != null; } + private String constructUrl(Set ids, List errors) { + if (CollectionUtils.isNotEmpty(ids)) { + final String url = String.format("%s?member_id=%s", endpointUrl, ids.iterator().next()); + try { + validateMemberId(ids); + } catch (PreBidException e) { + errors.add(BidderError.badInput(e.getMessage())); + } + return url; + } + return endpointUrl; + } + + private List> constructRequests(BidRequest bidRequest, + List imps, + String url, + Boolean generateAdPodId) { + if (isVideoRequest(bidRequest) && BooleanUtils.isTrue(generateAdPodId)) { + return groupImpsByPod(imps) + .values().stream() + .map(podImps -> splitHttpRequests(bidRequest, updateRequestExtForVideo(bidRequest), podImps, url)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } else { + return splitHttpRequests(bidRequest, updateRequestExt(bidRequest), imps, url); + } + } + private Map> groupImpsByPod(List processedImps) { return processedImps.stream() .collect(Collectors.groupingBy(imp -> StringUtils.substringBefore(imp.getId(), POD_SEPARATOR))); @@ -297,37 +314,22 @@ private Map> groupImpsByPod(List processedImps) { private List> splitHttpRequests(BidRequest bidRequest, ExtRequest requestExt, - List processedImps, + List imps, String url) { + final List> result = Lists.partition(imps, MAX_IMP_PER_REQUEST) + .stream() + .map(impsChunk -> createHttpRequest(bidRequest, requestExt, impsChunk, url)) + .collect(Collectors.toList()); - // Let's say there are 35 impressions and limit impressions per request equals to 10. - // In this case we need to create 4 requests with 10, 10, 10 and 5 impressions. - // With this formula initial capacity=(35+10-1)/10 = 4 - final int impSize = processedImps.size(); - final int numberOfRequests = (impSize + MAX_IMP_PER_REQUEST - 1) / MAX_IMP_PER_REQUEST; - final List> spitedRequests = new ArrayList<>(numberOfRequests); - - int startIndex = 0; - boolean impsLeft = true; - while (impsLeft) { - int endIndex = startIndex + MAX_IMP_PER_REQUEST; - if (endIndex >= impSize) { - impsLeft = false; - endIndex = impSize; - } - spitedRequests.add( - createHttpRequest(bidRequest, requestExt, processedImps.subList(startIndex, endIndex), url)); - startIndex = endIndex; - } - - return spitedRequests; + return result.isEmpty() + ? Collections.singletonList(createHttpRequest(bidRequest, requestExt, imps, url)) + : result; } private HttpRequest createHttpRequest(BidRequest bidRequest, ExtRequest requestExt, List imps, String url) { - final BidRequest outgoingRequest = bidRequest.toBuilder() .imp(imps) .ext(requestExt) @@ -342,7 +344,7 @@ private HttpRequest createHttpRequest(BidRequest bidRequest, .build(); } - private ImpWithMemberId makeImpWithMemberId(Imp imp, String defaultDisplayManagerVer) { + private ImpWithExtProperties processImp(Imp imp, String defaultDisplayManagerVer) { if (imp.getAudio() != null) { throw new PreBidException( String.format("Appnexus doesn't support audio Imps. Ignoring Imp ID=%s", imp.getId())); @@ -369,7 +371,8 @@ private ImpWithMemberId makeImpWithMemberId(Imp imp, String defaultDisplayManage impBuilder.displaymanagerver(defaultDisplayManagerVer); } - return ImpWithMemberId.of(impBuilder.build(), appnexusExt.getMember()); + return ImpWithExtProperties.of(impBuilder.build(), appnexusExt.getMember(), + appnexusExt.getGenerateAdPodId()); } private static boolean bidFloorIsValid(BigDecimal bidFloor) { diff --git a/src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithMemberId.java b/src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithExtProperties.java similarity index 77% rename from src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithMemberId.java rename to src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithExtProperties.java index 51cd7517160..defe2de2b4a 100644 --- a/src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithMemberId.java +++ b/src/main/java/org/prebid/server/bidder/appnexus/model/ImpWithExtProperties.java @@ -6,9 +6,11 @@ @AllArgsConstructor(staticName = "of") @Value -public class ImpWithMemberId { +public class ImpWithExtProperties { Imp imp; String memberId; + + Boolean generateAdPodId; } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/appnexus/ExtImpAppnexus.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/appnexus/ExtImpAppnexus.java index 4f2e68796ae..fd6a8e26b3d 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/appnexus/ExtImpAppnexus.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/appnexus/ExtImpAppnexus.java @@ -41,5 +41,7 @@ public class ExtImpAppnexus { Boolean usePmtRule; + Boolean generateAdPodId; + ObjectNode privateSizes; // At this time we do no processing on the private sizes, so just leaving it as a JSON blob } diff --git a/src/main/resources/static/bidder-params/appnexus.json b/src/main/resources/static/bidder-params/appnexus.json index 78701b95b48..bfcb275b644 100644 --- a/src/main/resources/static/bidder-params/appnexus.json +++ b/src/main/resources/static/bidder-params/appnexus.json @@ -71,6 +71,10 @@ "type": "boolean", "description": "Boolean to signal AppNexus to apply the relevant payment rule" }, + "generate_ad_pod_id": { + "type": "boolean", + "description": "Boolean to signal AppNexus to add ad pod id to each request" + }, "private_sizes": { "type": "array", "items": { diff --git a/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java b/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java index a84cbd13274..53217e24c59 100644 --- a/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/appnexus/AppnexusBidderTest.java @@ -55,6 +55,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.function.UnaryOperator; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -790,7 +791,7 @@ public void makeHttpRequestShouldReturnSingleRequestWhenOnePod() { imp -> imp .id(String.format("1_%d", impIdSuffix)) .banner(Banner.builder().build()), - ext -> ext.placementId(10))) + ext -> ext.placementId(10).generateAdPodId(true))) .collect(Collectors.toList()); final BidRequest bidRequest = BidRequest.builder() .imp(imps) @@ -820,7 +821,7 @@ public void makeHttpRequestShouldReturnMultipleRequestsWhenOnePodAndManyImps() { imp -> imp .id(String.format("1_%d", impIdSuffix)) .banner(Banner.builder().build()), - ext -> ext.placementId(10))) + ext -> ext.placementId(10).generateAdPodId(true))) .collect(Collectors.toList()); final BidRequest bidRequest = BidRequest.builder() .imp(imps) @@ -852,7 +853,7 @@ public void makeHttpRequestShouldReturnMultipleRequestsWhenTwoPods() { imp -> imp .id(String.format("%d_%d", impIdPrefix, impIdSuffix)) .banner(Banner.builder().build()), - ext -> ext.placementId(10)))) + ext -> ext.placementId(10).generateAdPodId(true)))) .collect(Collectors.toList()); final BidRequest bidRequest = BidRequest.builder() .imp(imps) @@ -884,7 +885,7 @@ public void makeHttpRequestShouldReturnMultipleRequestsWhenTwoPodsAndManyImps() imp -> imp .id(String.format("%d_%d", impIdPrefix, impIdSuffix)) .banner(Banner.builder().build()), - ext -> ext.placementId(10)))) + ext -> ext.placementId(10).generateAdPodId(true)))) .collect(Collectors.toList()); final BidRequest bidRequest = BidRequest.builder() .imp(imps) @@ -906,6 +907,70 @@ public void makeHttpRequestShouldReturnMultipleRequestsWhenTwoPodsAndManyImps() .matches(adPodIds -> new HashSet<>(adPodIds).size() == 2); // adPodIds should be different } + @Test + public void makeHttpRequestShouldReturnErrorIfRequestContainsMultipleGenerateAdPodIdsValues() { + // given + final List imps = IntStream.rangeClosed(1, 2) + .boxed() + .flatMap(impIdPrefix -> IntStream.rangeClosed(0, 15) + .mapToObj(impIdSuffix -> givenImp( + imp -> imp + .id(String.format("%d_%d", impIdPrefix, impIdSuffix)) + .banner(Banner.builder().build()), + ext -> ext.placementId(10).generateAdPodId(impIdSuffix % 2 == 0)))) + .collect(Collectors.toList()); + final BidRequest bidRequest = BidRequest.builder() + .imp(imps) + .ext(ExtRequest.of(ExtRequestPrebid.builder() + .pbs(ExtRequestPrebidPbs.of(Endpoint.openrtb2_video.value())) + .build())) + .build(); + + // when + final Result>> result = appnexusBidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()).isEmpty(); + assertThat(result.getErrors()) + .containsExactly(BidderError.badInput("Generate ad pod option should be same for all pods in request")); + } + + @Test + public void makeHttpRequestShouldNotGenerateAdPodIdWhenFlagIsNotSetInRequestImpExt() { + // given + final List imps = IntStream.rangeClosed(1, 2) + .boxed() + .flatMap(impIdPrefix -> IntStream.rangeClosed(0, 15) + .mapToObj(impIdSuffix -> givenImp( + imp -> imp + .id(String.format("%d_%d", impIdPrefix, impIdSuffix)) + .banner(Banner.builder().build()), + ext -> ext.placementId(10).generateAdPodId(false)))) + .collect(Collectors.toList()); + final BidRequest bidRequest = BidRequest.builder() + .imp(imps) + .ext(ExtRequest.of(ExtRequestPrebid.builder() + .targeting(ExtRequestTargeting.builder() + .includebrandcategory(ExtIncludeBrandCategory.of(null, null, null)) + .build()) + .pbs(ExtRequestPrebidPbs.of(Endpoint.openrtb2_video.value())) + .build())) + .build(); + + // when + final Result>> result = appnexusBidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .extracting(BidRequest::getExt) + .extracting(ext -> mapper.convertValue(ext.getProperties(), AppnexusReqExt.class)) + .extracting(AppnexusReqExt::getAppnexus).doesNotContainNull() + .extracting(AppnexusReqExtAppnexus::getAdpodId) + .matches(adPodIds -> adPodIds.stream().allMatch(Objects::isNull)); + } + @Test public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given @@ -1139,7 +1204,7 @@ private static BidRequest givenBidRequest(UnaryOperator bidRe UnaryOperator impCustomizer, UnaryOperator extCustomizer) { return bidRequestCustomizer.apply(BidRequest.builder() - .imp(singletonList(givenImp(impCustomizer, extCustomizer)))) + .imp(singletonList(givenImp(impCustomizer, extCustomizer)))) .build(); } @@ -1150,7 +1215,7 @@ private static BidRequest givenBidRequest(UnaryOperator impCustomize private static Imp givenImp(UnaryOperator impCustomizer, UnaryOperator extCustomizer) { return impCustomizer.apply(Imp.builder() - .ext(givenExt(extCustomizer))) + .ext(givenExt(extCustomizer))) .build(); } @@ -1184,15 +1249,16 @@ private static String givenBidResponse( UnaryOperator bidExtCustomizer) throws JsonProcessingException { - return mapper.writeValueAsString(bidResponseCustomizer.apply(BidResponse.builder() - .seatbid(singletonList(SeatBid.builder() - .bid(singletonList(bidCustomizer.apply(Bid.builder() - .impid("impId") - .ext(mapper.valueToTree(AppnexusBidExt.of( - bidExtCustomizer.apply(AppnexusBidExtAppnexus.builder().bidAdType(BANNER_TYPE)) - .build())))) - .build())) - .build()))) + return mapper.writeValueAsString(bidResponseCustomizer.apply( + BidResponse.builder() + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(bidCustomizer.apply(Bid.builder() + .impid("impId") + .ext(mapper.valueToTree(AppnexusBidExt.of(bidExtCustomizer.apply( + AppnexusBidExtAppnexus.builder() + .bidAdType(BANNER_TYPE)) + .build())))).build())) + .build()))) .build()); } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-1.json b/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-1.json index 55e1ff8c6be..8c9fec28d83 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-1.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-1.json @@ -138,6 +138,98 @@ "placement_id": 14997137 } } + }, + { + "id": "2_0", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 30, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 + }, + "ext": { + "appnexus": { + "placement_id": 15016213 + } + } + }, + { + "id": "2_1", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 30, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 + }, + "ext": { + "appnexus": { + "placement_id": 15016213 + } + } + }, + { + "id": "2_2", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 30, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 + }, + "ext": { + "appnexus": { + "placement_id": 15016213 + } + } + }, + { + "id": "2_3", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 30, + "maxduration": 30, + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 640, + "h": 480 + }, + "ext": { + "appnexus": { + "placement_id": 15016213 + } + } } ], "site": { diff --git a/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-2.json b/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-2.json index d403a3e5cc2..67eae45f9ee 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-2.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/video/test-video-appnexus-bid-request-2.json @@ -1,98 +1,6 @@ { "id": "bid_id", "imp": [ - { - "id": "2_0", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 30, - "maxduration": 30, - "protocols": [ - 2, - 3, - 5, - 6 - ], - "w": 640, - "h": 480 - }, - "ext": { - "appnexus": { - "placement_id": 15016213 - } - } - }, - { - "id": "2_1", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 30, - "maxduration": 30, - "protocols": [ - 2, - 3, - 5, - 6 - ], - "w": 640, - "h": 480 - }, - "ext": { - "appnexus": { - "placement_id": 15016213 - } - } - }, - { - "id": "2_2", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 30, - "maxduration": 30, - "protocols": [ - 2, - 3, - 5, - 6 - ], - "w": 640, - "h": 480 - }, - "ext": { - "appnexus": { - "placement_id": 15016213 - } - } - }, - { - "id": "2_3", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 30, - "maxduration": 30, - "protocols": [ - 2, - 3, - 5, - 6 - ], - "w": 640, - "h": 480 - }, - "ext": { - "appnexus": { - "placement_id": 15016213 - } - } - }, { "id": "2_4", "video": { From ee862a76886bcacb1090fb77070ade0ef98db625 Mon Sep 17 00:00:00 2001 From: IOTiagoFaria <76956619+IOTiagoFaria@users.noreply.github.com> Date: Mon, 9 Aug 2021 15:02:36 +0100 Subject: [PATCH 04/13] InteractiveOffers - New endpoint (#1408) --- src/main/resources/bidder-config/interactiveoffers.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/bidder-config/interactiveoffers.yaml b/src/main/resources/bidder-config/interactiveoffers.yaml index b5fb35b8e20..71b9e550407 100644 --- a/src/main/resources/bidder-config/interactiveoffers.yaml +++ b/src/main/resources/bidder-config/interactiveoffers.yaml @@ -1,7 +1,7 @@ adapters: interactiveoffers: enabled: false - endpoint: https://rtb.ioadx.com/bidRequest/?partnerId=d9e56d418c4825d466ee96c7a31bf1da6b62fa04 + endpoint: https://prebid-server.ioadx.com/bidRequest/?partnerId=d9e56d418c4825d466ee96c7a31bf1da6b62fa04 pbs-enforces-gdpr: true pbs-enforces-ccpa: true modifying-vast-xml-allowed: true From 1a44239e423c01d171b217beae30d121c6524638 Mon Sep 17 00:00:00 2001 From: laarchenko <48104398+laarchenko@users.noreply.github.com> Date: Tue, 10 Aug 2021 11:14:42 +0300 Subject: [PATCH 05/13] Add content-type header to /vtrack and /status endpoints (#1399) * Adding headers to vtrack and status * This commit added headers to /vtrack and /status * Working * Continue working progress * Updated tests and moved adding headers to lambdas * Moved fields in event type * Fixed tests * Fixed tests * Fixed imports * fixed tests --- .../prebid/server/handler/StatusHandler.java | 2 ++ .../prebid/server/handler/VtrackHandler.java | 2 ++ .../prebid/server/vertx/ContextRunner.java | 1 - .../server/handler/StatusHandlerTest.java | 26 ++++++++++++++++++- .../server/handler/VtrackHandlerTest.java | 15 ++++++++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/prebid/server/handler/StatusHandler.java b/src/main/java/org/prebid/server/handler/StatusHandler.java index 71870febc26..1c6acab5ea7 100644 --- a/src/main/java/org/prebid/server/handler/StatusHandler.java +++ b/src/main/java/org/prebid/server/handler/StatusHandler.java @@ -1,5 +1,6 @@ package org.prebid.server.handler; +import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpResponseStatus; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -38,6 +39,7 @@ public void handle(RoutingContext routingContext) { HttpUtil.executeSafely(routingContext, Endpoint.status, response -> response + .putHeader(HttpUtil.CONTENT_TYPE_HEADER, HttpHeaderValues.APPLICATION_JSON) .end(mapper.encode(nameToStatus))); } } diff --git a/src/main/java/org/prebid/server/handler/VtrackHandler.java b/src/main/java/org/prebid/server/handler/VtrackHandler.java index 7b0e7d9d352..3594fac13b6 100644 --- a/src/main/java/org/prebid/server/handler/VtrackHandler.java +++ b/src/main/java/org/prebid/server/handler/VtrackHandler.java @@ -1,5 +1,6 @@ package org.prebid.server.handler; +import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpResponseStatus; import io.vertx.core.AsyncResult; import io.vertx.core.Future; @@ -191,6 +192,7 @@ private static void respondWithServerError(RoutingContext routingContext, String private static void respondWith(RoutingContext routingContext, HttpResponseStatus status, String body) { HttpUtil.executeSafely(routingContext, Endpoint.vtrack, response -> response + .putHeader(HttpUtil.CONTENT_TYPE_HEADER, HttpHeaderValues.APPLICATION_JSON) .setStatusCode(status.code()) .end(body)); } diff --git a/src/main/java/org/prebid/server/vertx/ContextRunner.java b/src/main/java/org/prebid/server/vertx/ContextRunner.java index ed5ea8fdc20..19229ec1b8c 100644 --- a/src/main/java/org/prebid/server/vertx/ContextRunner.java +++ b/src/main/java/org/prebid/server/vertx/ContextRunner.java @@ -53,7 +53,6 @@ public void runOnServiceContext(Handler> action) { private void runOnContext(Supplier contextFactory, int times, Handler> action) { final CountDownLatch completionLatch = new CountDownLatch(times); final AtomicBoolean actionFailed = new AtomicBoolean(false); - for (int i = 0; i < times; i++) { final Context context = contextFactory.get(); diff --git a/src/test/java/org/prebid/server/handler/StatusHandlerTest.java b/src/test/java/org/prebid/server/handler/StatusHandlerTest.java index d3dfc0ea4a2..842261ef38f 100644 --- a/src/test/java/org/prebid/server/handler/StatusHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/StatusHandlerTest.java @@ -1,6 +1,8 @@ package org.prebid.server.handler; import com.fasterxml.jackson.core.JsonProcessingException; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.util.AsciiString; import io.vertx.core.http.HttpServerResponse; import io.vertx.ext.web.RoutingContext; import org.junit.Rule; @@ -11,10 +13,12 @@ import org.prebid.server.VertxTest; import org.prebid.server.health.HealthChecker; import org.prebid.server.health.model.StatusResponse; +import org.prebid.server.util.HttpUtil; import java.time.Clock; import java.time.ZonedDateTime; import java.util.Arrays; +import java.util.Collections; import java.util.Map; import java.util.TreeMap; @@ -23,6 +27,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; +import static org.mockito.ArgumentMatchers.any; public class StatusHandlerTest extends VertxTest { @@ -50,6 +55,8 @@ public void shouldRespondHttp200OkWithExpectedBody() throws JsonProcessingExcept statusHandler = new StatusHandler(Arrays.asList(healthCheck, healthCheck, healthCheck), jacksonMapper); given(routingContext.response()).willReturn(httpResponse); + given(httpResponse.putHeader(any(CharSequence.class), any(AsciiString.class))).willReturn(httpResponse); + given(healthCheck.name()).willReturn("application", "db", "other"); given(healthCheck.status()).willReturn(StatusResponse.of("ready", null), StatusResponse.of("UP", testTime), StatusResponse.of("DOWN", testTime)); @@ -62,12 +69,12 @@ public void shouldRespondHttp200OkWithExpectedBody() throws JsonProcessingExcept expectedMap.put("application", StatusResponse.of("ready", null)); expectedMap.put("db", StatusResponse.of("UP", testTime)); expectedMap.put("other", StatusResponse.of("DOWN", testTime)); - verify(httpResponse).end(eq(mapper.writeValueAsString(expectedMap))); } @Test public void shouldRespondWithNoContentWhenMessageWasNotDefined() { + // given statusHandler = new StatusHandler(emptyList(), jacksonMapper); given(routingContext.response()).willReturn(httpResponse); given(httpResponse.setStatusCode(eq(204))).willReturn(httpResponse); @@ -78,4 +85,21 @@ public void shouldRespondWithNoContentWhenMessageWasNotDefined() { // then verify(httpResponse).setStatusCode(eq(204)); } + + @Test + public void shouldRespondWithContentTypeHeaders() { + // given + statusHandler = new StatusHandler(Collections.singletonList(healthCheck), jacksonMapper); + + given(healthCheck.name()).willReturn("healthCheckName"); + given(healthCheck.status()).willReturn(StatusResponse.of("healthCheckStatus", null)); + + given(routingContext.response()).willReturn(httpResponse); + + // when + statusHandler.handle(routingContext); + + // then + verify(httpResponse).putHeader(HttpUtil.CONTENT_TYPE_HEADER, HttpHeaderValues.APPLICATION_JSON); + } } diff --git a/src/test/java/org/prebid/server/handler/VtrackHandlerTest.java b/src/test/java/org/prebid/server/handler/VtrackHandlerTest.java index e7f5bdea64d..faa1e2543c4 100644 --- a/src/test/java/org/prebid/server/handler/VtrackHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/VtrackHandlerTest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.TextNode; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.util.AsciiString; import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpServerRequest; @@ -23,6 +25,7 @@ import org.prebid.server.execution.TimeoutFactory; import org.prebid.server.settings.ApplicationSettings; import org.prebid.server.settings.model.Account; +import org.prebid.server.util.HttpUtil; import java.util.ArrayList; import java.util.HashSet; @@ -35,9 +38,9 @@ import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.function.Function.identity; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -69,6 +72,7 @@ public class VtrackHandlerTest extends VertxTest { public void setUp() { given(routingContext.request()).willReturn(httpRequest); given(routingContext.response()).willReturn(httpResponse); + given(httpResponse.putHeader(any(CharSequence.class), any(AsciiString.class))).willReturn(httpResponse); given(httpRequest.getParam("a")).willReturn("accountId"); given(httpRequest.getParam("int")).willReturn("pbjs"); @@ -94,6 +98,15 @@ public void shouldRespondWithBadRequestWhenAccountParameterIsMissing() { verify(httpResponse).end(eq("Account 'a' is required query parameter and can't be empty")); } + @Test + public void shouldRespondWithExpectedHeaders() { + // when + handler.handle(routingContext); + + // then + verify(httpResponse).putHeader(HttpUtil.CONTENT_TYPE_HEADER, HttpHeaderValues.APPLICATION_JSON); + } + @Test public void shouldRespondWithBadRequestWhenBodyIsEmpty() { // given From 12bea4c4dc072892b8db04fe929f29f5ee163284 Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Tue, 10 Aug 2021 12:17:39 +0300 Subject: [PATCH 06/13] IX: update required site id field to be more flexible (#1406) * Updated required site id field to be more flexible * Added explicit serialization siteId name * Removed redundant alias --- .../openrtb/ext/request/ix/ExtImpIx.java | 2 ++ .../resources/static/bidder-params/ix.json | 6 ++-- .../prebid/server/bidder/ix/IxBidderTest.java | 33 ++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ix/ExtImpIx.java b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ix/ExtImpIx.java index e7a8faee424..f91aa6cc0fb 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/request/ix/ExtImpIx.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/request/ix/ExtImpIx.java @@ -1,5 +1,6 @@ package org.prebid.server.proto.openrtb.ext.request.ix; +import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Value; @@ -11,6 +12,7 @@ public class ExtImpIx { @JsonProperty("siteId") + @JsonAlias({"siteid", "siteID"}) String siteId; List size; diff --git a/src/main/resources/static/bidder-params/ix.json b/src/main/resources/static/bidder-params/ix.json index da22db69803..f5a357c16f4 100644 --- a/src/main/resources/static/bidder-params/ix.json +++ b/src/main/resources/static/bidder-params/ix.json @@ -18,7 +18,9 @@ "description": "An array of two integer containing the dimension" } }, - "required": [ - "siteId" + "oneOf": [ + {"required": ["siteid"]}, + {"required": ["siteId"]}, + {"required": ["siteID"]} ] } diff --git a/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java b/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java index 98a7d6e006c..1c6b01e7603 100644 --- a/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/ix/IxBidderTest.java @@ -244,6 +244,37 @@ public void makeHttpRequestsShouldLimitImpsAmount() { assertThat(result.getValue()).hasSize(REQUEST_LIMIT); } + @Test + public void makeHttpRequestsShouldAcceptDifferentSiteIdAliases() { + final List imps = asList( + givenImp(impBuilder -> impBuilder + .id("123") + .ext(mapper.createObjectNode().set("bidder", + mapper.createObjectNode().put("siteid", "siteId1")))), + givenImp(impBuilder -> impBuilder + .id("346") + .ext(mapper.createObjectNode().set("bidder", + mapper.createObjectNode().put("siteId", "siteId2")))), + givenImp(impBuilder -> impBuilder + .id("678") + .ext(mapper.createObjectNode().set("bidder", + mapper.createObjectNode().put("siteID", "siteId3"))))); + final BidRequest bidRequest = givenBidRequest(requestBuilder -> + requestBuilder.imp(imps).site(Site.builder().build()), identity()); + + // when + final Result>> result = ixBidder.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .extracting(BidRequest::getSite) + .extracting(Site::getPublisher) + .extracting(Publisher::getId) + .containsExactlyInAnyOrder("siteId1", "siteId2", "siteId3"); + } + @Test public void makeHttpRequestsShouldLimitTotalAmountOfRequests() { // given @@ -620,7 +651,7 @@ private static BidRequest givenBidRequest(Function impCustomizer) { return impCustomizer.apply(Imp.builder() .id("123") - .banner(Banner.builder().build()) + .banner(Banner.builder().w(1).h(1).build()) .ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpIx.of(SITE_ID, null))))) .build(); } From 6eb674232816a5c7f9cc3a604c6553e50c06c7f1 Mon Sep 17 00:00:00 2001 From: Serhii Nahornyi Date: Tue, 10 Aug 2021 17:14:07 +0300 Subject: [PATCH 07/13] Remove Site object when both App and Site present (#1411) --- .../server/auction/ExchangeService.java | 8 ++++--- .../server/auction/ExchangeServiceTest.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/prebid/server/auction/ExchangeService.java b/src/main/java/org/prebid/server/auction/ExchangeService.java index ec4e750ef83..5dbc6840370 100644 --- a/src/main/java/org/prebid/server/auction/ExchangeService.java +++ b/src/main/java/org/prebid/server/auction/ExchangeService.java @@ -753,6 +753,8 @@ private BidderRequest createBidderRequest(BidderPrivacyResult bidderPrivacyResul final ExtBidderConfigOrtb fpdConfig = ObjectUtils.defaultIfNull(biddersToConfigs.get(bidder), biddersToConfigs.get(ALL_BIDDERS_CONFIG)); + final App bidRequestApp = bidRequest.getApp(); + final Site bidRequestSite = bidRequestApp == null ? bidRequest.getSite() : null; final ObjectNode fpdSite = fpdConfig != null ? fpdConfig.getSite() : null; final ObjectNode fpdApp = fpdConfig != null ? fpdConfig.getApp() : null; @@ -766,8 +768,8 @@ private BidderRequest createBidderRequest(BidderPrivacyResult bidderPrivacyResul .user(bidderPrivacyResult.getUser()) .device(bidderPrivacyResult.getDevice()) .imp(prepareImps(bidder, imps, useFirstPartyData)) - .app(prepareApp(bidRequest.getApp(), fpdApp, useFirstPartyData)) - .site(prepareSite(bidRequest.getSite(), fpdSite, useFirstPartyData)) + .app(prepareApp(bidRequestApp, fpdApp, useFirstPartyData)) + .site(prepareSite(bidRequestSite, fpdSite, useFirstPartyData)) .source(prepareSource(bidder, bidRequest)) .ext(prepareExt(bidder, bidderToPrebidBidders, bidderToMultiBid, bidRequest.getExt())) .build()); @@ -1008,7 +1010,7 @@ private Future invokeHooksAndRequestBids(AuctionContext auctionC .compose(stageResult -> requestBidsOrRejectBidder( stageResult, bidderRequest, timeout, headers, debugEnabled, aliases)) .compose(bidderResponse -> hookStageExecutor.executeRawBidderResponseStage( - bidderResponse, auctionContext) + bidderResponse, auctionContext) .map(stageResult -> rejectBidderResponseOrProceed(stageResult, bidderResponse))); } diff --git a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java index 3be977e8838..10a6a0824d1 100644 --- a/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java +++ b/src/test/java/org/prebid/server/auction/ExchangeServiceTest.java @@ -2190,6 +2190,28 @@ public void shouldCreateUserIfMissingInRequestAndBuyeridPresentInCookie() { assertThat(capturedUser).isEqualTo(User.builder().buyeruid("buyerid").build()); } + @Test + public void shouldRemoveSiteIfBothSiteAndAppPresent() { + // given + givenBidder(givenEmptySeatBid()); + final BidRequest bidRequest = givenBidRequest(givenSingleImp(singletonMap("someBidder", 1)), + bidRequestBuilder -> bidRequestBuilder + .site(Site.builder().build()) + .app(App.builder().build())); + + // when + exchangeService.holdAuction(givenRequestContext(bidRequest)); + + // then + final BidRequest captureBidRequest = captureBidRequest(); + assertThat(captureBidRequest) + .extracting(BidRequest::getSite) + .containsNull(); + assertThat(captureBidRequest) + .extracting(BidRequest::getApp) + .doesNotContainNull(); + } + @Test public void shouldPassGlobalTimeoutToConnectorUnchangedIfCachingIsNotRequested() { // given From bba57cf361d2e857c194701719be7a9edb47fcb3 Mon Sep 17 00:00:00 2001 From: Serhii Nahornyi Date: Wed, 11 Aug 2021 07:57:46 +0300 Subject: [PATCH 08/13] Align `/bidder/info` endpoint with Go behaviour (#1414) --- .../handler/info/BidderDetailsHandler.java | 26 ++++---- .../server/handler/info/BiddersHandler.java | 8 +-- .../server/proto/response/BidderInfo.java | 5 ++ .../config/bidder/util/BidderInfoCreator.java | 1 + .../PrivacyEnforcementServiceTest.java | 49 +++++++------- .../server/bidder/BidderCatalogTest.java | 2 + .../server/handler/CookieSyncHandlerTest.java | 10 +-- .../info/BidderDetailsHandlerTest.java | 64 ++++++++++++------- .../handler/info/BiddersHandlerTest.java | 8 +-- .../validation/BidderParamValidatorTest.java | 1 + .../test-info-bidder-details-response.json | 4 +- 11 files changed, 100 insertions(+), 78 deletions(-) diff --git a/src/main/java/org/prebid/server/handler/info/BidderDetailsHandler.java b/src/main/java/org/prebid/server/handler/info/BidderDetailsHandler.java index 8bc3606d34e..331f9b5ba48 100644 --- a/src/main/java/org/prebid/server/handler/info/BidderDetailsHandler.java +++ b/src/main/java/org/prebid/server/handler/info/BidderDetailsHandler.java @@ -46,13 +46,8 @@ private static void validateAliases(BidderCatalog bidderCatalog) { } } - /** - * Returns a {@link Map} with bidder name (or alias, or "all" keyword) as a key - * and json-encoded string of {@link BidderInfoResponseModel} as a value. - */ private Map createBidderInfos(BidderCatalog bidderCatalog) { final Map nameToInfo = bidderCatalog.names().stream() - .filter(bidderCatalog::isActive) .collect(Collectors.toMap(Function.identity(), name -> bidderNode(bidderCatalog, name))); final Map allToInfos = Collections.singletonMap(ALL_PARAM_VALUE, allInfos(nameToInfo)); @@ -62,17 +57,11 @@ private Map createBidderInfos(BidderCatalog bidderCatalog) { .collect(Collectors.toMap(Map.Entry::getKey, map -> mapper.encode(map.getValue()))); } - /** - * Returns bidder info as {@link ObjectNode}. - */ private ObjectNode bidderNode(BidderCatalog bidderCatalog, String name) { final BidderInfo bidderInfo = bidderCatalog.bidderInfoByName(name); return mapper.mapper().valueToTree(BidderInfoResponseModel.from(bidderInfo)); } - /** - * Returns a {@link Map} of all bidder's infos sorted by name as {@link ObjectNode}. - */ private ObjectNode allInfos(Map nameToInfo) { return mapper.mapper().valueToTree(new TreeMap<>(nameToInfo)); } @@ -98,6 +87,14 @@ public void handle(RoutingContext routingContext) { @Value(staticConstructor = "of") private static class BidderInfoResponseModel { + private static final String STATUS_ACTIVE = "ACTIVE"; + private static final String STATUS_DISABLED = "DISABLED"; + + String status; + + @JsonProperty("usesHttps") + boolean usesHttps; + BidderInfo.MaintainerInfo maintainer; BidderInfo.CapabilitiesInfo capabilities; @@ -106,7 +103,12 @@ private static class BidderInfoResponseModel { String aliasOf; private static BidderInfoResponseModel from(BidderInfo bidderInfo) { - return of(bidderInfo.getMaintainer(), bidderInfo.getCapabilities(), bidderInfo.getAliasOf()); + return of( + bidderInfo.isEnabled() ? STATUS_ACTIVE : STATUS_DISABLED, + bidderInfo.isUsesHttps(), + bidderInfo.getMaintainer(), + bidderInfo.getCapabilities(), + bidderInfo.getAliasOf()); } } } diff --git a/src/main/java/org/prebid/server/handler/info/BiddersHandler.java b/src/main/java/org/prebid/server/handler/info/BiddersHandler.java index 1ffb9e6a899..d604ac54be5 100644 --- a/src/main/java/org/prebid/server/handler/info/BiddersHandler.java +++ b/src/main/java/org/prebid/server/handler/info/BiddersHandler.java @@ -9,9 +9,7 @@ import org.prebid.server.util.HttpUtil; import java.util.Objects; -import java.util.Set; import java.util.TreeSet; -import java.util.stream.Collectors; public class BiddersHandler implements Handler { @@ -21,11 +19,7 @@ public BiddersHandler(BidderCatalog bidderCatalog, JacksonMapper mapper) { Objects.requireNonNull(bidderCatalog); Objects.requireNonNull(mapper); - final Set bidderNamesAndAliases = bidderCatalog.names().stream() - .filter(bidderCatalog::isActive) - .collect(Collectors.toCollection(TreeSet::new)); - - body = mapper.encode(bidderNamesAndAliases); + body = mapper.encode(new TreeSet<>(bidderCatalog.names())); } @Override diff --git a/src/main/java/org/prebid/server/proto/response/BidderInfo.java b/src/main/java/org/prebid/server/proto/response/BidderInfo.java index 540df9c76e7..6526bf586fd 100644 --- a/src/main/java/org/prebid/server/proto/response/BidderInfo.java +++ b/src/main/java/org/prebid/server/proto/response/BidderInfo.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Value; +import org.apache.commons.lang3.StringUtils; import java.util.List; @@ -10,6 +11,8 @@ public class BidderInfo { boolean enabled; + boolean usesHttps; + String aliasOf; MaintainerInfo maintainer; @@ -25,6 +28,7 @@ public class BidderInfo { boolean modifyingVastXmlAllowed; public static BidderInfo create(boolean enabled, + String endpoint, String aliasOf, String maintainerEmail, List appMediaTypes, @@ -37,6 +41,7 @@ public static BidderInfo create(boolean enabled, return of( enabled, + StringUtils.startsWith(endpoint, "https://"), aliasOf, new MaintainerInfo(maintainerEmail), new CapabilitiesInfo(platformInfo(appMediaTypes), platformInfo(siteMediaTypes)), diff --git a/src/main/java/org/prebid/server/spring/config/bidder/util/BidderInfoCreator.java b/src/main/java/org/prebid/server/spring/config/bidder/util/BidderInfoCreator.java index 262220f8d1e..704cefde1e4 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/util/BidderInfoCreator.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/util/BidderInfoCreator.java @@ -18,6 +18,7 @@ public static BidderInfo create(BidderConfigurationProperties configurationPrope final MetaInfo metaInfo = configurationProperties.getMetaInfo(); return BidderInfo.create( configurationProperties.getEnabled(), + configurationProperties.getEndpoint(), aliasOf, metaInfo.getMaintainerEmail(), metaInfo.getAppMediaTypes(), diff --git a/src/test/java/org/prebid/server/auction/PrivacyEnforcementServiceTest.java b/src/test/java/org/prebid/server/auction/PrivacyEnforcementServiceTest.java index d0628dd87eb..a324ecbbb8d 100644 --- a/src/test/java/org/prebid/server/auction/PrivacyEnforcementServiceTest.java +++ b/src/test/java/org/prebid/server/auction/PrivacyEnforcementServiceTest.java @@ -383,7 +383,7 @@ public void shouldMaskForCoppaWhenDeviceLmtIsEnforceAndOneAndRegsCoppaIsOneAndDo final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -424,7 +424,7 @@ public void shouldMaskForCcpaWhenUsPolicyIsValidAndCoppaIsZero() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -520,7 +520,7 @@ public void shouldNotMaskWhenDeviceLmtIsZeroAndCoppaIsZeroAndGdprIsZeroAndTcfDef final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -561,7 +561,7 @@ public void shouldMaskForTcfWhenTcfServiceAllowAllAndDeviceLmtIsOneAndLmtIsEnfor final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -599,7 +599,7 @@ public void shouldNotMaskForTcfWhenTcfServiceAllowAllAndDeviceLmtIsOneAndLmtIsNo final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device) @@ -634,7 +634,7 @@ public void shouldMaskForTcfWhenTcfDefinerServiceRestrictDeviceAndUser() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -674,7 +674,7 @@ public void shouldMaskUserIdsWhenTcfDefinerServiceRestrictUserIds() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -726,7 +726,7 @@ public void shouldMaskUserIdsWhenTcfDefinerServiceRestrictUserIdsAndReturnNullWh final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user)); @@ -763,7 +763,7 @@ public void shouldMaskGeoWhenTcfDefinerServiceRestrictGeo() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -806,7 +806,7 @@ public void shouldMaskDeviceIpWhenTcfDefinerServiceRestrictDeviceIp() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -848,7 +848,7 @@ public void shouldMaskDeviceInfoWhenTcfDefinerServiceRestrictDeviceInfo() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -918,7 +918,7 @@ public void shouldNotSendRelatedMetricsIfBlockBidderRequestEnforcementIsPresent( final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(notMaskedDevice())); @@ -949,7 +949,7 @@ public void shouldNotSendUserIdRemovedMetricIfNoPrivateUserInformation() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user)); final PrivacyContext privacyContext = givenPrivacyContext("0", Ccpa.EMPTY, 0); @@ -975,7 +975,7 @@ public void shouldNotSendGeoMaskedMetricIfNoPrivateGeoInformation() { TcfResponse.of(true, singletonMap(BIDDER_NAME, privacyEnforcementAction), null))); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .device(Device.builder().model("blackberry").build())); final PrivacyContext privacyContext = givenPrivacyContext("0", Ccpa.EMPTY, 0); @@ -1002,7 +1002,7 @@ public void shouldRerunEmptyResultWhenTcfDefinerServiceRestrictRequest() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -1122,7 +1122,7 @@ public void shouldNotReturnUserIfMaskingAppliedAndUserBecameEmptyObject() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user)); @@ -1154,7 +1154,7 @@ public void shouldReturnFailedFutureWhenTcfServiceIsReturnFailedFuture() { final Map bidderToUser = singletonMap(BIDDER_NAME, user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -1206,7 +1206,7 @@ public void shouldMaskForCcpaAndTcfWhenUsPolicyIsValidAndGdprIsEnforcedAndCOPPAI bidderToUser.put(bidder3Name, notMaskedUser()); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device) @@ -1220,10 +1220,10 @@ public void shouldMaskForCcpaAndTcfWhenUsPolicyIsValidAndGdprIsEnforcedAndCOPPAI // when final List result = privacyEnforcementService.mask( - context, - bidderToUser, - asList(bidder1Name, bidder2Name, bidder3Name), - BidderAliases.of(null, null, bidderCatalog)) + context, + bidderToUser, + asList(bidder1Name, bidder2Name, bidder3Name), + BidderAliases.of(null, null, bidderCatalog)) .result(); // then @@ -1264,7 +1264,7 @@ public void shouldNotMaskForCcpaWhenCatchAllWildcardIsPresentInNosaleList() { final Map bidderToUser = singletonMap(BIDDER_NAME, notMaskedUser()); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap(BIDDER_NAME, 1)), + singletonMap(BIDDER_NAME, 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device) @@ -1416,7 +1416,7 @@ public void shouldIncrementCcpaAndAuctionTcfMetrics() { final Map bidderToUser = singletonMap("someAlias", user); final BidRequest bidRequest = givenBidRequest(givenSingleImp( - singletonMap("someAlias", 1)), + singletonMap("someAlias", 1)), bidRequestBuilder -> bidRequestBuilder .user(user) .device(device)); @@ -1582,6 +1582,7 @@ private static PrivacyEnforcementAction restrictDeviceAndUser() { private static BidderInfo givenBidderInfo(int gdprVendorId, boolean enforceCcpa) { return BidderInfo.of( + true, true, null, null, diff --git a/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java b/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java index c4a4e5e1154..0bfe687c68f 100644 --- a/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java +++ b/src/test/java/org/prebid/server/bidder/BidderCatalogTest.java @@ -87,6 +87,7 @@ public void metaInfoByNameShouldReturnMetaInfoForKnownBidder() { final BidderInfo bidderInfo = BidderInfo.create( true, null, + null, "test@email.com", singletonList("banner"), singletonList("video"), @@ -161,6 +162,7 @@ public void nameByVendorIdShouldReturnBidderNameForVendorId() { final BidderInfo bidderInfo = BidderInfo.create( true, null, + null, "test@email.com", singletonList("banner"), singletonList("video"), diff --git a/src/test/java/org/prebid/server/handler/CookieSyncHandlerTest.java b/src/test/java/org/prebid/server/handler/CookieSyncHandlerTest.java index 18bed77e052..0f97f72cbb3 100644 --- a/src/test/java/org/prebid/server/handler/CookieSyncHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/CookieSyncHandlerTest.java @@ -661,7 +661,7 @@ public void shouldTolerateRejectedBidderByTcf() throws IOException { given(bidderCatalog.isActive(APPNEXUS)).willReturn(true); given(bidderCatalog.bidderInfoByName(APPNEXUS)) - .willReturn(BidderInfo.create(true, null, null, null, null, null, 2, true, true, false)); + .willReturn(BidderInfo.create(true, null, null, null, null, null, null, 2, true, true, false)); givenTcfServiceReturningVendorIdResult(singleton(1)); givenTcfServiceReturningBidderNamesResult(singleton(RUBICON)); @@ -726,7 +726,7 @@ bidderCatalog, tcfDefinerService, privacyEnforcementService, null, false, emptyL given(bidderCatalog.isActive(APPNEXUS)).willReturn(true); given(bidderCatalog.bidderInfoByName(APPNEXUS)) - .willReturn(BidderInfo.create(true, null, null, + .willReturn(BidderInfo.create(true, null, null, null, null, null, null, 2, true, true, false)); givenTcfServiceReturningBidderNamesResult(singleton(RUBICON)); @@ -757,7 +757,7 @@ public void shouldUpdateCookieSyncSetAndRejectByTcfMetricForEachRejectedAndSynce given(bidderCatalog.isActive(APPNEXUS)).willReturn(true); given(bidderCatalog.bidderInfoByName(APPNEXUS)) - .willReturn(BidderInfo.create(true, null, null, null, null, null, 2, true, true, false)); + .willReturn(BidderInfo.create(true, null, null, null, null, null, null, 2, true, true, false)); givenTcfServiceReturningVendorIdResult(singleton(1)); givenTcfServiceReturningBidderNamesResult(singleton(RUBICON)); @@ -1329,9 +1329,9 @@ public void shouldRespondWithNoCookieWhenBothCcpaAndGdprRejectBidders() throws I given(bidderCatalog.isActive(APPNEXUS)).willReturn(true); given(bidderCatalog.bidderInfoByName(RUBICON)).willReturn( - BidderInfo.create(true, null, null, null, null, null, 2, true, true, false)); + BidderInfo.create(true, null, null, null, null, null, null, 2, true, true, false)); given(bidderCatalog.bidderInfoByName(APPNEXUS)).willReturn( - BidderInfo.create(true, null, null, null, null, null, 2, true, false, false)); + BidderInfo.create(true, null, null, null, null, null, null, 2, true, false, false)); given(privacyEnforcementService.isCcpaEnforced(any(), any())).willReturn(true); diff --git a/src/test/java/org/prebid/server/handler/info/BidderDetailsHandlerTest.java b/src/test/java/org/prebid/server/handler/info/BidderDetailsHandlerTest.java index f26988d2fb5..ff251736427 100644 --- a/src/test/java/org/prebid/server/handler/info/BidderDetailsHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/info/BidderDetailsHandlerTest.java @@ -56,12 +56,12 @@ public void setUp() { given(bidderCatalog.names()).willReturn(new HashSet<>( asList("bidderName1", "bidderName2", "bidderAlias1", "bidderAlias2"))); - given(bidderCatalog.isActive("bidderName1")).willReturn(true); - given(bidderCatalog.isActive("bidderName2")).willReturn(false); - given(bidderCatalog.isActive("bidderAlias1")).willReturn(true); - given(bidderCatalog.isActive("bidderAlias2")).willReturn(false); - given(bidderCatalog.bidderInfoByName(eq("bidderName1"))).willReturn(givenBidderInfo()); - given(bidderCatalog.bidderInfoByName(eq("bidderAlias1"))).willReturn(givenBidderInfo("bidderName1")); + given(bidderCatalog.bidderInfoByName("bidderName1")).willReturn(givenBidderInfo()); + given(bidderCatalog.bidderInfoByName("bidderAlias2")).willReturn(givenBidderInfo()); + given(bidderCatalog.bidderInfoByName(eq("bidderName2"))) + .willReturn(givenBidderInfo(false, "http://", null)); + given(bidderCatalog.bidderInfoByName(eq("bidderAlias1"))) + .willReturn(givenBidderInfo(false, "http://", "bidderName1")); handler = new BidderDetailsHandler(bidderCatalog, jacksonMapper); } @@ -95,7 +95,7 @@ public void shouldRespondWithHttpStatus404IfNoBidderFound() { } @Test - public void shouldRespondWithHttpStatus404IfBidderIsDisabled() { + public void shouldRespondWithExpectedBodyForDisabledBidder() { // given given(httpRequest.getParam(anyString())).willReturn("bidderName2"); @@ -103,11 +103,14 @@ public void shouldRespondWithHttpStatus404IfBidderIsDisabled() { handler.handle(routingContext); // then - verify(httpResponse).setStatusCode(404); + verify(httpResponse).end("{\"status\":\"DISABLED\",\"usesHttps\":false," + + "\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}"); } @Test - public void shouldRespondWithHttpStatus404IfBidderAliasIsDisabled() { + public void shouldRespondWithExpecteddBodyForDisabledAlias() { // given given(httpRequest.getParam(anyString())).willReturn("bidderAlias2"); @@ -115,7 +118,10 @@ public void shouldRespondWithHttpStatus404IfBidderAliasIsDisabled() { handler.handle(routingContext); // then - verify(httpResponse).setStatusCode(404); + verify(httpResponse).end("{\"status\":\"ACTIVE\",\"usesHttps\":true," + + "\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}"); } @Test @@ -125,8 +131,9 @@ public void shouldRespondWithExpectedBody() { // then verify(httpResponse).end( - eq("{\"maintainer\":{\"email\":\"test@email.org\"},\"capabilities\":{\"app\":" - + "{\"mediaTypes\":[\"mediaType1\"]},\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}")); + eq("{\"status\":\"ACTIVE\",\"usesHttps\":true,\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}")); } @Test @@ -139,9 +146,9 @@ public void shouldRespondWithExpectedBodyForBidderAlias() { // then verify(httpResponse).end( - eq("{\"maintainer\":{\"email\":\"test@email.org\"},\"capabilities\":{\"app\":" - + "{\"mediaTypes\":[\"mediaType1\"]},\"site\":{\"mediaTypes\":[\"mediaType2\"]}}," - + "\"aliasOf\":\"bidderName1\"}")); + eq("{\"status\":\"DISABLED\",\"usesHttps\":false,\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}},\"aliasOf\":\"bidderName1\"}")); } @Test @@ -154,16 +161,27 @@ public void shouldRespondWithExpectedBodyForAllQueryParam() { // then verify(httpResponse).end( - eq("{\"bidderAlias1\":{\"maintainer\":{\"email\":\"test@email.org\"},\"capabilities\":" - + "{\"app\":{\"mediaTypes\":[\"mediaType1\"]},\"site\":{\"mediaTypes\":[\"mediaType2\"]}}," - + "\"aliasOf\":\"bidderName1\"}," - + "\"bidderName1\":{\"maintainer\":{\"email\":\"test@email.org\"},\"capabilities\":" - + "{\"app\":{\"mediaTypes\":[\"mediaType1\"]},\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}}")); + eq("{\"bidderAlias1\":{\"status\":\"DISABLED\",\"usesHttps\":false," + + "\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}},\"aliasOf\":\"bidderName1\"}," + + "\"bidderAlias2\":{\"status\":\"ACTIVE\",\"usesHttps\":true," + + "\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}},\"bidderName1\":{\"status\":\"ACTIVE\"," + + "\"usesHttps\":true,\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}," + + "\"bidderName2\":{\"status\":\"DISABLED\",\"usesHttps\":false," + + "\"maintainer\":{\"email\":\"test@email.org\"}," + + "\"capabilities\":{\"app\":{\"mediaTypes\":[\"mediaType1\"]}," + + "\"site\":{\"mediaTypes\":[\"mediaType2\"]}}}}")); } - private static BidderInfo givenBidderInfo(String aliasOf) { + private static BidderInfo givenBidderInfo(boolean enabled, String endpoint, String aliasOf) { return BidderInfo.create( - true, + enabled, + endpoint, aliasOf, "test@email.org", singletonList("mediaType1"), @@ -176,6 +194,6 @@ private static BidderInfo givenBidderInfo(String aliasOf) { } private static BidderInfo givenBidderInfo() { - return givenBidderInfo(null); + return givenBidderInfo(true, "https://endpoint.com", null); } } diff --git a/src/test/java/org/prebid/server/handler/info/BiddersHandlerTest.java b/src/test/java/org/prebid/server/handler/info/BiddersHandlerTest.java index 128551cf545..446b6a09fab 100644 --- a/src/test/java/org/prebid/server/handler/info/BiddersHandlerTest.java +++ b/src/test/java/org/prebid/server/handler/info/BiddersHandlerTest.java @@ -19,7 +19,6 @@ import static java.util.Collections.emptySet; import static org.assertj.core.api.Assertions.assertThatNullPointerException; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -66,18 +65,15 @@ public void shouldRespondWithExpectedHeaders() { } @Test - public void shouldRespondWithExpectedBodyAndExcludeNotActiveBidders() { + public void shouldRespondWithExpectedBody() { // given given(bidderCatalog.names()).willReturn(new HashSet<>(asList("bidder2", "bidder3", "bidder1"))); - given(bidderCatalog.isActive(anyString())).willReturn(true); - given(bidderCatalog.isActive(eq("bidder3"))).willReturn(false); - handler = new BiddersHandler(bidderCatalog, jacksonMapper); // when handler.handle(routingContext); // then - verify(httpResponse).end(eq("[\"bidder1\",\"bidder2\"]")); + verify(httpResponse).end(eq("[\"bidder1\",\"bidder2\",\"bidder3\"]")); } } diff --git a/src/test/java/org/prebid/server/validation/BidderParamValidatorTest.java b/src/test/java/org/prebid/server/validation/BidderParamValidatorTest.java index 2864d8f443c..2751185b181 100644 --- a/src/test/java/org/prebid/server/validation/BidderParamValidatorTest.java +++ b/src/test/java/org/prebid/server/validation/BidderParamValidatorTest.java @@ -442,6 +442,7 @@ public void schemaShouldReturnSchemasString() throws IOException { private static BidderInfo givenBidderInfo(String aliasOf) { return BidderInfo.create( true, + "https://endpoint.com", aliasOf, null, null, diff --git a/src/test/resources/org/prebid/server/it/info-bidders/test-info-bidder-details-response.json b/src/test/resources/org/prebid/server/it/info-bidders/test-info-bidder-details-response.json index f0cec89cd02..5c9f462d1a0 100644 --- a/src/test/resources/org/prebid/server/it/info-bidders/test-info-bidder-details-response.json +++ b/src/test/resources/org/prebid/server/it/info-bidders/test-info-bidder-details-response.json @@ -1,4 +1,6 @@ { + "status":"ACTIVE", + "usesHttps": false, "maintainer": { "email": "header-bidding@rubiconproject.com" }, @@ -15,4 +17,4 @@ ] } } -} \ No newline at end of file +} From e4f4a670d26a824cf783c0e4c8eccfdbf9d092d5 Mon Sep 17 00:00:00 2001 From: Braslavskyi Andrii Date: Wed, 11 Aug 2021 07:59:07 +0300 Subject: [PATCH 09/13] Add headers to response debug section (#1147) --- .../server/auction/BidResponseCreator.java | 1 + .../server/bidder/HttpBidderRequester.java | 4 +- .../org/prebid/server/cache/CacheService.java | 8 +- .../server/cache/model/DebugHttpCall.java | 5 + .../openrtb/ext/response/ExtHttpCall.java | 5 + .../java/org/prebid/server/util/HttpUtil.java | 26 ++ .../bidder/HttpBidderRequesterTest.java | 311 ++++++++++-------- .../prebid/server/cache/CacheServiceTest.java | 14 + ...est-auction-rubicon-appnexus-response.json | 70 ++++ 9 files changed, 311 insertions(+), 133 deletions(-) diff --git a/src/main/java/org/prebid/server/auction/BidResponseCreator.java b/src/main/java/org/prebid/server/auction/BidResponseCreator.java index aea80ab3fc4..ddae0ed9544 100644 --- a/src/main/java/org/prebid/server/auction/BidResponseCreator.java +++ b/src/main/java/org/prebid/server/auction/BidResponseCreator.java @@ -724,6 +724,7 @@ private static ExtHttpCall toExtHttpCall(DebugHttpCall debugHttpCall) { .requestbody(debugHttpCall.getRequestBody()) .status(debugHttpCall.getResponseStatus()) .responsebody(debugHttpCall.getResponseBody()) + .requestheaders(debugHttpCall.getRequestHeaders()) .build(); } diff --git a/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java b/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java index 763d6586177..11011e40066 100644 --- a/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java +++ b/src/main/java/org/prebid/server/bidder/HttpBidderRequester.java @@ -21,6 +21,7 @@ import org.prebid.server.execution.Timeout; import org.prebid.server.model.CaseInsensitiveMultiMap; import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall; +import org.prebid.server.util.HttpUtil; import org.prebid.server.vertx.http.HttpClient; import org.prebid.server.vertx.http.model.HttpClientResponse; @@ -313,7 +314,8 @@ private static ExtHttpCall toExt(HttpCall httpCall) { final HttpRequest request = httpCall.getRequest(); final ExtHttpCall.ExtHttpCallBuilder builder = ExtHttpCall.builder() .uri(request.getUri()) - .requestbody(request.getBody()); + .requestbody(request.getBody()) + .requestheaders(HttpUtil.toDebugHeaders(request.getHeaders())); final HttpResponse response = httpCall.getResponse(); if (response != null) { diff --git a/src/main/java/org/prebid/server/cache/CacheService.java b/src/main/java/org/prebid/server/cache/CacheService.java index 8bedc9b5ae2..8150e30500b 100644 --- a/src/main/java/org/prebid/server/cache/CacheService.java +++ b/src/main/java/org/prebid/server/cache/CacheService.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.node.TextNode; import com.iab.openrtb.request.Imp; import io.vertx.core.Future; +import io.vertx.core.MultiMap; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import lombok.Value; @@ -61,6 +62,8 @@ public class CacheService { private static final Logger logger = LoggerFactory.getLogger(CacheService.class); + private static final MultiMap CACHE_HEADERS = HttpUtil.headers(); + private static final Map> DEBUG_HEADERS = HttpUtil.toDebugHeaders(CACHE_HEADERS); private static final String BID_WURL_ATTRIBUTE = "wurl"; private final CacheTtl mediaTypeCacheTtl; @@ -124,7 +127,7 @@ private Future makeRequest( } final long startTime = clock.millis(); - return httpClient.post(endpointUrl.toString(), HttpUtil.headers(), mapper.encode(bidCacheRequest), + return httpClient.post(endpointUrl.toString(), CACHE_HEADERS, mapper.encode(bidCacheRequest), remainingTimeout) .map(response -> toBidCacheResponse( response.getStatusCode(), response.getBody(), bidCount, accountId, startTime)) @@ -307,7 +310,7 @@ private Future doCacheOpenrtb(List bids, final CacheHttpRequest httpRequest = CacheHttpRequest.of(url, body); final long startTime = clock.millis(); - return httpClient.post(url, HttpUtil.headers(), body, remainingTimeout) + return httpClient.post(url, CACHE_HEADERS, body, remainingTimeout) .map(response -> processResponseOpenrtb( response, httpRequest, cachedCreatives.size(), bids, videoBids, accountId, startTime)) .otherwise(exception -> failResponseOpenrtb(exception, accountId, httpRequest, startTime)); @@ -368,6 +371,7 @@ private DebugHttpCall makeDebugHttpCall(String endpoint, CacheHttpRequest httpRe .responseStatus(httpResponse != null ? httpResponse.getStatusCode() : null) .responseBody(httpResponse != null ? httpResponse.getBody() : null) .responseTimeMillis(responseTime(startTime)) + .requestHeaders(DEBUG_HEADERS) .build(); } diff --git a/src/main/java/org/prebid/server/cache/model/DebugHttpCall.java b/src/main/java/org/prebid/server/cache/model/DebugHttpCall.java index ef30c0c6027..19f0a3440b4 100644 --- a/src/main/java/org/prebid/server/cache/model/DebugHttpCall.java +++ b/src/main/java/org/prebid/server/cache/model/DebugHttpCall.java @@ -3,6 +3,9 @@ import lombok.Builder; import lombok.Value; +import java.util.List; +import java.util.Map; + /** * Holds HTTP interaction related data. */ @@ -20,5 +23,7 @@ public class DebugHttpCall { String responseBody; + Map> requestHeaders; + Integer responseTimeMillis; } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtHttpCall.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtHttpCall.java index fae55c73cab..d57adfc178d 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtHttpCall.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtHttpCall.java @@ -3,6 +3,9 @@ import lombok.Builder; import lombok.Value; +import java.util.List; +import java.util.Map; + /** * Defines the contract for a bidresponse.ext.debug.httpcalls.{bidder}[i] */ @@ -16,5 +19,7 @@ public class ExtHttpCall { String responsebody; + Map> requestheaders; + Integer status; } diff --git a/src/main/java/org/prebid/server/util/HttpUtil.java b/src/main/java/org/prebid/server/util/HttpUtil.java index 7f5cfa63bbe..4ed04cc0ed1 100644 --- a/src/main/java/org/prebid/server/util/HttpUtil.java +++ b/src/main/java/org/prebid/server/util/HttpUtil.java @@ -20,8 +20,12 @@ import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -60,6 +64,7 @@ public final class HttpUtil { public static final CharSequence ACCEPT_ENCODING_HEADER = HttpHeaders.createOptimized("Accept-Encoding"); public static final CharSequence X_OPENRTB_VERSION_HEADER = HttpHeaders.createOptimized("x-openrtb-version"); public static final CharSequence X_PREBID_HEADER = HttpHeaders.createOptimized("x-prebid"); + private static final Set SENSITIVE_HEADERS = new HashSet<>(Arrays.asList(AUTHORIZATION_HEADER.toString())); private HttpUtil() { } @@ -178,4 +183,25 @@ public static boolean executeSafely(RoutingContext routingContext, String endpoi return false; } } + + /** + * Converts {@link MultiMap} headers format to Map, where keys are headers names and values are lists + * of header's values + */ + public static Map> toDebugHeaders(MultiMap headers) { + return headers != null + ? headers.entries().stream() + .filter(entry -> !isSensitiveHeader(entry.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, + entry -> StringUtils.isNotBlank(entry.getValue()) + ? Arrays.stream(entry.getValue().split(",")) + .map(String::trim) + .collect(Collectors.toList()) + : Collections.singletonList(entry.getValue()))) + : null; + } + + private static boolean isSensitiveHeader(String header) { + return SENSITIVE_HEADERS.stream().anyMatch(header::equalsIgnoreCase); + } } diff --git a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java index ca21f950bb3..467bbf4186a 100644 --- a/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java +++ b/src/test/java/org/prebid/server/bidder/HttpBidderRequesterTest.java @@ -14,7 +14,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.BDDMockito; -import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -38,11 +37,13 @@ import java.time.Instant; import java.time.ZoneId; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeoutException; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -74,8 +75,6 @@ public class HttpBidderRequesterTest extends VertxTest { private RoutingContext routingContext; @Mock private HttpServerRequest httpServerRequest; - @Captor - private ArgumentCaptor headerCaptor; private HttpBidderRequester httpBidderRequester; @@ -144,12 +143,12 @@ public void shouldPassStoredResponseToBidderMakeBidsMethodAndReturnSeatBids() { headers.add("header1", "value1"); headers.add("header2", "value2"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri") - .body("requestBody") - .headers(headers) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri") + .body("requestBody") + .headers(headers) + .build()), emptyList())); final List bids = asList(BidderBid.of(null, null, null), BidderBid.of(null, null, null)); @@ -180,18 +179,18 @@ public void shouldMakeRequestToBidderWhenStoredResponseDefinedButBidderCreatesMo headers.add("header1", "value1"); headers.add("header2", "value2"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri") - .body("requestBody") - .headers(headers) - .build(), - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri") - .body("requestBody2") - .headers(headers) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri") + .body("requestBody") + .headers(headers) + .build(), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri") + .body("requestBody2") + .headers(headers) + .build()), emptyList())); final BidderRequest bidderRequest = BidderRequest.of("bidder", "storedResponse", BidRequest.builder().build()); @@ -209,10 +208,10 @@ public void shouldSendPopulatedGetRequestWithoutBody() { givenHttpClientReturnsResponse(200, null); given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.GET) - .uri("uri") - .build()), + HttpRequest.builder() + .method(HttpMethod.GET) + .uri("uri") + .build()), emptyList())); final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); @@ -230,18 +229,18 @@ public void shouldSendMultipleRequests() { givenHttpClientReturnsResponse(200, null); given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build()), emptyList())); final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); @@ -257,12 +256,12 @@ public void shouldSendMultipleRequests() { public void shouldReturnBidsCreatedByBidder() { // given given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build()), emptyList())); givenHttpClientReturnsResponse(200, "responseBody"); @@ -284,21 +283,24 @@ public void shouldReturnBidsCreatedByBidder() { @Test public void shouldReturnFullDebugInfoIfDebugEnabled() { // given + final MultiMap headers = new CaseInsensitiveHeaders().add("headerKey", "headerValue"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri1") - .body("requestBody1") - .headers(new CaseInsensitiveHeaders()) - .build(), - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri2") - .body("requestBody2") - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri1") + .body("requestBody1") + .headers(headers) + .build(), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri2") + .body("requestBody2") + .headers(headers) + .build()), emptyList())); + given(requestEnricher.enrichHeaders(any(), any(), any())).willReturn(headers); + givenHttpClientReturnsResponses( HttpClientResponse.of(200, null, "responseBody1"), HttpClientResponse.of(200, null, "responseBody2")); @@ -315,23 +317,61 @@ public void shouldReturnFullDebugInfoIfDebugEnabled() { // then assertThat(bidderSeatBid.getHttpCalls()).hasSize(2).containsOnly( ExtHttpCall.builder().uri("uri1").requestbody("requestBody1").responsebody("responseBody1") + .requestheaders(singletonMap("headerKey", singletonList("headerValue"))) .status(200).build(), ExtHttpCall.builder().uri("uri2").requestbody("requestBody2").responsebody("responseBody2") + .requestheaders(singletonMap("headerKey", singletonList("headerValue"))) .status(200).build()); } + @Test + public void shouldNotReturnSensitiveHeadersInFullDebugInfo() { + // given + final CaseInsensitiveHeaders headers = new CaseInsensitiveHeaders(); + headers.add("headerKey", "headerValue"); + headers.add("Authorization", "authorizationValue"); + given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri1") + .body("requestBody1") + .headers(headers) + .build()), + emptyList())); + given(requestEnricher.enrichHeaders(any(), any(), any())).willReturn(headers); + + givenHttpClientReturnsResponses( + HttpClientResponse.of(200, null, "responseBody1")); + + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); + + // when + final BidderSeatBid bidderSeatBid = + httpBidderRequester + .requestBids(bidder, bidderRequest, timeout, CaseInsensitiveMultiMap.empty(), true).result(); + + // then + assertThat(bidderSeatBid.getHttpCalls()) + .extracting(ExtHttpCall::getRequestheaders) + .flatExtracting(Map::keySet) + .containsExactly("headerKey"); + } + @Test public void shouldReturnPartialDebugInfoIfDebugEnabledAndGlobalTimeoutAlreadyExpired() { // given + final MultiMap headers = new CaseInsensitiveHeaders().add("headerKey", "headerValue"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri1") - .body("requestBody1") - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri1") + .headers(headers) + .body("requestBody1") + .build()), emptyList())); + given(requestEnricher.enrichHeaders(any(), any(), any())).willReturn(headers); + final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); // when @@ -341,21 +381,26 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndGlobalTimeoutAlreadyExp // then assertThat(bidderSeatBid.getHttpCalls()).hasSize(1).containsOnly( - ExtHttpCall.builder().uri("uri1").requestbody("requestBody1").build()); + ExtHttpCall.builder().uri("uri1").requestbody("requestBody1") + .requestheaders(singletonMap("headerKey", singletonList("headerValue"))) + .build()); } @Test public void shouldReturnPartialDebugInfoIfDebugEnabledAndHttpErrorOccurs() { // given + final MultiMap headers = new CaseInsensitiveHeaders().add("headerKey", "headerValue"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri1") - .body("requestBody1") - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri1") + .body("requestBody1") + .headers(headers) + .build()), emptyList())); + given(requestEnricher.enrichHeaders(any(), any(), any())).willReturn(headers); + givenHttpClientProducesException(new RuntimeException("Request exception")); final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); @@ -367,21 +412,26 @@ public void shouldReturnPartialDebugInfoIfDebugEnabledAndHttpErrorOccurs() { // then assertThat(bidderSeatBid.getHttpCalls()).hasSize(1).containsOnly( - ExtHttpCall.builder().uri("uri1").requestbody("requestBody1").build()); + ExtHttpCall.builder().uri("uri1").requestbody("requestBody1") + .requestheaders(singletonMap("headerKey", singletonList("headerValue"))) + .build()); } @Test public void shouldReturnFullDebugInfoIfDebugEnabledAndErrorStatus() { // given + final MultiMap headers = new CaseInsensitiveHeaders().add("headerKey", "headerValue"); given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri("uri1") - .body("requestBody1") - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri("uri1") + .body("requestBody1") + .headers(headers) + .build()), emptyList())); + given(requestEnricher.enrichHeaders(any(), any(), any())).willReturn(headers); + givenHttpClientReturnsResponses(HttpClientResponse.of(500, null, "responseBody1")); final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); @@ -394,22 +444,23 @@ public void shouldReturnFullDebugInfoIfDebugEnabledAndErrorStatus() { // then assertThat(bidderSeatBid.getHttpCalls()).hasSize(1).containsOnly( ExtHttpCall.builder().uri("uri1").requestbody("requestBody1").responsebody("responseBody1") + .requestheaders(singletonMap("headerKey", singletonList("headerValue"))) .status(500).build()); assertThat(bidderSeatBid.getErrors()).hasSize(1) .extracting(BidderError::getMessage).containsOnly( - "Unexpected status code: 500. Run with request.test = 1 for more info"); + "Unexpected status code: 500. Run with request.test = 1 for more info"); } @Test public void shouldTolerateAlreadyExpiredGlobalTimeout() { // given given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build()), emptyList())); final BidderRequest bidderRequest = BidderRequest.of("bidder", null, BidRequest.builder().build()); @@ -454,48 +505,48 @@ public void shouldNotifyBidderOfTimeout() { public void shouldTolerateMultipleErrors() { // given given(bidder.makeHttpRequests(any())).willReturn(Result.of(asList( - // this request will fail with response exception - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - // this request will fail with timeout - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - // this request will fail with 500 status - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - // this request will fail with 400 status - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - // this request will get 204 status - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build(), - // finally this request will succeed - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build()), + // this request will fail with response exception + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + // this request will fail with timeout + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + // this request will fail with 500 status + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + // this request will fail with 400 status + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + // this request will get 204 status + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build(), + // finally this request will succeed + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build()), singletonList(BidderError.badInput("makeHttpRequestsError")))); when(requestEnricher.enrichHeaders(any(), any(), any())).thenAnswer(invocation -> new CaseInsensitiveHeaders()); given(httpClient.request(any(), anyString(), any(), anyString(), anyLong())) @@ -540,12 +591,12 @@ public void shouldTolerateMultipleErrors() { public void shouldNotMakeBidsIfResponseStatusIs204() { // given given(bidder.makeHttpRequests(any())).willReturn(Result.of(singletonList( - HttpRequest.builder() - .method(HttpMethod.POST) - .uri(EMPTY) - .body(EMPTY) - .headers(new CaseInsensitiveHeaders()) - .build()), + HttpRequest.builder() + .method(HttpMethod.POST) + .uri(EMPTY) + .body(EMPTY) + .headers(new CaseInsensitiveHeaders()) + .build()), emptyList())); givenHttpClientReturnsResponse(204, EMPTY); diff --git a/src/test/java/org/prebid/server/cache/CacheServiceTest.java b/src/test/java/org/prebid/server/cache/CacheServiceTest.java index 471e3b28682..caf6aede045 100644 --- a/src/test/java/org/prebid/server/cache/CacheServiceTest.java +++ b/src/test/java/org/prebid/server/cache/CacheServiceTest.java @@ -48,7 +48,9 @@ import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.UnaryOperator; import static java.util.Arrays.asList; @@ -255,6 +257,7 @@ public void cacheBidsOpenrtbShouldTolerateReadingHttpResponseFails() throws Json final CacheHttpRequest request = givenCacheHttpRequest(bidinfo.getBid()); assertThat(result.getHttpCall()) .isEqualTo(DebugHttpCall.builder() + .requestHeaders(givenDebugHeaders()) .endpoint("http://cache-service/cache") .requestBody(request.getBody()) .requestUri(request.getUri()) @@ -289,6 +292,7 @@ public void cacheBidsOpenrtbShouldTolerateResponseCodeIsNot200() throws JsonProc .requestBody(request.getBody()) .requestUri(request.getUri()) .responseStatus(503) + .requestHeaders(givenDebugHeaders()) .responseBody("response") .responseTimeMillis(0) .build()); @@ -320,6 +324,7 @@ public void cacheBidsOpenrtbShouldTolerateResponseBodyCouldNotBeParsed() throws .endpoint("http://cache-service/cache") .requestUri(request.getUri()) .requestBody(request.getBody()) + .requestHeaders(givenDebugHeaders()) .responseStatus(200) .responseBody("response") .responseTimeMillis(0) @@ -354,6 +359,7 @@ public void cacheBidsOpenrtbShouldTolerateCacheEntriesNumberDoesNotMatchBidsNumb .endpoint("http://cache-service/cache") .requestBody(request.getBody()) .requestUri(request.getUri()) + .requestHeaders(givenDebugHeaders()) .responseStatus(200).responseBody("{}") .responseTimeMillis(0) .build()); @@ -381,6 +387,7 @@ public void cacheBidsOpenrtbShouldReturnExpectedDebugInfo() throws JsonProcessin .endpoint("http://cache-service/cache") .requestUri(request.getUri()) .requestBody(request.getBody()) + .requestHeaders(givenDebugHeaders()) .responseStatus(200) .responseBody("{\"responses\":[{\"uuid\":\"uuid1\"}]}") .responseTimeMillis(0) @@ -896,4 +903,11 @@ private BidCacheRequest captureBidCacheRequest() throws IOException { verify(httpClient).post(anyString(), any(), captor.capture(), anyLong()); return mapper.readValue(captor.getValue(), BidCacheRequest.class); } + + private Map> givenDebugHeaders() { + final Map> headers = new HashMap<>(); + headers.put("Accept", singletonList("application/json")); + headers.put("Content-Type", singletonList("application/json;charset=utf-8")); + return headers; + } } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json b/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json index 97781e502b2..27f1506c80a 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json @@ -343,6 +343,14 @@ "uri": "{{ cache.endpoint }}", "requestbody": "{\"puts\":[{\"type\":\"json\",\"value\":{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600,\"ext\":{\"origbidcpm\":4.26,\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5.5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"cat\":[],\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"a121a07f-1579-4465-bc5e-5c5b02a0c421\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.9,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.9,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1,\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adid\":\"69595837\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3},\"origbidcpm\":1,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"native\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"f227a07f-1579-4465-bc5e-5c5b02a0c180\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.8,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.8,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]},\"origbidcpm\":8.43,\"prebid\":{\"type\":\"video\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"xml\",\"value\":\"\",\"ttlseconds\":120,\"aid\":\"tid\"}]}", "responsebody": "{\"responses\":[{\"uuid\":\"4fe59ef5-6fb4-48c5-88b6-9870257fc49e\"},{\"uuid\":\"117431c9-807a-41e1-82a7-dcd8f8875493\"},{\"uuid\":\"91912e5b-dfa8-42bc-9c7e-df6ce0449c19\"},{\"uuid\":\"765e116a-5773-49d5-a648-0b97a9907a4e\"},{\"uuid\":\"6cf69b42-96f5-4ba1-a984-a9b4d8ff21cf\"},{\"uuid\":\"c75130ed-bcdd-4821-ad91-90cf835615c5\"},{\"uuid\":\"683fe79f-6df7-4971-ac70-820e0486992d\"},{\"uuid\":\"b2528f73-96ab-42ab-8f15-fbe6ed779a26\"}]}", + "requestheaders": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, "status": 200 } ], @@ -351,6 +359,20 @@ "uri": "{{ appnexus.exchange_uri }}?member_id=103", "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":3},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=bar,foo=baz\",\"traffic_source_code\":\"trafficSource\"}}},{\"id\":\"impId131\",\"native\":{\"request\":\"{\\\"ver\\\":\\\"1.1\\\",\\\"context\\\":1,\\\"contextsubtype\\\":11,\\\"plcmttype\\\":4,\\\"plcmtcnt\\\":1,\\\"assets\\\":[{\\\"id\\\":0,\\\"required\\\":1,\\\"title\\\":{\\\"len\\\":500}},{\\\"id\\\":1,\\\"required\\\":1,\\\"img\\\":{\\\"type\\\":3,\\\"wmin\\\":1,\\\"hmin\\\":1}},{\\\"id\\\":2,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":4,\\\"len\\\":200}},{\\\"id\\\":3,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":2,\\\"len\\\":15000}},{\\\"id\\\":4,\\\"required\\\":0,\\\"data\\\":{\\\"len\\\":40}},{\\\"id\\\":5,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":11}}]}\",\"ver\":\"1.1\"},\"ext\":{\"appnexus\":{\"placement_id\":9880618}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"958\",\"bid\":[{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}},{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1.0,\"adid\":\"69595837\",\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", + "requestheaders": { + "Accept": [ + "application/json" + ], + "x-prebid": [ + "pbs-java/1.70.0" + ], + "Sec-GPC": [ + "1" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, "status": 200 } ], @@ -359,6 +381,20 @@ "uri": "{{ appnexus.exchange_uri }}?member_id=104", "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":1},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=barAlias,foo=bazAlias\",\"traffic_source_code\":\"trafficSourceAlias\"}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"959\",\"bid\":[{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5.0,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", + "requestheaders": { + "Accept": [ + "application/json" + ], + "x-prebid": [ + "pbs-java/1.70.0" + ], + "Sec-GPC": [ + "1" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, "status": 200 } ], @@ -367,12 +403,46 @@ "uri": "{{ rubicon.exchange_uri }}?tk_xint=dmbjs", "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId1\",\"video\":{\"mimes\":[\"mimes\"],\"minduration\":20,\"maxduration\":60,\"protocols\":[1],\"w\":300,\"h\":250,\"startdelay\":5,\"skipmin\":0,\"skipafter\":0,\"playbackmethod\":[1],\"ext\":{\"skip\":5,\"skipdelay\":1,\"rp\":{\"size_id\":15},\"videotype\":\"rewarded\"}},\"ext\":{\"rp\":{\"zone_id\":4001,\"target\":{\"rating\":[\"5-star\"],\"prodtype\":[\"tech\"],\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":2001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":3001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"ucat\":[\"new\"],\"search\":[\"iphone\"],\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", "responsebody": "{\"id\":\"bidResponseId1\",\"seatbid\":[{\"bid\":[{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]}}}],\"seat\":\"seatId1\",\"group\":0}]}", + "requestheaders": { + "Accept": [ + "application/json" + ], + "x-prebid": [ + "pbs-java/1.70.0" + ], + "User-Agent": [ + "prebid-server/1.0" + ], + "Sec-GPC": [ + "1" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, "status": 200 }, { "uri": "{{ rubicon.exchange_uri }}?tk_xint=dmbjs", "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId2\",\"banner\":{\"format\":[{\"w\":300,\"h\":600}],\"w\":300,\"h\":600,\"ext\":{\"rp\":{\"size_id\":10,\"mime\":\"text/html\"}}},\"ext\":{\"rp\":{\"zone_id\":7001,\"target\":{\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":5001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":6001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", "responsebody": "{\"id\":\"bidResponseId2\",\"seatbid\":[{\"bid\":[{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600}],\"seat\":\"seatId2\",\"group\":0}]}", + "requestheaders": { + "Accept": [ + "application/json" + ], + "x-prebid": [ + "pbs-java/1.70.0" + ], + "User-Agent": [ + "prebid-server/1.0" + ], + "Sec-GPC": [ + "1" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, "status": 200 } ] From 182ad4ea7f0de7f79a78be06874ac81873e382df Mon Sep 17 00:00:00 2001 From: Alex Maltsev Date: Wed, 11 Aug 2021 08:06:02 +0300 Subject: [PATCH 10/13] Remove redundant meta model (#1415) --- .../server/bidder/rubicon/RubiconBidder.java | 9 ++-- .../openrtb/ext/response/ExtBidPrebid.java | 3 +- .../ext/response/ExtBidPrebidMeta.java | 48 ------------------- .../bidder/rubicon/RubiconBidderTest.java | 6 +-- 4 files changed, 9 insertions(+), 57 deletions(-) delete mode 100644 src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebidMeta.java diff --git a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java index 4b2527e3ab7..ee55f9b8fd7 100644 --- a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java +++ b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.ImmutableSet; import com.iab.openrtb.request.App; @@ -88,7 +89,6 @@ import org.prebid.server.proto.openrtb.ext.request.rubicon.RubiconVideoParams; 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.util.HttpUtil; import java.math.BigDecimal; @@ -1316,11 +1316,10 @@ private Bid insertNetworkIdToMeta(Bid bid, int networkId, List erro return null; } final ExtBidPrebid extBidPrebid = extPrebid != null ? extPrebid.getPrebid() : null; - final ExtBidPrebidMeta meta = extBidPrebid != null ? extBidPrebid.getMeta() : null; + final ObjectNode meta = extBidPrebid != null ? extBidPrebid.getMeta() : null; - final ExtBidPrebidMeta updatedMeta = meta != null - ? meta.toBuilder().networkId(networkId).build() - : ExtBidPrebidMeta.builder().networkId(networkId).build(); + final ObjectNode updatedMeta = meta != null ? meta : mapper.mapper().createObjectNode(); + updatedMeta.set("networkId", IntNode.valueOf(networkId)); final ExtBidPrebid modifiedExtBidPrebid = extBidPrebid != null ? extBidPrebid.toBuilder().meta(updatedMeta).build() diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebid.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebid.java index f32c3485511..6eaae8e9393 100644 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebid.java +++ b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebid.java @@ -1,6 +1,7 @@ package org.prebid.server.proto.openrtb.ext.response; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.iab.openrtb.request.Video; import lombok.Builder; import lombok.Value; @@ -32,5 +33,5 @@ public class ExtBidPrebid { ExtBidPrebidVideo video; - ExtBidPrebidMeta meta; + ObjectNode meta; } diff --git a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebidMeta.java b/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebidMeta.java deleted file mode 100644 index cc980d905d8..00000000000 --- a/src/main/java/org/prebid/server/proto/openrtb/ext/response/ExtBidPrebidMeta.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.prebid.server.proto.openrtb.ext.response; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Value; - -import java.util.List; - -@Builder(toBuilder = true) -@Value -public class ExtBidPrebidMeta { - - @JsonProperty("advertiserId") - Integer advertiserId; - - @JsonProperty("advertiserName") - String advertiserName; - - @JsonProperty("agencyId") - Integer agencyId; - - @JsonProperty("agencyName") - String agencyName; - - @JsonProperty("brandId") - Integer brandId; - - @JsonProperty("brandName") - String brandName; - - @JsonProperty("mediaType") - String mediaType; - - @JsonProperty("networkId") - Integer networkId; - - @JsonProperty("networkName") - String networkName; - - @JsonProperty("primaryCatId") - String primaryCatId; - - @JsonProperty("secondaryCatIds") - List secondaryCatIds; - - @JsonProperty("dChain") - String dChain; -} diff --git a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java index 281bfebdfda..c67debacee6 100644 --- a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; import com.iab.openrtb.request.App; @@ -84,7 +85,6 @@ import org.prebid.server.proto.openrtb.ext.request.rubicon.ExtUserTpIdRubicon; import org.prebid.server.proto.openrtb.ext.request.rubicon.RubiconVideoParams; import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid; -import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta; import org.prebid.server.util.HttpUtil; import java.io.IOException; @@ -2550,7 +2550,7 @@ public void makeBidsShouldSetSeatBuyerToMetaNetworkId() throws JsonProcessingExc // then final ObjectNode expectedBidExt = mapper.valueToTree( ExtPrebid.of(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().networkId(123).build()) + .meta(mapper.createObjectNode().set("networkId", IntNode.valueOf(123))) .build(), null)); assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) @@ -2953,7 +2953,7 @@ public void makeBidsShouldReturnBidWithCurrencyFromBidResponse() throws JsonProc public void makeBidsShouldReturnBidWithDchainFromRequest() throws JsonProcessingException { // given final ObjectNode requestNode = mapper.valueToTree(ExtBidPrebid.builder() - .meta(ExtBidPrebidMeta.builder().dChain("dChain").build()) + .meta(mapper.createObjectNode().set("dChain", TextNode.valueOf("dChain"))) .build()); final HttpCall httpCall = givenHttpCall( givenBidRequest(identity()), From a8621652c0335970c599fd76691f1fa926ddfda1 Mon Sep 17 00:00:00 2001 From: laarchenko <48104398+laarchenko@users.noreply.github.com> Date: Wed, 11 Aug 2021 17:15:40 +0300 Subject: [PATCH 11/13] Rubicon: Update site segTaxes, to work with 5 and 6 (#1404) --- .../org/prebid/server/bidder/rubicon/RubiconBidder.java | 2 +- .../prebid/server/bidder/rubicon/RubiconBidderTest.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java index ee55f9b8fd7..8286f71752f 100644 --- a/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java +++ b/src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java @@ -146,7 +146,7 @@ public class RubiconBidder implements Bidder { private static final String DMP_STYPE = "dmp"; private static final String XAPI_CURRENCY = "USD"; private static final Set USER_SEGTAXES = ImmutableSet.of(4); - private static final Set SITE_SEGTAXES = ImmutableSet.of(1, 2); + private static final Set SITE_SEGTAXES = ImmutableSet.of(1, 2, 5, 6); private static final Set STYPE_TO_REMOVE = new HashSet<>(Arrays.asList(PPUID_STYPE, SHA256EMAIL_STYPE, DMP_STYPE)); diff --git a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java index c67debacee6..ba84f312b10 100644 --- a/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java @@ -878,7 +878,7 @@ public void makeHttpRequestsShouldFillUserExtRpWithIabAttributeOnlyIfSegtaxIsEqu } @Test - public void makeHttpRequestsShouldFillSiteExtRpWithIabAttributeIfSegtaxEqualsOneOrTwo() { + public void makeHttpRequestsShouldFillSiteExtRpWithIabAttributeIfSegtaxEqualsOneOrTwoOrFiveOrSix() { // given final BidRequest bidRequest = givenBidRequest( builder -> builder.site(Site.builder() @@ -886,7 +886,9 @@ public void makeHttpRequestsShouldFillSiteExtRpWithIabAttributeIfSegtaxEqualsOne .data(asList( givenDataWithSegmentEntry(1, "firstSegmentId"), givenDataWithSegmentEntry(2, "secondSegmentId"), - givenDataWithSegmentEntry(3, "thirdSegmentId"))) + givenDataWithSegmentEntry(3, "thirdSegmentId"), + givenDataWithSegmentEntry(5, "fifthSegmentId"), + givenDataWithSegmentEntry(6, "sixthSegmentId"))) .build()) .build()), builder -> builder.video(Video.builder().build()), @@ -900,6 +902,8 @@ public void makeHttpRequestsShouldFillSiteExtRpWithIabAttributeIfSegtaxEqualsOne final ArrayNode expectedIabAttribute = expectedTarget.putArray("iab"); expectedIabAttribute.add("firstSegmentId"); expectedIabAttribute.add("secondSegmentId"); + expectedIabAttribute.add("fifthSegmentId"); + expectedIabAttribute.add("sixthSegmentId"); assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()).hasSize(1).doesNotContainNull() From 15ee0da58b198bb4c454a6678f647a1990df573f Mon Sep 17 00:00:00 2001 From: rpanchyk Date: Wed, 11 Aug 2021 17:19:50 +0300 Subject: [PATCH 12/13] Update TripleLift endpoint (#1418) --- src/main/resources/bidder-config/triplelift.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/bidder-config/triplelift.yaml b/src/main/resources/bidder-config/triplelift.yaml index ac984af1295..8f6cc913b57 100644 --- a/src/main/resources/bidder-config/triplelift.yaml +++ b/src/main/resources/bidder-config/triplelift.yaml @@ -1,7 +1,7 @@ adapters: triplelift: enabled: false - endpoint: https://tlx.3lift.com/s2s/auction?sra=1&supplier_id=20 + endpoint: https://tlx.3lift.com/s2s/auction?sra=1&supplier_id=39 pbs-enforces-gdpr: true pbs-enforces-ccpa: true modifying-vast-xml-allowed: true From 70e307d2a898b2f11ecb5d9c9b6f513b977735fa Mon Sep 17 00:00:00 2001 From: rpanchyk Date: Wed, 11 Aug 2021 18:21:42 +0300 Subject: [PATCH 13/13] Fix integration test against PBS version in debug header (#1416) --- .../org/prebid/server/it/ApplicationTest.java | 3 ++- .../org/prebid/server/it/IntegrationTest.java | 6 +++++- ...est-auction-rubicon-appnexus-response.json | 20 +++++++++---------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/test/java/org/prebid/server/it/ApplicationTest.java b/src/test/java/org/prebid/server/it/ApplicationTest.java index 2322b7f6494..598ef016b01 100644 --- a/src/test/java/org/prebid/server/it/ApplicationTest.java +++ b/src/test/java/org/prebid/server/it/ApplicationTest.java @@ -131,7 +131,8 @@ public void openrtb2AuctionShouldRespondWithBidsFromRubiconAndAppnexus() throws // then assertJsonEquals("openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json", - response, asList(RUBICON, APPNEXUS, APPNEXUS_ALIAS), openrtbCacheDebugCustomization()); + response, asList(RUBICON, APPNEXUS, APPNEXUS_ALIAS), + openrtbCacheDebugCustomization(), headersDebugCustomization()); } @Test diff --git a/src/test/java/org/prebid/server/it/IntegrationTest.java b/src/test/java/org/prebid/server/it/IntegrationTest.java index e5a481351fb..9ee6247ace1 100644 --- a/src/test/java/org/prebid/server/it/IntegrationTest.java +++ b/src/test/java/org/prebid/server/it/IntegrationTest.java @@ -197,6 +197,10 @@ static Customization openrtbCacheDebugCustomization() { return new Customization("ext.debug.httpcalls.cache", arrayValueMatcher); } + static Customization headersDebugCustomization() { + return new Customization("**.requestheaders.x-prebid", (o1, o2) -> true); + } + protected static void assertJsonEquals(String file, Response response, List bidders, @@ -213,7 +217,7 @@ protected static void assertJsonEquals(String file, JSONAssert.assertEquals(expectedRequest, response.asString(), new CustomComparator(JSONCompareMode.NON_EXTENSIBLE, - fullCustomizations.stream().toArray(Customization[]::new))); + fullCustomizations.toArray(new Customization[0]))); } private static String replaceStaticInfo(String json) { diff --git a/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json b/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json index 27f1506c80a..c4035b145bd 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/rubicon_appnexus/test-auction-rubicon-appnexus-response.json @@ -341,8 +341,6 @@ "cache": [ { "uri": "{{ cache.endpoint }}", - "requestbody": "{\"puts\":[{\"type\":\"json\",\"value\":{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600,\"ext\":{\"origbidcpm\":4.26,\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5.5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"cat\":[],\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"a121a07f-1579-4465-bc5e-5c5b02a0c421\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.9,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.9,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1,\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adid\":\"69595837\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3},\"origbidcpm\":1,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"native\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"f227a07f-1579-4465-bc5e-5c5b02a0c180\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.8,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.8,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]},\"origbidcpm\":8.43,\"prebid\":{\"type\":\"video\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"xml\",\"value\":\"\",\"ttlseconds\":120,\"aid\":\"tid\"}]}", - "responsebody": "{\"responses\":[{\"uuid\":\"4fe59ef5-6fb4-48c5-88b6-9870257fc49e\"},{\"uuid\":\"117431c9-807a-41e1-82a7-dcd8f8875493\"},{\"uuid\":\"91912e5b-dfa8-42bc-9c7e-df6ce0449c19\"},{\"uuid\":\"765e116a-5773-49d5-a648-0b97a9907a4e\"},{\"uuid\":\"6cf69b42-96f5-4ba1-a984-a9b4d8ff21cf\"},{\"uuid\":\"c75130ed-bcdd-4821-ad91-90cf835615c5\"},{\"uuid\":\"683fe79f-6df7-4971-ac70-820e0486992d\"},{\"uuid\":\"b2528f73-96ab-42ab-8f15-fbe6ed779a26\"}]}", "requestheaders": { "Accept": [ "application/json" @@ -351,14 +349,14 @@ "application/json;charset=utf-8" ] }, + "requestbody": "{\"puts\":[{\"type\":\"json\",\"value\":{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600,\"ext\":{\"origbidcpm\":4.26,\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=466223845&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5.5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184841&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5,\"adm\":\"some-test-ad\",\"adid\":\"29681110\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"cat\":[],\"w\":300,\"h\":250,\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0},\"origbidcpm\":5,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=7706636740145184840&a=5001&aid=tid&ts=1000&bidder=appnexusAlias&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"a121a07f-1579-4465-bc5e-5c5b02a0c421\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.9,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.9,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=a121a07f-1579-4465-bc5e-5c5b02a0c421&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1,\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adid\":\"69595837\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3},\"origbidcpm\":1,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"native\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=928185755156387460&a=5001&aid=tid&ts=1000&bidder=appnexus&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"f227a07f-1579-4465-bc5e-5c5b02a0c180\",\"impid\":\"impStoredAuctionResponse\",\"price\":0.8,\"crid\":\"crid1\",\"ext\":{\"origbidcpm\":0.8,\"origbidcur\":\"USD\",\"prebid\":{\"type\":\"banner\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=f227a07f-1579-4465-bc5e-5c5b02a0c180&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"json\",\"value\":{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]},\"origbidcpm\":8.43,\"prebid\":{\"type\":\"video\",\"events\":{\"win\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\",\"imp\":\"http://localhost:8080/event?t=imp&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"}}},\"wurl\":\"http://localhost:8080/event?t=win&b=880290288&a=5001&aid=tid&ts=1000&bidder=rubicon&f=i&int=dmbjs\"},\"aid\":\"tid\"},{\"type\":\"xml\",\"value\":\"\",\"ttlseconds\":120,\"aid\":\"tid\"}]}", + "responsebody": "{\"responses\":[{\"uuid\":\"4fe59ef5-6fb4-48c5-88b6-9870257fc49e\"},{\"uuid\":\"117431c9-807a-41e1-82a7-dcd8f8875493\"},{\"uuid\":\"91912e5b-dfa8-42bc-9c7e-df6ce0449c19\"},{\"uuid\":\"765e116a-5773-49d5-a648-0b97a9907a4e\"},{\"uuid\":\"6cf69b42-96f5-4ba1-a984-a9b4d8ff21cf\"},{\"uuid\":\"c75130ed-bcdd-4821-ad91-90cf835615c5\"},{\"uuid\":\"683fe79f-6df7-4971-ac70-820e0486992d\"},{\"uuid\":\"b2528f73-96ab-42ab-8f15-fbe6ed779a26\"}]}", "status": 200 } ], "appnexus": [ { "uri": "{{ appnexus.exchange_uri }}?member_id=103", - "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":3},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=bar,foo=baz\",\"traffic_source_code\":\"trafficSource\"}}},{\"id\":\"impId131\",\"native\":{\"request\":\"{\\\"ver\\\":\\\"1.1\\\",\\\"context\\\":1,\\\"contextsubtype\\\":11,\\\"plcmttype\\\":4,\\\"plcmtcnt\\\":1,\\\"assets\\\":[{\\\"id\\\":0,\\\"required\\\":1,\\\"title\\\":{\\\"len\\\":500}},{\\\"id\\\":1,\\\"required\\\":1,\\\"img\\\":{\\\"type\\\":3,\\\"wmin\\\":1,\\\"hmin\\\":1}},{\\\"id\\\":2,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":4,\\\"len\\\":200}},{\\\"id\\\":3,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":2,\\\"len\\\":15000}},{\\\"id\\\":4,\\\"required\\\":0,\\\"data\\\":{\\\"len\\\":40}},{\\\"id\\\":5,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":11}}]}\",\"ver\":\"1.1\"},\"ext\":{\"appnexus\":{\"placement_id\":9880618}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", - "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"958\",\"bid\":[{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}},{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1.0,\"adid\":\"69595837\",\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", "requestheaders": { "Accept": [ "application/json" @@ -373,14 +371,14 @@ "application/json;charset=utf-8" ] }, + "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":3},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=bar,foo=baz\",\"traffic_source_code\":\"trafficSource\"}}},{\"id\":\"impId131\",\"native\":{\"request\":\"{\\\"ver\\\":\\\"1.1\\\",\\\"context\\\":1,\\\"contextsubtype\\\":11,\\\"plcmttype\\\":4,\\\"plcmtcnt\\\":1,\\\"assets\\\":[{\\\"id\\\":0,\\\"required\\\":1,\\\"title\\\":{\\\"len\\\":500}},{\\\"id\\\":1,\\\"required\\\":1,\\\"img\\\":{\\\"type\\\":3,\\\"wmin\\\":1,\\\"hmin\\\":1}},{\\\"id\\\":2,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":4,\\\"len\\\":200}},{\\\"id\\\":3,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":2,\\\"len\\\":15000}},{\\\"id\\\":4,\\\"required\\\":0,\\\"data\\\":{\\\"len\\\":40}},{\\\"id\\\":5,\\\"required\\\":0,\\\"data\\\":{\\\"type\\\":11}}]}\",\"ver\":\"1.1\"},\"ext\":{\"appnexus\":{\"placement_id\":9880618}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", + "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"958\",\"bid\":[{\"id\":\"7706636740145184841\",\"impid\":\"impId3\",\"price\":5.5,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"ext\":{\"appnexus\":{\"brand_id\":1,\"auction_id\":8189378542222915032,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}},{\"id\":\"928185755156387460\",\"impid\":\"impId131\",\"price\":1.0,\"adid\":\"69595837\",\"adm\":\"{\\\"assets\\\":[{\\\"id\\\":0,\\\"title\\\":{\\\"text\\\":\\\"This is an example Prebid Native creative\\\"}},{\\\"id\\\":1,\\\"img\\\":{\\\"url\\\":\\\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\\\",\\\"w\\\":3000,\\\"h\\\":2250,\\\"ext\\\":{\\\"appnexus\\\":{\\\"prevent_crop\\\":0}}}},{\\\"id\\\":2,\\\"data\\\":{\\\"value\\\":\\\"Prebid.org\\\"}},{\\\"id\\\":3,\\\"data\\\":{\\\"value\\\":\\\"ThisisaPrebidNativeCreative.Therearemanylikeit,butthisoneismine.\\\"}}],\\\"link\\\":{\\\"url\\\":\\\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\\\"},\\\"imptrackers\\\":[\\\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\\\"],\\\"jstracker\\\":\\\"\\\"}\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=69595837\",\"cid\":\"958\",\"crid\":\"69595837\",\"ext\":{\"appnexus\":{\"brand_id\":1,\"brand_category_id\":1,\"auction_id\":5607483846416358664,\"bidder_id\":2,\"bid_ad_type\":3}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", "status": 200 } ], "appnexusAlias": [ { "uri": "{{ appnexus.exchange_uri }}?member_id=104", - "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":1},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=barAlias,foo=bazAlias\",\"traffic_source_code\":\"trafficSourceAlias\"}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", - "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"959\",\"bid\":[{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5.0,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", "requestheaders": { "Accept": [ "application/json" @@ -395,14 +393,14 @@ "application/json;charset=utf-8" ] }, + "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId3\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}],\"w\":300,\"h\":250,\"pos\":1},\"tagid\":\"abc\",\"bidfloor\":1.0,\"ext\":{\"appnexus\":{\"keywords\":\"foo=barAlias,foo=bazAlias\",\"traffic_source_code\":\"trafficSourceAlias\"}}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"id\":\"5001\",\"domain\":\"example.com\"},\"ext\":{\"amp\":0}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"prebid\":{\"interstitial\":{\"minwidthperc\":50,\"minheightperc\":60}}}},\"user\":{\"buyeruid\":\"12345\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}]}},\"at\":1,\"tmax\":5000,\"cur\":[\"USD\"],\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\"}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}},\"ext\":{\"prebid\":{\"debug\":1,\"aliases\":{\"appnexusAlias\":\"appnexus\"},\"currency\":{\"rates\":{\"EUR\":{\"USD\":1.2406},\"USD\":{\"EUR\":0.811}},\"usepbsrates\":false},\"targeting\":{\"pricegranularity\":{\"precision\":2,\"ranges\":[{\"max\":20,\"increment\":0.1}]},\"includewinners\":true,\"includebidderkeys\":true},\"cache\":{\"bids\":{},\"vastxml\":{\"ttlseconds\":120}},\"events\":{},\"auctiontimestamp\":1000,\"integration\":\"dmbjs\",\"channel\":{\"name\":\"web\"},\"pbs\":{\"endpoint\":\"/openrtb2/auction\"}}}}", + "responsebody": "{\"id\":\"tid\",\"seatbid\":[{\"seat\":\"959\",\"bid\":[{\"id\":\"7706636740145184840\",\"impid\":\"impId3\",\"price\":5.0,\"adid\":\"29681110\",\"adm\":\"some-test-ad\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\":250,\"w\":300,\"cat\":[\"IAB20-3\"],\"ext\":{\"appnexus\":{\"brand_id\":350,\"brand_category_id\":350,\"auction_id\":8189378542222915031,\"bidder_id\":2,\"bid_ad_type\":0,\"ranking_price\":0.0}}}]}],\"bidid\":\"5778926625248726496\",\"cur\":\"USD\"}", "status": 200 } ], "rubicon": [ { "uri": "{{ rubicon.exchange_uri }}?tk_xint=dmbjs", - "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId1\",\"video\":{\"mimes\":[\"mimes\"],\"minduration\":20,\"maxduration\":60,\"protocols\":[1],\"w\":300,\"h\":250,\"startdelay\":5,\"skipmin\":0,\"skipafter\":0,\"playbackmethod\":[1],\"ext\":{\"skip\":5,\"skipdelay\":1,\"rp\":{\"size_id\":15},\"videotype\":\"rewarded\"}},\"ext\":{\"rp\":{\"zone_id\":4001,\"target\":{\"rating\":[\"5-star\"],\"prodtype\":[\"tech\"],\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":2001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":3001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"ucat\":[\"new\"],\"search\":[\"iphone\"],\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", - "responsebody": "{\"id\":\"bidResponseId1\",\"seatbid\":[{\"bid\":[{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]}}}],\"seat\":\"seatId1\",\"group\":0}]}", "requestheaders": { "Accept": [ "application/json" @@ -420,12 +418,12 @@ "application/json;charset=utf-8" ] }, + "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId1\",\"video\":{\"mimes\":[\"mimes\"],\"minduration\":20,\"maxduration\":60,\"protocols\":[1],\"w\":300,\"h\":250,\"startdelay\":5,\"skipmin\":0,\"skipafter\":0,\"playbackmethod\":[1],\"ext\":{\"skip\":5,\"skipdelay\":1,\"rp\":{\"size_id\":15},\"videotype\":\"rewarded\"}},\"ext\":{\"rp\":{\"zone_id\":4001,\"target\":{\"rating\":[\"5-star\"],\"prodtype\":[\"tech\"],\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":2001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":3001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"ucat\":[\"new\"],\"search\":[\"iphone\"],\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", + "responsebody": "{\"id\":\"bidResponseId1\",\"seatbid\":[{\"bid\":[{\"id\":\"880290288\",\"impid\":\"impId1\",\"price\":8.43,\"adm\":\"\",\"crid\":\"crid1\",\"w\":300,\"h\":250,\"ext\":{\"rp\":{\"targeting\":[{\"key\":\"rpfl_1001\",\"values\":[\"2_tier0100\"]}]}}}],\"seat\":\"seatId1\",\"group\":0}]}", "status": 200 }, { "uri": "{{ rubicon.exchange_uri }}?tk_xint=dmbjs", - "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId2\",\"banner\":{\"format\":[{\"w\":300,\"h\":600}],\"w\":300,\"h\":600,\"ext\":{\"rp\":{\"size_id\":10,\"mime\":\"text/html\"}}},\"ext\":{\"rp\":{\"zone_id\":7001,\"target\":{\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":5001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":6001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", - "responsebody": "{\"id\":\"bidResponseId2\",\"seatbid\":[{\"bid\":[{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600}],\"seat\":\"seatId2\",\"group\":0}]}", "requestheaders": { "Accept": [ "application/json" @@ -443,6 +441,8 @@ "application/json;charset=utf-8" ] }, + "requestbody": "{\"id\":\"tid\",\"imp\":[{\"id\":\"impId2\",\"banner\":{\"format\":[{\"w\":300,\"h\":600}],\"w\":300,\"h\":600,\"ext\":{\"rp\":{\"size_id\":10,\"mime\":\"text/html\"}}},\"ext\":{\"rp\":{\"zone_id\":7001,\"target\":{\"page\":[\"http://www.example.com\"]},\"track\":{\"mint\":\"\",\"mint_version\":\"\"}},\"maxbids\":1}}],\"site\":{\"domain\":\"www.example.com\",\"page\":\"http://www.example.com\",\"publisher\":{\"ext\":{\"rp\":{\"account_id\":5001}}},\"ext\":{\"amp\":0,\"rp\":{\"site_id\":6001}}},\"device\":{\"ua\":\"userAgent\",\"dnt\":2,\"ip\":\"80.215.195.0\",\"pxratio\":4.2,\"language\":\"en\",\"ifa\":\"ifaId\",\"ext\":{\"rp\":{\"pixelratio\":4.2}}},\"user\":{\"buyeruid\":\"J5VLCWQP-26-CWFT\",\"data\":[{\"segment\":[{\"id\":\"segmentId1\"},{\"id\":\"segmentId2\"}],\"ext\":{\"segtax\":4}}],\"ext\":{\"consent\":\"CPBCa-mPBCa-mAAAAAENA0CAAEAAAAAAACiQAaQAwAAgAgABoAAAAAA\",\"eids\":[{\"source\":\"adserver.org\",\"uids\":[{\"id\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\",\"ext\":{\"rtiPartner\":\"TDID\"}}]},{\"source\":\"liveintent.com\",\"uids\":[{\"id\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"ext\":{\"segments\":[\"999\",\"888\"]}},{\"source\":\"pubcid\",\"id\":\"29cfaea8-a429-48fc-9537-8a19a8eb4f0d\"}],\"tpid\":[{\"source\":\"tdid\",\"uid\":\"cd96870f-f53d-4986-a08e-cd1612fb13b0\"},{\"source\":\"liveintent.com\",\"uid\":\"efcf3a33-2eaf-4d6b-bf11-a411f134278c\"}],\"rp\":{\"target\":{\"LIseg\":[\"999\",\"888\"],\"iab\":[\"segmentId1\",\"segmentId2\"]}}}},\"at\":1,\"tmax\":5000,\"source\":{\"fd\":1,\"tid\":\"tid\",\"ext\":{\"schain\":{\"ver\":\"1.0\",\"complete\":1,\"nodes\":[{\"asi\":\"superads.com\",\"sid\":\"123\",\"hp\":1}]}}},\"regs\":{\"ext\":{\"us_privacy\":\"1YNN\"}}}", + "responsebody": "{\"id\":\"bidResponseId2\",\"seatbid\":[{\"bid\":[{\"id\":\"466223845\",\"impid\":\"impId2\",\"price\":4.26,\"adm\":\"adm2\",\"crid\":\"crid2\",\"w\":300,\"h\":600}],\"seat\":\"seatId2\",\"group\":0}]}", "status": 200 } ]