Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.response.Bid;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.model.BidderBid;
import org.prebid.server.bidder.model.BidderCall;
import org.prebid.server.bidder.model.BidderError;
import org.prebid.server.bidder.model.HttpRequest;
import org.prebid.server.bidder.model.Price;
import org.prebid.server.bidder.model.Result;
import org.prebid.server.bidder.stroeercore.model.StroeerCoreBid;
import org.prebid.server.bidder.stroeercore.model.StroeerCoreBidResponse;
import org.prebid.server.currency.CurrencyConversionService;
import org.prebid.server.exception.PreBidException;
import org.prebid.server.json.DecodeException;
import org.prebid.server.json.JacksonMapper;
Expand All @@ -26,7 +23,6 @@
import org.prebid.server.util.BidderUtil;
import org.prebid.server.util.HttpUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -41,14 +37,10 @@ public class StroeerCoreBidder implements Bidder<BidRequest> {

private final String endpointUrl;
private final JacksonMapper mapper;
private final CurrencyConversionService currencyConversionService;

public StroeerCoreBidder(String endpointUrl,
JacksonMapper mapper,
CurrencyConversionService currencyConversionService) {
public StroeerCoreBidder(String endpointUrl, JacksonMapper mapper) {
this.endpointUrl = HttpUtil.validateUrl(endpointUrl);
this.mapper = Objects.requireNonNull(mapper);
this.currencyConversionService = Objects.requireNonNull(currencyConversionService);
}

@Override
Expand All @@ -57,37 +49,20 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest bidRequ
final List<BidderError> errors = new ArrayList<>();

for (Imp imp : bidRequest.getImp()) {
final ExtImpStroeerCore impExt;
final Price price;

try {
validateImp(imp);

impExt = parseImpExt(imp);
validateImpExt(impExt);

price = convertBidFloor(bidRequest, imp);
final ExtImpStroeerCore impExt = parseImpExt(imp);
modifiedImps.add(imp.toBuilder().tagid(impExt.getSlotId()).build());
} catch (PreBidException e) {
errors.add(BidderError.badInput("%s. Ignore imp id = %s.".formatted(e.getMessage(), imp.getId())));
continue;
}

modifiedImps.add(modifyImp(imp, impExt, price));
}

if (modifiedImps.isEmpty()) {
return Result.withErrors(errors);
}

final BidRequest outgoingRequest = bidRequest.toBuilder().imp(modifiedImps).build();

return createHttpRequests(errors, outgoingRequest);
}

private static void validateImp(Imp imp) {
if (imp.getBanner() == null && imp.getVideo() == null) {
throw new PreBidException("Expected banner or video impression");
}
return Result.withValue(BidderUtil.defaultRequest(outgoingRequest, endpointUrl, mapper));
}

private ExtImpStroeerCore parseImpExt(Imp imp) {
Expand All @@ -98,95 +73,65 @@ private ExtImpStroeerCore parseImpExt(Imp imp) {
}
}

private static void validateImpExt(ExtImpStroeerCore impExt) {
if (StringUtils.isBlank(impExt.getSlotId())) {
throw new PreBidException("Custom param slot id (sid) is empty");
}
}

private Price convertBidFloor(BidRequest bidRequest, Imp imp) {
final BigDecimal bidFloor = imp.getBidfloor();
final String bidFloorCurrency = imp.getBidfloorcur();

if (!shouldConvertBidFloor(bidFloor, bidFloorCurrency)) {
return Price.of(bidFloorCurrency, bidFloor);
}

final BigDecimal convertedBidFloor = currencyConversionService.convertCurrency(
bidFloor, bidRequest, bidFloorCurrency, BIDDER_CURRENCY);

return Price.of(BIDDER_CURRENCY, convertedBidFloor);
}

private Result<List<HttpRequest<BidRequest>>> createHttpRequests(List<BidderError> errors, BidRequest bidRequest) {
return Result.of(Collections.singletonList(BidderUtil.defaultRequest(bidRequest, endpointUrl, mapper)), errors);
}

private static boolean shouldConvertBidFloor(BigDecimal bidFloor, String bidFloorCurrency) {
return BidderUtil.isValidPrice(bidFloor) && !StringUtils.equalsIgnoreCase(bidFloorCurrency, BIDDER_CURRENCY);
}

private static Imp modifyImp(Imp imp, ExtImpStroeerCore impExt, Price price) {
return imp.toBuilder()
.bidfloorcur(price.getCurrency())
.bidfloor(price.getValue())
.tagid(impExt.getSlotId())
.build();
}

@Override
public Result<List<BidderBid>> makeBids(BidderCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final String body = httpCall.getResponse().getBody();
final List<BidderError> errors = new ArrayList<>();
final StroeerCoreBidResponse bidResponse = mapper.decodeValue(body, StroeerCoreBidResponse.class);
return Result.withValues(extractBids(httpCall.getRequest().getPayload(), bidResponse));
return Result.of(extractBids(bidResponse, errors), errors);
} catch (DecodeException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
}
}

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

