Skip to content

Commit dedd923

Browse files
authored
ORTB-Blocking Module: Add new configuration options (#3480)
1 parent 2dfd97a commit dedd923

26 files changed

Lines changed: 1090 additions & 177 deletions

File tree

extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/AccountConfigReader.java

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ResponseBlockingConfig;
1919
import org.prebid.server.hooks.modules.ortb2.blocking.core.model.Result;
2020
import org.prebid.server.hooks.modules.ortb2.blocking.core.util.MergeUtils;
21+
import org.prebid.server.spring.config.bidder.model.MediaType;
2122
import org.prebid.server.util.ObjectUtil;
2223
import org.prebid.server.util.StreamUtil;
2324

@@ -51,7 +52,11 @@ public class AccountConfigReader {
5152
private static final String ALLOWED_APP_FOR_DEALS_FIELD = "allowed-app-for-deals";
5253
private static final String BLOCKED_BANNER_TYPE_FIELD = "blocked-banner-type";
5354
private static final String BLOCKED_BANNER_ATTR_FIELD = "blocked-banner-attr";
55+
private static final String BLOCKED_VIDEO_ATTR_FIELD = "blocked-video-attr";
56+
private static final String BLOCKED_AUDIO_ATTR_FIELD = "blocked-audio-attr";
5457
private static final String ALLOWED_BANNER_ATTR_FOR_DEALS = "allowed-banner-attr-for-deals";
58+
private static final String ALLOWED_VIDEO_ATTR_FOR_DEALS = "allowed-video-attr-for-deals";
59+
private static final String ALLOWED_AUDIO_ATTR_FOR_DEALS = "allowed-audio-attr-for-deals";
5560
private static final String ACTION_OVERRIDES_FIELD = "action-overrides";
5661
private static final String OVERRIDE_FIELD = "override";
5762
private static final String CONDITIONS_FIELD = "conditions";
@@ -100,8 +105,14 @@ public Result<BlockedAttributes> blockedAttributesFor(BidRequest bidRequest) {
100105
blockedAttribute(BAPP_FIELD, String.class, BLOCKED_APP_FIELD, requestMediaTypes);
101106
final Result<Map<String, List<Integer>>> btype =
102107
blockedAttributesForImps(BTYPE_FIELD, Integer.class, BLOCKED_BANNER_TYPE_FIELD, bidRequest);
103-
final Result<Map<String, List<Integer>>> battr =
108+
final Result<Map<String, List<Integer>>> bannerBattr =
104109
blockedAttributesForImps(BATTR_FIELD, Integer.class, BLOCKED_BANNER_ATTR_FIELD, bidRequest);
110+
final Result<Map<String, List<Integer>>> videoBattr =
111+
blockedAttributesForImps(BATTR_FIELD, Integer.class, BLOCKED_VIDEO_ATTR_FIELD, bidRequest);
112+
final Result<Map<String, List<Integer>>> audioBattr =
113+
blockedAttributesForImps(BATTR_FIELD, Integer.class, BLOCKED_AUDIO_ATTR_FIELD, bidRequest);
114+
final Result<Map<MediaType, Map<String, List<Integer>>>> battr =
115+
mergeBlockedAttributes(bannerBattr, videoBattr, audioBattr);
105116

106117
return Result.of(
107118
toBlockedAttributes(badv, bcat, cattaxComplement, bapp, btype, battr),
@@ -133,22 +144,39 @@ public Result<ResponseBlockingConfig> responseBlockingConfigFor(BidderBid bidder
133144
ALLOWED_APP_FOR_DEALS_FIELD,
134145
bidMediaTypes,
135146
dealid);
136-
final Result<BidAttributeBlockingConfig<Integer>> battr = blockingConfigForAttribute(
147+
final Result<BidAttributeBlockingConfig<Integer>> bannerBattr = blockingConfigForAttribute(
137148
BATTR_FIELD,
138149
Integer.class,
139150
ALLOWED_BANNER_ATTR_FOR_DEALS,
140151
bidMediaTypes,
141152
dealid);
153+
final Result<BidAttributeBlockingConfig<Integer>> videoBattr = blockingConfigForAttribute(
154+
BATTR_FIELD,
155+
Integer.class,
156+
ALLOWED_VIDEO_ATTR_FOR_DEALS,
157+
bidMediaTypes,
158+
dealid);
159+
final Result<BidAttributeBlockingConfig<Integer>> audioBattr = blockingConfigForAttribute(
160+
BATTR_FIELD,
161+
Integer.class,
162+
ALLOWED_AUDIO_ATTR_FOR_DEALS,
163+
bidMediaTypes,
164+
dealid);
165+
final Map<MediaType, BidAttributeBlockingConfig<Integer>> battr = new HashMap<>();
166+
battr.put(MediaType.BANNER, bannerBattr.getValue());
167+
battr.put(MediaType.VIDEO, videoBattr.getValue());
168+
battr.put(MediaType.AUDIO, audioBattr.getValue());
142169

143170
final ResponseBlockingConfig response = ResponseBlockingConfig.builder()
144171
.badv(badv.getValue())
145172
.bcat(bcat.getValue())
146173
.cattax(cattax.getValue())
147174
.bapp(bapp.getValue())
148-
.battr(battr.getValue())
175+
.battr(battr)
149176
.build();
150177

151-
final List<String> warnings = MergeUtils.mergeMessages(badv, bcat, cattax, bapp, battr);
178+
final List<String> warnings = MergeUtils.mergeMessages(
179+
badv, bcat, cattax, bapp, bannerBattr, videoBattr, audioBattr);
152180

153181
return Result.of(response, warnings);
154182
}
@@ -218,6 +246,28 @@ private <T> Result<Map<String, List<T>>> blockedAttributesForImps(String attribu
218246
MergeUtils.mergeMessages(results));
219247
}
220248

249+
private static Result<Map<MediaType, Map<String, List<Integer>>>> mergeBlockedAttributes(
250+
Result<Map<String, List<Integer>>> bannerBattr,
251+
Result<Map<String, List<Integer>>> videoBattr,
252+
Result<Map<String, List<Integer>>> audioBattr) {
253+
254+
final Map<MediaType, Map<String, List<Integer>>> battr = new HashMap<>();
255+
256+
if (bannerBattr.hasValue()) {
257+
battr.put(MediaType.BANNER, bannerBattr.getValue());
258+
}
259+
if (videoBattr.hasValue()) {
260+
battr.put(MediaType.VIDEO, videoBattr.getValue());
261+
}
262+
if (audioBattr.hasValue()) {
263+
battr.put(MediaType.AUDIO, audioBattr.getValue());
264+
}
265+
266+
return Result.of(
267+
!battr.isEmpty() ? battr : null,
268+
MergeUtils.mergeMessages(bannerBattr, videoBattr, audioBattr));
269+
}
270+
221271
private <T> Result<BidAttributeBlockingConfig<T>> blockingConfigForAttribute(String attribute,
222272
Class<T> attributeType,
223273
String blockUnknownField,
@@ -360,8 +410,8 @@ private Result<JsonNode> toResult(List<JsonNode> specificBidderResults,
360410
Set<String> actualMediaTypes) {
361411

362412
final JsonNode value = ObjectUtils.firstNonNull(
363-
specificBidderResults.size() > 0 ? specificBidderResults.get(0) : null,
364-
catchAllBidderResults.size() > 0 ? catchAllBidderResults.get(0) : null);
413+
!specificBidderResults.isEmpty() ? specificBidderResults.getFirst() : null,
414+
!catchAllBidderResults.isEmpty() ? catchAllBidderResults.getFirst() : null);
365415
final List<String> warnings = debugEnabled && specificBidderResults.size() + catchAllBidderResults.size() > 1
366416
? Collections.singletonList(
367417
"More than one conditions matches request. Bidder: %s, request media types: %s"
@@ -376,7 +426,7 @@ private static BlockedAttributes toBlockedAttributes(Result<List<String>> badv,
376426
Result<Integer> cattaxComplement,
377427
Result<List<String>> bapp,
378428
Result<Map<String, List<Integer>>> btype,
379-
Result<Map<String, List<Integer>>> battr) {
429+
Result<Map<MediaType, Map<String, List<Integer>>>> battr) {
380430

381431
return badv.hasValue()
382432
|| bcat.hasValue()

extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/BidsBlocker.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import org.prebid.server.hooks.modules.ortb2.blocking.core.model.ResponseBlockingConfig;
1919
import org.prebid.server.hooks.modules.ortb2.blocking.core.model.Result;
2020
import org.prebid.server.hooks.modules.ortb2.blocking.core.util.MergeUtils;
21+
import org.prebid.server.proto.openrtb.ext.response.BidType;
22+
import org.prebid.server.spring.config.bidder.model.MediaType;
2123

2224
import java.util.ArrayList;
2325
import java.util.Collections;
@@ -91,7 +93,6 @@ public ExecutionResult<BlockedBids> block() {
9193

9294
try {
9395
final List<Result<BlockingResult>> blockedBidResults = bids.stream()
94-
.sequential()
9596
.map(bid -> isBlocked(bid, accountConfigReader))
9697
.toList();
9798

@@ -170,11 +171,30 @@ private AttributeCheckResult<String> checkBapp(BidderBid bidderBid, ResponseBloc
170171
}
171172

172173
private AttributeCheckResult<Integer> checkBattr(BidderBid bidderBid, ResponseBlockingConfig blockingConfig) {
173-
174+
final MediaType mediaType = mapBidTypeToMediaType(bidderBid.getType());
174175
return checkAttribute(
175176
bidderBid.getBid().getAttr(),
176-
blockingConfig.getBattr(),
177-
blockedAttributeValues(BlockedAttributes::getBattr, bidderBid.getBid().getImpid()));
177+
blockingConfig.getBattr().get(mediaType),
178+
blockedAttributeValues(
179+
blockedAttributes -> extractBattrForMediaType(blockedAttributes, mediaType),
180+
bidderBid.getBid().getImpid()));
181+
}
182+
183+
private static MediaType mapBidTypeToMediaType(BidType bidType) {
184+
return switch (bidType) {
185+
case banner -> MediaType.BANNER;
186+
case video -> MediaType.VIDEO;
187+
case audio -> MediaType.AUDIO;
188+
case xNative -> MediaType.NATIVE;
189+
case null -> null;
190+
};
191+
}
192+
193+
private static Map<String, List<Integer>> extractBattrForMediaType(BlockedAttributes blockedAttributes,
194+
MediaType mediaType) {
195+
196+
final Map<MediaType, Map<String, List<Integer>>> battr = blockedAttributes.getBattr();
197+
return battr != null ? battr.get(mediaType) : null;
178198
}
179199

180200
private <T> AttributeCheckResult<T> checkAttribute(List<T> attribute,

extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/RequestUpdater.java

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package org.prebid.server.hooks.modules.ortb2.blocking.core;
22

3+
import com.iab.openrtb.request.Audio;
34
import com.iab.openrtb.request.Banner;
45
import com.iab.openrtb.request.BidRequest;
56
import com.iab.openrtb.request.Imp;
7+
import com.iab.openrtb.request.Video;
68
import org.apache.commons.collections4.CollectionUtils;
79
import org.apache.commons.collections4.MapUtils;
810
import org.prebid.server.hooks.modules.ortb2.blocking.core.model.BlockedAttributes;
11+
import org.prebid.server.spring.config.bidder.model.MediaType;
912

1013
import java.util.List;
1114
import java.util.Map;
1215
import java.util.Objects;
16+
import java.util.Optional;
1317

1418
public class RequestUpdater {
1519

@@ -40,39 +44,93 @@ public BidRequest update(BidRequest bidRequest) {
4044

4145
private List<Imp> updateImps(List<Imp> imps) {
4246
final Map<String, List<Integer>> blockedBannerType = blockedAttributes.getBtype();
43-
final Map<String, List<Integer>> blockedBannerAttr = blockedAttributes.getBattr();
47+
final Map<MediaType, Map<String, List<Integer>>> blockedAttr = blockedAttributes.getBattr();
4448

45-
if (MapUtils.isEmpty(blockedBannerType) && MapUtils.isEmpty(blockedBannerAttr)) {
49+
if (MapUtils.isEmpty(blockedBannerType) && MapUtils.isEmpty(blockedAttr)) {
4650
return imps;
4751
}
4852

4953
return imps.stream()
50-
.map(imp -> updateImp(imp, blockedBannerType, blockedBannerAttr))
54+
.map(imp -> updateImp(imp, blockedBannerType, blockedAttr))
5155
.toList();
5256
}
5357

5458
private Imp updateImp(Imp imp,
5559
Map<String, List<Integer>> blockedBannerType,
56-
Map<String, List<Integer>> blockedBannerAttr) {
60+
Map<MediaType, Map<String, List<Integer>>> blockedAttr) {
5761

5862
final String impId = imp.getId();
5963
final List<Integer> btypeForImp = blockedBannerType != null ? blockedBannerType.get(impId) : null;
60-
final List<Integer> battrForImp = blockedBannerAttr != null ? blockedBannerAttr.get(impId) : null;
64+
final List<Integer> bannerBattrForImp = extractBattr(blockedAttr, MediaType.BANNER, impId);
65+
final List<Integer> videoBattrForImp = extractBattr(blockedAttr, MediaType.VIDEO, impId);
66+
final List<Integer> audioBattrForImp = extractBattr(blockedAttr, MediaType.AUDIO, impId);
67+
68+
if (CollectionUtils.isEmpty(btypeForImp)
69+
&& CollectionUtils.isEmpty(bannerBattrForImp)
70+
&& CollectionUtils.isEmpty(videoBattrForImp)
71+
&& CollectionUtils.isEmpty(audioBattrForImp)) {
6172

62-
if (CollectionUtils.isEmpty(btypeForImp) && CollectionUtils.isEmpty(battrForImp)) {
6373
return imp;
6474
}
6575

6676
final Banner banner = imp.getBanner();
67-
final List<Integer> existingBtype = banner != null ? banner.getBtype() : null;
68-
final List<Integer> existingBattr = banner != null ? banner.getBattr() : null;
69-
final Banner.BannerBuilder bannerBuilder = banner != null ? banner.toBuilder() : Banner.builder();
77+
final Video video = imp.getVideo();
78+
final Audio audio = imp.getAudio();
7079

7180
return imp.toBuilder()
72-
.banner(bannerBuilder
73-
.btype(CollectionUtils.isNotEmpty(existingBtype) ? existingBtype : btypeForImp)
74-
.battr(CollectionUtils.isNotEmpty(existingBattr) ? existingBattr : battrForImp)
75-
.build())
81+
.banner(CollectionUtils.isNotEmpty(btypeForImp) || CollectionUtils.isNotEmpty(bannerBattrForImp)
82+
? updateBanner(banner, btypeForImp, bannerBattrForImp)
83+
: banner)
84+
.video(CollectionUtils.isNotEmpty(videoBattrForImp)
85+
? updateVideo(imp.getVideo(), videoBattrForImp)
86+
: video)
87+
.audio(CollectionUtils.isNotEmpty(audioBattrForImp)
88+
? updateAudio(imp.getAudio(), audioBattrForImp)
89+
: audio)
7690
.build();
7791
}
92+
93+
private static List<Integer> extractBattr(Map<MediaType, Map<String, List<Integer>>> blockedAttr,
94+
MediaType mediaType,
95+
String impId) {
96+
97+
final Map<String, List<Integer>> impIdToBattr = blockedAttr != null ? blockedAttr.get(mediaType) : null;
98+
return impIdToBattr != null ? impIdToBattr.get(impId) : null;
99+
}
100+
101+
private static Banner updateBanner(Banner banner, List<Integer> btype, List<Integer> battr) {
102+
final List<Integer> existingBtype = banner != null ? banner.getBtype() : null;
103+
final List<Integer> existingBattr = banner != null ? banner.getBattr() : null;
104+
105+
return CollectionUtils.isEmpty(existingBtype) || CollectionUtils.isEmpty(existingBattr)
106+
? Optional.ofNullable(banner)
107+
.map(Banner::toBuilder)
108+
.orElseGet(Banner::builder)
109+
.btype(CollectionUtils.isNotEmpty(existingBtype) ? existingBtype : btype)
110+
.battr(CollectionUtils.isNotEmpty(existingBattr) ? existingBattr : battr)
111+
.build()
112+
: banner;
113+
}
114+
115+
private static Video updateVideo(Video video, List<Integer> battr) {
116+
final List<Integer> existingBattr = video != null ? video.getBattr() : null;
117+
return CollectionUtils.isEmpty(existingBattr)
118+
? Optional.ofNullable(video)
119+
.map(Video::toBuilder)
120+
.orElseGet(Video::builder)
121+
.battr(battr)
122+
.build()
123+
: video;
124+
}
125+
126+
private static Audio updateAudio(Audio audio, List<Integer> battr) {
127+
final List<Integer> existingBattr = audio != null ? audio.getBattr() : null;
128+
return CollectionUtils.isEmpty(existingBattr)
129+
? Optional.ofNullable(audio)
130+
.map(Audio::toBuilder)
131+
.orElseGet(Audio::builder)
132+
.battr(battr)
133+
.build()
134+
: audio;
135+
}
78136
}

extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/BlockedAttributes.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import lombok.Builder;
44
import lombok.Value;
5+
import org.prebid.server.spring.config.bidder.model.MediaType;
56

67
import java.util.List;
78
import java.util.Map;
@@ -20,5 +21,5 @@ public class BlockedAttributes {
2021

2122
Map<String, List<Integer>> btype;
2223

23-
Map<String, List<Integer>> battr;
24+
Map<MediaType, Map<String, List<Integer>>> battr;
2425
}

extra/modules/ortb2-blocking/src/main/java/org/prebid/server/hooks/modules/ortb2/blocking/core/model/ResponseBlockingConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import lombok.Builder;
44
import lombok.Value;
5+
import org.prebid.server.spring.config.bidder.model.MediaType;
6+
7+
import java.util.Map;
58

69
@Builder
710
@Value
@@ -15,5 +18,5 @@ public class ResponseBlockingConfig {
1518

1619
BidAttributeBlockingConfig<String> bapp;
1720

18-
BidAttributeBlockingConfig<Integer> battr;
21+
Map<MediaType, BidAttributeBlockingConfig<Integer>> battr;
1922
}

0 commit comments

Comments
 (0)