New Adapter: ReVantage#4477
Conversation
| if (feedId == null) { | ||
| throw new PreBidException("imp %s: missing required param feedId".formatted(imp.getId())); | ||
| } | ||
| final Imp rewrittenImp = rewriteImpExt(imp, feedId, ext); |
There was a problem hiding this comment.
rewriteImpExt -> updateImp, rewrittenImp -> updatedImp
| if (wrapper == null || wrapper.getBidder() == null) { | ||
| throw new PreBidException("imp %s: missing imp.ext.bidder".formatted(imp.getId())); | ||
| } |
There was a problem hiding this comment.
No need for this checks. At this stage, neither the wrapper nor the wrapper.getBidder() can be null
| final ObjectNode bidderNode = mapper.mapper().createObjectNode(); | ||
| if (StringUtils.isNotBlank(ext.getPlacementId())) { | ||
| bidderNode.put("placementId", ext.getPlacementId()); | ||
| } | ||
| if (StringUtils.isNotBlank(ext.getPublisherId())) { | ||
| bidderNode.put("publisherId", ext.getPublisherId()); | ||
| } | ||
|
|
||
| final ObjectNode rewritten = mapper.mapper().createObjectNode(); | ||
| rewritten.put("feedId", feedId); | ||
| rewritten.set("bidder", bidderNode); | ||
|
|
||
| return imp.toBuilder().ext(rewritten).build(); |
There was a problem hiding this comment.
final ObjectNode newExt = mapper.mapper().createObjectNode();
newExt.put("feedId", feedId);
final ObjectNode bidderNode = rewritten.putObject("bidder");
final String placementId = ext.getPlacementId();
if (StringUtils.isNotBlank(placementId)) {
bidderNode.put("placementId", placementId);
}
final String publisherId = ext.getPublisherId();
if (StringUtils.isNotBlank(publisherId)) {
bidderNode.put("publisherId", publisherId);
}
return imp.toBuilder().ext(newExt).build();
| return HttpRequest.<BidRequest>builder() | ||
| .method(HttpMethod.POST) | ||
| .uri(uri) | ||
| .headers(headers) | ||
| .body(mapper.encodeToBytes(request)) | ||
| .impIds(collectImpIds(request)) | ||
| .payload(request) | ||
| .build(); |
There was a problem hiding this comment.
Use BidderUtil.defaultRequest instead
|
|
||
| private static List<BidderBid> extractBids(BidResponse response, BidRequest request) { | ||
| if (response == null || CollectionUtils.isEmpty(response.getSeatbid())) { | ||
| return List.of(); |
There was a problem hiding this comment.
List.of -> Collections.emptyList
| private static BidType resolveMediaType(Bid bid, List<Imp> imps) { | ||
| if (bid.getMtype() != null) { | ||
| switch (bid.getMtype()) { | ||
| case 1: | ||
| return BidType.banner; | ||
| case 2: | ||
| return BidType.video; | ||
| default: | ||
| // fall through | ||
| } | ||
| } | ||
|
|
||
| final JsonNode ext = bid.getExt(); |
There was a problem hiding this comment.
Refactor this method:
private static BidType resolveBidType(Bid bid, List<Imp> imps) {
return bidTypeFromMtype(bid.getMtype())
.or(() -> bidTypeFromExt(bid.getExt()))
.or(() -> bidTypeFromAdm(bid.getAdm()))
.or(() -> bidTypeFromImp(bid.getImpid(), imps))
.orElseThrow(() -> new PreBidException(
"Cannot determine media type for bid %s on imp %s".formatted(bid.getId(), bid.getImpid())));
}
private static Optional<BidType> bidTypeFromMtype(Integer mType) {
return Optional.ofNullable(switch (mType) {
case 1 -> BidType.banner;
case 2 -> BidType.video;
case null, default -> null;
});
}
private static Optional<BidType> bidTypeFromExt(ObjectNode bidExt) {
return Optional.ofNullable(bidExt)
.map(ext -> ext.get("mediaType"))
.filter(JsonNode::isTextual)
.map(JsonNode::asText)
.map(String::toLowerCase)
.map(mediaType -> switch (mediaType) {
case "banner" -> BidType.banner;
case "video" -> BidType.video;
default -> null;
});
}
private static Optional<BidType> bidTypeFromAdm(String adm) {
if (StringUtils.isBlank(adm)) {
return Optional.empty();
}
final String trimmed = adm.trim().toUpperCase();
return trimmed.startsWith("<VAST") || trimmed.startsWith("<?XML")
? Optional.of(BidType.video)
: Optional.empty();
}
private static Optional<BidType> bidTypeFromImp(String impId, List<Imp> imps) {
for (Imp imp : imps) {
if (!Objects.equals(imp.getId(), impId)) {
continue;
}
final boolean hasBanner = imp.getBanner() != null;
final boolean hasVideo = imp.getVideo() != null;
if (hasVideo && !hasBanner) {
return Optional.of(BidType.video);
}
if (hasBanner) {
return Optional.of(BidType.banner);
}
break;
}
return Optional.empty();
}
|
|
||
| @Bean("revantageConfigurationProperties") | ||
| @ConfigurationProperties("adapters.revantage") | ||
| @Validated |
Removed detailed class-level documentation and some comments in the makeHttpRequests method.
| try { | ||
| final ExtImpRevantage ext = parseImpExt(imp); | ||
| final String feedId = StringUtils.trimToNull(ext.getFeedId()); | ||
| if (feedId == null) { | ||
| throw new PreBidException("imp %s: missing required param feedId".formatted(imp.getId())); | ||
| } | ||
| final Imp rewrittenImp = rewriteImpExt(imp, feedId, ext); | ||
| impsByFeed.computeIfAbsent(feedId, k -> new ArrayList<>()).add(rewrittenImp); | ||
| } catch (PreBidException e) { | ||
| errors.add(BidderError.badInput(e.getMessage())); | ||
| } | ||
| } |
There was a problem hiding this comment.
nitpick
I think we don't need to throw an exception here, we could just add to the errors list, when we don't have the feedId.
Something like
| try { | |
| final ExtImpRevantage ext = parseImpExt(imp); | |
| final String feedId = StringUtils.trimToNull(ext.getFeedId()); | |
| if (feedId == null) { | |
| throw new PreBidException("imp %s: missing required param feedId".formatted(imp.getId())); | |
| } | |
| final Imp rewrittenImp = rewriteImpExt(imp, feedId, ext); | |
| impsByFeed.computeIfAbsent(feedId, k -> new ArrayList<>()).add(rewrittenImp); | |
| } catch (PreBidException e) { | |
| errors.add(BidderError.badInput(e.getMessage())); | |
| } | |
| } | |
| final ExtImpRevantage ext = parseImpExt(imp); | |
| final String feedId = StringUtils.trimToNull(ext.getFeedId()); | |
| if (feedId == null) { | |
| errors.add(BidderError.badInput("imp %s: missing required param feedId".formatted(imp.getId()))); | |
| continue; | |
| } | |
| final Imp rewrittenImp = rewriteImpExt(imp, feedId, ext); | |
| impsByFeed.computeIfAbsent(feedId, k -> new ArrayList<>()).add(rewrittenImp); |
| public void makeBidsShouldReturnEmptyListOn204() throws Exception { | ||
| // given | ||
| final BidderCall<BidRequest> httpCall = givenHttpCall(204, null); | ||
|
|
||
| // when | ||
| final Result<List<BidderBid>> result = target.makeBids(httpCall, BidRequest.builder().build()); | ||
|
|
||
| // then | ||
| assertThat(result.getErrors()).isEmpty(); | ||
| assertThat(result.getValue()).isEmpty(); | ||
| } |
There was a problem hiding this comment.
As null is expected in the body, maybe it would make sense to first check if it's not null, since this test, doesn't seem to pass.
Also can the body of the response be null when makeBids is called? Would expect for it to be an empty string "".
@CTMBNara what do you think?
| } | ||
|
|
||
| @Test | ||
| public void makeBidsShouldDetectVideoFromVastWhenMtypeAbsent() throws Exception { |
There was a problem hiding this comment.
nitpick
I would suggest to add a test cases for the adm that starts with <?XML and also for the case that adm is empty that it would be marked as an mtype of banner.
🔧 Type of changes
✨ What's the context?
What's the context for the changes?
🧠 Rationale behind the change
Why did you choose to make these changes? Were there any trade-offs you had to consider?
🔎 New Bid Adapter Checklist
🧪 Test plan
How do you know the changes are safe to ship to production?
🏎 Quality check