return bidResponse.getBids().stream()
.filter(Objects::nonNull)
.map(stroeerCoreBid -> toBidderBid(bidRequest, stroeerCoreBid))
.map(stroeerCoreBid -> toBidderBid(stroeerCoreBid, errors))
.filter(Objects::nonNull)
.toList();
}

private BidderBid toBidderBid(BidRequest bidRequest, StroeerCoreBid stroeercoreBid) {
private BidderBid toBidderBid(StroeerCoreBid stroeercoreBid, List<BidderError> errors) {
final BidType bidType = getBidType(stroeercoreBid.getMtype());
if (bidType == null) {
errors.add(BidderError.badServerResponse(
"Bid media type error: unable to determine media type for bid with id \"%s\""
.formatted(stroeercoreBid.getBidId())));
return null;
}

final ObjectNode bidExt = stroeercoreBid.getDsa() != null
? mapper.mapper().createObjectNode().set("dsa", stroeercoreBid.getDsa())
: null;

return BidderBid.of(
Bid.builder()
.id(stroeercoreBid.getId())
.impid(stroeercoreBid.getImpId())
.impid(stroeercoreBid.getBidId())
.w(stroeercoreBid.getWidth())
.h(stroeercoreBid.getHeight())
.price(stroeercoreBid.getCpm())
.adm(stroeercoreBid.getAdMarkup())
.crid(stroeercoreBid.getCreativeId())
.adomain(stroeercoreBid.getAdomain())
.mtype(bidType.ordinal() + 1)
.ext(bidExt)
.build(),
getBidType(stroeercoreBid.getImpId(), bidRequest.getImp()),
bidType,
BIDDER_CURRENCY);
}

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;
} else if (imp.getVideo() != null) {
return BidType.video;
}
}
}

return BidType.banner;
private static BidType getBidType(String mtype) {
return switch (mtype) {
case "banner" -> BidType.banner;
case "video" -> BidType.video;
default -> null;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Value;

import java.math.BigDecimal;
import java.util.List;

@Value
@Builder
Expand All @@ -14,7 +15,7 @@ public class StroeerCoreBid {
String id;

@JsonProperty("bidId")
String impId;
String bidId;

BigDecimal cpm;

Expand All @@ -29,4 +30,8 @@ public class StroeerCoreBid {
String creativeId;

ObjectNode dsa;

String mtype;

List<String> adomain;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.prebid.server.bidder.BidderDeps;
import org.prebid.server.bidder.stroeercore.StroeerCoreBidder;
import org.prebid.server.currency.CurrencyConversionService;
import org.prebid.server.json.JacksonMapper;
import org.prebid.server.spring.config.bidder.model.BidderConfigurationProperties;
import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler;
Expand Down Expand Up @@ -31,13 +30,12 @@ BidderConfigurationProperties configurationProperties() {
@Bean
BidderDeps stroeercoreBidderDeps(BidderConfigurationProperties stroeercoreConfigurationProperties,
@NotBlank @Value("${external-url}") String externalUrl,
CurrencyConversionService currencyConversionService,
JacksonMapper mapper) {

return BidderDepsAssembler.forBidder(BIDDER_NAME)
.withConfig(stroeercoreConfigurationProperties)
.usersyncerCreator(UsersyncerCreator.create(externalUrl))
.bidderCreator(config -> new StroeerCoreBidder(config.getEndpoint(), mapper, currencyConversionService))
.bidderCreator(config -> new StroeerCoreBidder(config.getEndpoint(), mapper))
.assemble();
}
}
4 changes: 3 additions & 1 deletion src/main/resources/static/bidder-params/stroeerCore.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@
"description": "Slot Id"
}
},
"required": ["sid"]
"required": [
"sid"
]
}
Loading
Loading