Skip to content

Commit

Permalink
Revert "Revert "Iqzone: Add mType support (#3044)" (#3089)"
Browse files Browse the repository at this point in the history
This reverts commit a46a54c.
  • Loading branch information
Net-burst committed Apr 3, 2024
1 parent a46a54c commit 10ba575
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 53 deletions.
69 changes: 37 additions & 32 deletions src/main/java/org/prebid/server/bidder/iqzone/IqzoneBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.node.TextNode;
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.apache.commons.collections4.CollectionUtils;
Expand Down Expand Up @@ -49,32 +50,43 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
final List<HttpRequest<BidRequest>> httpRequests = new ArrayList<>();

for (Imp imp : request.getImp()) {
final ExtImpIqzone extImpIqzone;
try {
final ExtImpIqzone extImpIqzone = parseImpExt(imp);
final Imp modifiedImp = modifyImp(imp, extImpIqzone);

httpRequests.add(makeHttpRequest(request, modifiedImp));
extImpIqzone = parseImpExt(imp);
} catch (IllegalArgumentException e) {
return Result.withError(BidderError.badInput(e.getMessage()));
}

final Imp modifiedImp = modifyImp(imp, extImpIqzone);
httpRequests.add(makeHttpRequest(request, modifiedImp));
}

return Result.withValues(httpRequests);
}

private ExtImpIqzone parseImpExt(Imp imp) {
return mapper.mapper().convertValue(imp.getExt(), IQZONE_EXT_TYPE_REFERENCE).getBidder();
try {
return mapper.mapper().convertValue(imp.getExt(), IQZONE_EXT_TYPE_REFERENCE).getBidder();
} catch (IllegalArgumentException e) {
throw new PreBidException(e.getMessage());
}
}

private Imp modifyImp(Imp imp, ExtImpIqzone impExt) {
final String placementId = impExt.getPlacementId();
final ObjectNode modifiedImpExtBidder = mapper.mapper().createObjectNode();
final String endpointId = impExt.getEndpointId();

final boolean isPlacementIdEmpty = StringUtils.isEmpty(placementId);
if (isPlacementIdEmpty && StringUtils.isEmpty(endpointId)) {
return imp;
}

if (StringUtils.isNotEmpty(placementId)) {
final ObjectNode modifiedImpExtBidder = mapper.mapper().createObjectNode();
if (!isPlacementIdEmpty) {
modifiedImpExtBidder.set("placementId", TextNode.valueOf(placementId));
modifiedImpExtBidder.set("type", TextNode.valueOf("publisher"));
} else {
modifiedImpExtBidder.set("endpointId", TextNode.valueOf(impExt.getEndpointId()));
modifiedImpExtBidder.set("endpointId", TextNode.valueOf(endpointId));
modifiedImpExtBidder.set("type", TextNode.valueOf("network"));
}

Expand All @@ -84,54 +96,47 @@ private Imp modifyImp(Imp imp, ExtImpIqzone impExt) {
}

private HttpRequest<BidRequest> makeHttpRequest(BidRequest request, Imp imp) {
final BidRequest outgoingRequest = request.toBuilder().imp(List.of(imp)).build();

final BidRequest outgoingRequest = request.toBuilder().imp(Collections.singletonList(imp)).build();
return BidderUtil.defaultRequest(outgoingRequest, endpointUrl, mapper);
}

@Override
public Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
return Result.of(extractBids(httpCall.getRequest().getPayload(), bidResponse), Collections.emptyList());
return Result.withValues(extractBids(bidResponse));
} catch (DecodeException | PreBidException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
}
}

private List<BidderBid> extractBids(BidRequest bidRequest, BidResponse bidResponse) {
private List<BidderBid> extractBids(BidResponse bidResponse) {
if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) {
return Collections.emptyList();
}

return bidsFromResponse(bidRequest, bidResponse);
}

private List<BidderBid> bidsFromResponse(BidRequest bidRequest, BidResponse bidResponse) {
return bidResponse.getSeatbid().stream()
.filter(Objects::nonNull)
.map(SeatBid::getBid)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(bid -> BidderBid.of(bid, getBidType(bid.getImpid(), bidRequest.getImp()), bidResponse.getCur()))
.filter(Objects::nonNull)
.map(bid -> BidderBid.of(bid, getBidMediaType(bid), bidResponse.getCur()))
.toList();
}

