diff --git a/src/main/java/com/iab/openrtb/request/Audio.java b/src/main/java/com/iab/openrtb/request/Audio.java index 58901a625b3..3f1fccce76b 100644 --- a/src/main/java/com/iab/openrtb/request/Audio.java +++ b/src/main/java/com/iab/openrtb/request/Audio.java @@ -81,7 +81,7 @@ public class Audio { * within a bid request share the same podid, this indicates that * those impression opportunities belong to the same audio ad pod. */ - Integer podid; + String podid; /** * The sequence (position) of the audio ad pod within a diff --git a/src/main/java/com/iab/openrtb/request/Banner.java b/src/main/java/com/iab/openrtb/request/Banner.java index b24584b110b..3f34ab3ea21 100644 --- a/src/main/java/com/iab/openrtb/request/Banner.java +++ b/src/main/java/com/iab/openrtb/request/Banner.java @@ -44,6 +44,30 @@ public class Banner { */ Integer h; + /** + * Maximum width in device independent pixels (DIPS), retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of format. + */ + Integer wmax; + + /** + * Maximum height in device independent pixels (DIPS), retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of format. + */ + Integer hmax; + + /** + * Minimum width in device independent pixels (DIPS), retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of format. + */ + Integer wmin; + + /** + * Minimum height in device independent pixels (DIPS), retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of format. + */ + Integer hmin; + /** * Blocked banner ad types. * Values: diff --git a/src/main/java/com/iab/openrtb/request/Content.java b/src/main/java/com/iab/openrtb/request/Content.java index 486630d8eed..0419512c7a8 100644 --- a/src/main/java/com/iab/openrtb/request/Content.java +++ b/src/main/java/com/iab/openrtb/request/Content.java @@ -64,6 +64,16 @@ public class Content { */ String genre; + /** + * Taxonomy used by genres. If omitted, Content Category Taxonomy 3.1 (9) is assumed. + */ + Integer gtax; + + /** + * Genre IDs from the taxonomy specified by gtax. + */ + List genres; + /** * Album to which the content belongs; typically for audio. */ @@ -103,6 +113,12 @@ public class Content { */ Integer prodq; + /** + * Video production quality retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of prodq. + */ + Integer videoquality; + /** * Type of content (game, video, text, etc.). Refer to * List: Content Contexts in AdCOM 1.0. @@ -136,7 +152,7 @@ public class Content { List kwarray; /** - * 0 = not live, 1 = content is live (e.g., stream, live blog). + * Indicates whether the broadcast is scheduled: 0 = on-demand, 1 = scheduled (linear viewing). */ Integer livestream; @@ -182,6 +198,16 @@ public class Content { */ Channel channel; + /** + * Indicates whether the event is happening in real time: 0 = replay, 1 = real time. + */ + Integer realtime; + + /** + * Indicates whether this is the first broadcast of the content: 0 = no, 1 = yes. + */ + Integer firstbroadcast; + /** * Placeholder for exchange-specific extensions to OpenRTB. */ diff --git a/src/main/java/com/iab/openrtb/request/Data.java b/src/main/java/com/iab/openrtb/request/Data.java index fd48b7100b8..49a1ee7b7a7 100644 --- a/src/main/java/com/iab/openrtb/request/Data.java +++ b/src/main/java/com/iab/openrtb/request/Data.java @@ -28,6 +28,11 @@ public class Data { */ String name; + /** + * Extended video or audio content IDs from the source specified by name. + */ + List cids; + /** * Array of {@link Segment} (Section 3.2.22) objects that contain the actual data * values. diff --git a/src/main/java/com/iab/openrtb/request/Video.java b/src/main/java/com/iab/openrtb/request/Video.java index 369d576a3ac..b476ee4c8fb 100644 --- a/src/main/java/com/iab/openrtb/request/Video.java +++ b/src/main/java/com/iab/openrtb/request/Video.java @@ -74,6 +74,12 @@ public class Video { */ List protocols; + /** + * Video protocol retained for OpenRTB 2.5 round trips. + * Deprecated as of OpenRTB 2.5 and removed in 2.6 in favor of protocols. + */ + Integer protocol; + /** * Width of the video player in device independent pixels (DIPS). */ @@ -90,7 +96,7 @@ public class Video { * within a bid request share the same podid, this indicates that * those impression opportunities belong to the same video ad pod. */ - Integer podid; + String podid; /** * The sequence (position) of the video ad pod within a diff --git a/src/main/java/org/prebid/server/protobuf/request/ProtobufRequestUtils.java b/src/main/java/org/prebid/server/protobuf/request/ProtobufRequestUtils.java index b8d0a9ddebe..ff6ba262211 100644 --- a/src/main/java/org/prebid/server/protobuf/request/ProtobufRequestUtils.java +++ b/src/main/java/org/prebid/server/protobuf/request/ProtobufRequestUtils.java @@ -263,6 +263,10 @@ public static ProtobufMapper ProtobufMapper ProtobufMapper protocols Integer startdelay List rqddurs - Integer podid + String podid Integer podseq Integer sequence Integer slotinpod diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Content.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Content.groovy index 7b49458a5fc..8e8f8b26c97 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Content.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Content.groovy @@ -15,6 +15,8 @@ class Content { String season String artist String genre + Integer gtax + List genres String album String isrc Producer producer @@ -29,6 +31,8 @@ class Content { String keywords List kwarray Integer livestream + Integer realtime + Integer firstbroadcast Integer sourcerelationship Integer len String language diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Data.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Data.groovy index 894ba61e4cf..9731712864e 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Data.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Data.groovy @@ -10,6 +10,7 @@ class Data { String id String name + List cids List segment ExtData ext diff --git a/src/test/groovy/org/prebid/server/functional/model/request/auction/Video.groovy b/src/test/groovy/org/prebid/server/functional/model/request/auction/Video.groovy index 53e86c5ed28..e71191dc113 100644 --- a/src/test/groovy/org/prebid/server/functional/model/request/auction/Video.groovy +++ b/src/test/groovy/org/prebid/server/functional/model/request/auction/Video.groovy @@ -19,7 +19,7 @@ class Video { Integer width @JsonProperty("h") Integer height - Integer podid + String podid Integer podseq List rqddurs VideoPlacementSubtypes placement diff --git a/src/test/groovy/org/prebid/server/functional/tests/OrtbConverterSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/OrtbConverterSpec.groovy index 21bb80df135..1615d173965 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/OrtbConverterSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/OrtbConverterSpec.groovy @@ -4,6 +4,7 @@ import org.prebid.server.functional.model.db.StoredRequest import org.prebid.server.functional.model.request.auction.Audio import org.prebid.server.functional.model.request.auction.BidRequest import org.prebid.server.functional.model.request.auction.Content +import org.prebid.server.functional.model.request.auction.Data import org.prebid.server.functional.model.request.auction.Device import org.prebid.server.functional.model.request.auction.Dooh import org.prebid.server.functional.model.request.auction.DoohExt @@ -32,6 +33,7 @@ import spock.lang.Shared import static org.prebid.server.functional.model.request.auction.Content.Channel import static org.prebid.server.functional.model.request.auction.DistributionChannel.APP import static org.prebid.server.functional.model.request.auction.DistributionChannel.DOOH +import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE class OrtbConverterSpec extends BaseSpec { @@ -556,7 +558,7 @@ class OrtbConverterSpec extends BaseSpec { rqddurs = [PBSUtils.randomNumber] maxseq = PBSUtils.randomNumber poddur = PBSUtils.randomNumber - podid = PBSUtils.randomNumber + podid = PBSUtils.randomString podseq = PBSUtils.randomNumber mincpmpersec = PBSUtils.randomDecimal slotinpod = PBSUtils.randomNumber @@ -580,7 +582,7 @@ class OrtbConverterSpec extends BaseSpec { rqddurs = [PBSUtils.randomNumber] maxseq = PBSUtils.randomNumber poddur = PBSUtils.randomNumber - podid = PBSUtils.randomNumber + podid = PBSUtils.randomString podseq = PBSUtils.randomNumber mincpmpersec = PBSUtils.randomDecimal slotinpod = PBSUtils.randomNumber @@ -604,7 +606,7 @@ class OrtbConverterSpec extends BaseSpec { rqddurs = [PBSUtils.randomNumber] maxseq = PBSUtils.randomNumber poddur = PBSUtils.randomNumber - podid = PBSUtils.randomNumber + podid = PBSUtils.randomString podseq = PBSUtils.randomNumber mincpmpersec = PBSUtils.randomDecimal slotinpod = PBSUtils.randomNumber @@ -626,7 +628,7 @@ class OrtbConverterSpec extends BaseSpec { rqddurs = [PBSUtils.randomNumber] maxseq = PBSUtils.randomNumber poddur = PBSUtils.randomNumber - podid = PBSUtils.randomNumber + podid = PBSUtils.randomString podseq = PBSUtils.randomNumber mincpmpersec = BigDecimal.valueOf(1) slotinpod = PBSUtils.randomNumber @@ -671,6 +673,43 @@ class OrtbConverterSpec extends BaseSpec { assert bidderRequest.imp[0].ssai == ssaiRandomNumber } + def "PBS should preserve content metadata for #distributionChannel when bidder supports ortb #ortbVersion"() { + given: "Content with genre taxonomy, broadcast flags and extended content identifiers" + def content = Content.defaultContent.tap { + gtax = 1 + genres = ["genre-001", "genre-002"] + realtime = realtimeFlag + firstbroadcast = firstbroadcastFlag + data = [new Data(id: "provider-id", cids: ["content-001", "00042"])] + } + def bidRequest = BidRequest.getDefaultBidRequest(distributionChannel).tap { + it[distributionChannel.value].content = content + } + def service = ortbVersion == "2.5" ? prebidServerServiceWithElderOrtb : prebidServerServiceWithNewOrtb + + when: "Requesting a PBS auction" + service.sendAuctionRequest(bidRequest) + + then: "The bidder receives the content metadata unchanged" + def actualContent = bidder.getBidderRequest(bidRequest.id)[distributionChannel.value].content + verifyAll(actualContent) { + gtax == content.gtax + genres == content.genres + realtime == realtimeFlag + firstbroadcast == firstbroadcastFlag + data == content.data + } + + where: + distributionChannel | ortbVersion | realtimeFlag | firstbroadcastFlag + SITE | "2.5" | 0 | 1 + SITE | "2.6" | 1 | 0 + APP | "2.5" | 1 | 0 + APP | "2.6" | 0 | 1 + DOOH | "2.5" | 0 | 1 + DOOH | "2.6" | 1 | 0 + } + def "PBS shouldn't remove site.content.{channel, network} when bidder doesn't support ortb 2.6"() { given: "Default bid request with site.content.{network, channel}" def defaultChannel = Channel.defaultChannel diff --git a/src/test/java/org/prebid/server/protobuf/request/ProtobufRequestUtilsTest.java b/src/test/java/org/prebid/server/protobuf/request/ProtobufRequestUtilsTest.java index 29e092f73c8..8901b7d918f 100644 --- a/src/test/java/org/prebid/server/protobuf/request/ProtobufRequestUtilsTest.java +++ b/src/test/java/org/prebid/server/protobuf/request/ProtobufRequestUtilsTest.java @@ -361,6 +361,21 @@ public void bannerMapperShouldReturnValidMapper() { assertThat(result).isEqualTo(expectedResult); } + @Test + public void bannerMapperShouldLeaveMissingLegacyDimensionsUnset() { + // given + final Banner banner = givenBanner().toBuilder().wmax(null).hmax(null).wmin(null).hmin(null).build(); + final ProtobufMapper mapper = + ProtobufRequestUtils.bannerMapper(formatMapper, givenJsonExtensionMapper(OpenRtbTest.banner)); + + // when + final OpenRtb.BidRequest.Imp.Banner result = mapper.map(banner); + + // then + assertThat(result).isEqualTo(givenProtobufBanner().toBuilder() + .clearWmax().clearHmax().clearWmin().clearHmin().build()); + } + @Test public void nativeImageMapperShouldReturnValidMapper() { // when @@ -410,6 +425,20 @@ public void contentMapperShouldReturnValidMapper() { assertThat(result).isEqualTo(expectedResult); } + @Test + public void contentMapperShouldLeaveMissingVideoqualityUnset() { + // given + final Content content = givenContent().toBuilder().videoquality(null).build(); + final ProtobufMapper mapper = ProtobufRequestUtils.contentMapper( + producerMapper, dataMapper, givenJsonExtensionMapper(OpenRtbTest.content)); + + // when + final OpenRtb.BidRequest.Content result = mapper.map(content); + + // then + assertThat(result).isEqualTo(givenProtobufContent().toBuilder().clearVideoquality().build()); + } + @Test public void deviceMapperShouldReturnValidMapper() { // given @@ -811,6 +840,20 @@ public void videoMapperShouldReturnValidMapper() { assertThat(result).isEqualTo(expectedResult); } + @Test + public void videoMapperShouldLeaveMissingProtocolUnset() { + // given + final Video video = givenVideo().toBuilder().protocol(null).build(); + final ProtobufMapper mapper = + ProtobufRequestUtils.videoMapper(bannerMapper, givenJsonExtensionMapper(OpenRtbTest.video)); + + // when + final OpenRtb.BidRequest.Imp.Video result = mapper.map(video); + + // then + assertThat(result).isEqualTo(givenProtobufVideo().toBuilder().clearProtocol().build()); + } + @Test public void userMapperShouldReturnValidMapper() { // given @@ -1158,6 +1201,7 @@ private static Video givenVideo() { .minduration(1) .maxduration(2) .startdelay(3) + .protocol(2) .protocols(singletonList(4)) .w(5) .h(6) @@ -1189,6 +1233,7 @@ private static OpenRtb.BidRequest.Imp.Video givenProtobufVideo() { .setMinduration(1) .setMaxduration(2) .setStartdelay(3) + .setProtocol(2) .addProtocols(4) .setW(5) .setH(6) @@ -1343,6 +1388,10 @@ private static Banner givenBanner() { .format(singletonList(givenFormat())) .w(1) .h(2) + .wmax(640) + .hmax(480) + .wmin(160) + .hmin(120) .btype(singletonList(3)) .battr(singletonList(4)) .pos(5) @@ -1360,6 +1409,10 @@ private static OpenRtb.BidRequest.Imp.Banner givenProtobufBanner() { .addAllFormat(singletonList(givenProtobufFormat())) .setW(1) .setH(2) + .setWmax(640) + .setHmax(480) + .setWmin(160) + .setHmin(120) .addBtype(3) .addBattr(4) .setPos(5) @@ -1620,6 +1673,7 @@ private static Content givenContent() { .url("url") .cat(singletonList("cat")) .prodq(2) + .videoquality(1) .context(3) .contentrating("contentrating") .userrating("userrating") @@ -1650,6 +1704,7 @@ private static OpenRtb.BidRequest.Content givenProtobufContent() { .setUrl("url") .addCat("cat") .setProdq(2) + .setVideoquality(1) .setContext(3) .setContentrating("contentrating") .setUserrating("userrating")