private static BidType getBidType(String impId, List<Imp> imps) {
for (Imp imp : imps) {
if (imp.getId().equals(impId)) {
if (imp.getBanner() != null) {
return BidType.banner;
}
if (imp.getVideo() != null) {
return BidType.video;
}
if (imp.getXNative() != null) {
return BidType.xNative;
}
throw new PreBidException("Unknown impression type for ID: \"%s\"".formatted(impId));
}
private static BidType getBidMediaType(Bid bid) {
final Integer markupType = bid.getMtype();
if (markupType == null) {
throw new PreBidException("Missing MType for bid: " + bid.getId());
}
throw new PreBidException("Failed to find impression for ID: \"%s\"".formatted(impId));

return switch (markupType) {
case 1 -> BidType.banner;
case 2 -> BidType.video;
case 4 -> BidType.xNative;
default -> throw new PreBidException(
"Unable to fetch mediaType " + bid.getMtype() + " in multi-format: " + bid.getImpid());
};
}
}
54 changes: 33 additions & 21 deletions src/test/java/org/prebid/server/bidder/iqzone/IqzoneBidderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.request.Native;
import com.iab.openrtb.request.Video;
import com.iab.openrtb.response.Bid;
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
Expand Down Expand Up @@ -116,6 +113,26 @@ public void makeHttpRequestsShouldModifyImpExtWithEndpointIdAndTypeIfEndpointIdP
.set("bidder", mapper.valueToTree(expectedImpExtBidder)));
}

@Test
public void makeHttpRequestsShouldNotModifyImpExt() {
// given
final BidRequest bidRequest = givenBidRequest(impBuilder ->
impBuilder.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpIqzone.of(null, null)))));

// when
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.extracting(Imp::getExt)
.extracting(ext -> ext.get("bidder"))
.map(JsonNode::isEmpty)
.containsExactly(true);
}

@Test
public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() {
// given
Expand Down Expand Up @@ -163,9 +180,8 @@ public void makeBidsShouldReturnEmptyResponseIfBidResponseSeatBidIsNull() throws
@Test
public void makeBidsShouldCorrectlyProceedWithVideo() throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(impBuilder -> impBuilder
.id("someId").video(Video.builder().build())),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("someId"))));
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.mtype(2))));

// when
final Result<List<BidderBid>> result = target.makeBids(httpCall, null);
Expand All @@ -179,9 +195,8 @@ public void makeBidsShouldCorrectlyProceedWithVideo() throws JsonProcessingExcep
@Test
public void makeBidsShouldCorrectlyProceedWithNative() throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(impBuilder -> impBuilder
.id("someId").xNative(Native.builder().build())),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("someId"))));
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.mtype(4))));

// when
final Result<List<BidderBid>> result = target.makeBids(httpCall, null);
Expand All @@ -195,9 +210,8 @@ public void makeBidsShouldCorrectlyProceedWithNative() throws JsonProcessingExce
@Test
public void makeBidsShouldCorrectlyProceedWithBanner() throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(impBuilder -> impBuilder
.id("someId").banner(Banner.builder().build())),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("someId"))));
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.mtype(1))));

// when
final Result<List<BidderBid>> result = target.makeBids(httpCall, null);
Expand All @@ -211,9 +225,8 @@ public void makeBidsShouldCorrectlyProceedWithBanner() throws JsonProcessingExce
@Test
public void makeBidsShouldReturnErrorIfImpIdDoesNotMatchImpIdInBid() throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(impBuilder -> impBuilder
.id("someIdThatIsDifferentFromIDInBid").xNative(Native.builder().build())),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("someId"))));
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(identity()),
mapper.writeValueAsString(givenBidResponse(identity())));

// when
final Result<List<BidderBid>> result = target.makeBids(httpCall, null);
Expand All @@ -222,17 +235,16 @@ public void makeBidsShouldReturnErrorIfImpIdDoesNotMatchImpIdInBid() throws Json
assertThat(result.getErrors()).hasSize(1)
.allSatisfy(error -> {
assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response);
assertThat(error.getMessage()).startsWith("Failed to find impression for ID:");
assertThat(error.getMessage()).startsWith("Missing MType for bid: null");
});
assertThat(result.getValue()).isEmpty();
}

@Test
public void makeBidsShouldReturnErrorWhenMissingType() throws JsonProcessingException {
public void makeBidsShouldReturnErrorWhenMissingMType() throws JsonProcessingException {
// given
final BidderCall<BidRequest> httpCall = givenHttpCall(
givenBidRequest(impBuilder -> impBuilder.id("someId")),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("someId"))));
final BidderCall<BidRequest> httpCall = givenHttpCall(givenBidRequest(),
mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.mtype(null))));

// when
final Result<List<BidderBid>> result = target.makeBids(httpCall, null);
Expand All @@ -241,7 +253,7 @@ public void makeBidsShouldReturnErrorWhenMissingType() throws JsonProcessingExce
assertThat(result.getErrors()).hasSize(1)
.allSatisfy(error -> {
assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response);
assertThat(error.getMessage()).startsWith("Unknown impression type for ID");
assertThat(error.getMessage()).startsWith("Missing MType for bid: null");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"impid": "imp_id",
"price": 3.33,
"adm": "adm001",
"mtype": 1,
"adid": "adid001",
"cid": "cid001",
"crid": "crid001",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"id": "bid_id",
"impid": "imp_id",
"price": 3.33,
"mtype": 1,
"adid": "adid001",
"crid": "crid001",
"cid": "cid001",
Expand Down

0 comments on commit 10ba575

Please sign in to comment.