Skip to content

Commit

Permalink
Merge branch 'master' into rubicon/fpd/adSlot/update
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java
  • Loading branch information
Serhii Nahornyi committed Aug 12, 2021
2 parents c346eb9 + 70e307d commit 8d92124
Show file tree
Hide file tree
Showing 56 changed files with 1,218 additions and 500 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ private static ExtHttpCall toExtHttpCall(DebugHttpCall debugHttpCall) {
.requestbody(debugHttpCall.getRequestBody())
.status(debugHttpCall.getResponseStatus())
.responsebody(debugHttpCall.getResponseBody())
.requestheaders(debugHttpCall.getRequestHeaders())
.build();
}

Expand Down
8 changes: 5 additions & 3 deletions src/main/java/org/prebid/server/auction/ExchangeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,8 @@ private BidderRequest createBidderRequest(BidderPrivacyResult bidderPrivacyResul
final ExtBidderConfigOrtb fpdConfig = ObjectUtils.defaultIfNull(biddersToConfigs.get(bidder),
biddersToConfigs.get(ALL_BIDDERS_CONFIG));

final App bidRequestApp = bidRequest.getApp();
final Site bidRequestSite = bidRequestApp == null ? bidRequest.getSite() : null;
final ObjectNode fpdSite = fpdConfig != null ? fpdConfig.getSite() : null;
final ObjectNode fpdApp = fpdConfig != null ? fpdConfig.getApp() : null;

Expand All @@ -766,8 +768,8 @@ private BidderRequest createBidderRequest(BidderPrivacyResult bidderPrivacyResul
.user(bidderPrivacyResult.getUser())
.device(bidderPrivacyResult.getDevice())
.imp(prepareImps(bidder, imps, useFirstPartyData))
.app(prepareApp(bidRequest.getApp(), fpdApp, useFirstPartyData))
.site(prepareSite(bidRequest.getSite(), fpdSite, useFirstPartyData))
.app(prepareApp(bidRequestApp, fpdApp, useFirstPartyData))
.site(prepareSite(bidRequestSite, fpdSite, useFirstPartyData))
.source(prepareSource(bidder, bidRequest))
.ext(prepareExt(bidder, bidderToPrebidBidders, bidderToMultiBid, bidRequest.getExt()))
.build());
Expand Down Expand Up @@ -1008,7 +1010,7 @@ private Future<BidderResponse> invokeHooksAndRequestBids(AuctionContext auctionC
.compose(stageResult -> requestBidsOrRejectBidder(
stageResult, bidderRequest, timeout, headers, debugEnabled, aliases))
.compose(bidderResponse -> hookStageExecutor.executeRawBidderResponseStage(
bidderResponse, auctionContext)
bidderResponse, auctionContext)
.map(stageResult -> rejectBidderResponseOrProceed(stageResult, bidderResponse)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.prebid.server.execution.Timeout;
import org.prebid.server.model.CaseInsensitiveMultiMap;
import org.prebid.server.proto.openrtb.ext.response.ExtHttpCall;
import org.prebid.server.util.HttpUtil;
import org.prebid.server.vertx.http.HttpClient;
import org.prebid.server.vertx.http.model.HttpClientResponse;

Expand Down Expand Up @@ -313,7 +314,8 @@ private static <T> ExtHttpCall toExt(HttpCall<T> httpCall) {
final HttpRequest<T> request = httpCall.getRequest();
final ExtHttpCall.ExtHttpCallBuilder builder = ExtHttpCall.builder()
.uri(request.getUri())
.requestbody(request.getBody());
.requestbody(request.getBody())
.requestheaders(HttpUtil.toDebugHeaders(request.getHeaders()));

final HttpResponse response = httpCall.getResponse();
if (response != null) {
Expand Down
117 changes: 60 additions & 57 deletions src/main/java/org/prebid/server/bidder/appnexus/AppnexusBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Imp;
Expand All @@ -11,10 +12,12 @@
import com.iab.openrtb.response.SeatBid;
import io.vertx.core.http.HttpMethod;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.prebid.server.auction.model.Endpoint;
import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.appnexus.model.ImpWithMemberId;
import org.prebid.server.bidder.appnexus.model.ImpWithExtProperties;
import org.prebid.server.bidder.appnexus.proto.AppnexusBidExt;
import org.prebid.server.bidder.appnexus.proto.AppnexusBidExtAppnexus;
import org.prebid.server.bidder.appnexus.proto.AppnexusImpExt;
Expand Down Expand Up @@ -182,47 +185,33 @@ public AppnexusBidder(String endpointUrl, JacksonMapper mapper) {
public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest bidRequest) {
final List<BidderError> errors = new ArrayList<>();
final String defaultDisplayManagerVer = makeDefaultDisplayManagerVer(bidRequest);

final List<Imp> processedImps = new ArrayList<>();
final Set<String> memberIds = new HashSet<>();
final Set<String> uniqueIds = new HashSet<>();
Boolean generateAdPodId = null;

for (final Imp imp : bidRequest.getImp()) {
try {
final ImpWithMemberId impWithMemberId = makeImpWithMemberId(imp, defaultDisplayManagerVer);
processedImps.add(impWithMemberId.getImp());
memberIds.add(impWithMemberId.getMemberId());
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
}
final ImpWithExtProperties impWithExtProperties = processImp(imp, defaultDisplayManagerVer);
final Boolean impGenerateAdPodId = impWithExtProperties.getGenerateAdPodId();

final Set<String> uniqueIds = memberIds.stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet());
generateAdPodId = ObjectUtils.defaultIfNull(generateAdPodId, impGenerateAdPodId);
if (!Objects.equals(generateAdPodId, impGenerateAdPodId)) {
return Result.withError(BidderError.badInput(
"Generate ad pod option should be same for all pods in request"));
}

final String url;
if (CollectionUtils.isNotEmpty(uniqueIds)) {
url = String.format("%s?member_id=%s", endpointUrl, uniqueIds.iterator().next());
try {
validateMemberId(uniqueIds);
processedImps.add(impWithExtProperties.getImp());
final String memberId = impWithExtProperties.getMemberId();
if (memberId != null) {
uniqueIds.add(memberId);
}
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
} else {
url = endpointUrl;
}

final List<HttpRequest<BidRequest>> httpRequests;
if (isVideoRequest(bidRequest)) {
httpRequests = groupImpsByPod(processedImps)
.values().stream()
.map(podImps -> splitHttpRequests(bidRequest, updateRequestExtForVideo(bidRequest), podImps, url))
.flatMap(Collection::stream)
.collect(Collectors.toList());
} else {
httpRequests = splitHttpRequests(bidRequest, updateRequestExt(bidRequest), processedImps, url);
}

return Result.of(httpRequests, errors);
final String url = constructUrl(uniqueIds, errors);
return Result.of(constructRequests(bidRequest, processedImps, url, generateAdPodId), errors);
}

private String makeDefaultDisplayManagerVer(BidRequest bidRequest) {
Expand Down Expand Up @@ -290,44 +279,57 @@ private static boolean isIncludeBrandCategory(ExtRequest extRequest) {
return includebrandcategory != null;
}

private String constructUrl(Set<String> ids, List<BidderError> errors) {
if (CollectionUtils.isNotEmpty(ids)) {
final String url = String.format("%s?member_id=%s", endpointUrl, ids.iterator().next());
try {
validateMemberId(ids);
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
return url;
}
return endpointUrl;
}

private List<HttpRequest<BidRequest>> constructRequests(BidRequest bidRequest,
List<Imp> imps,
String url,
Boolean generateAdPodId) {
if (isVideoRequest(bidRequest) && BooleanUtils.isTrue(generateAdPodId)) {
return groupImpsByPod(imps)
.values().stream()
.map(podImps -> splitHttpRequests(bidRequest, updateRequestExtForVideo(bidRequest), podImps, url))
.flatMap(Collection::stream)
.collect(Collectors.toList());
} else {
return splitHttpRequests(bidRequest, updateRequestExt(bidRequest), imps, url);
}
}

private Map<String, List<Imp>> groupImpsByPod(List<Imp> processedImps) {
return processedImps.stream()
.collect(Collectors.groupingBy(imp -> StringUtils.substringBefore(imp.getId(), POD_SEPARATOR)));
}

private List<HttpRequest<BidRequest>> splitHttpRequests(BidRequest bidRequest,
ExtRequest requestExt,
List<Imp> processedImps,
List<Imp> imps,
String url) {
final List<HttpRequest<BidRequest>> result = Lists.partition(imps, MAX_IMP_PER_REQUEST)
.stream()
.map(impsChunk -> createHttpRequest(bidRequest, requestExt, impsChunk, url))
.collect(Collectors.toList());

// Let's say there are 35 impressions and limit impressions per request equals to 10.
// In this case we need to create 4 requests with 10, 10, 10 and 5 impressions.
// With this formula initial capacity=(35+10-1)/10 = 4
final int impSize = processedImps.size();
final int numberOfRequests = (impSize + MAX_IMP_PER_REQUEST - 1) / MAX_IMP_PER_REQUEST;
final List<HttpRequest<BidRequest>> spitedRequests = new ArrayList<>(numberOfRequests);

int startIndex = 0;
boolean impsLeft = true;
while (impsLeft) {
int endIndex = startIndex + MAX_IMP_PER_REQUEST;
if (endIndex >= impSize) {
impsLeft = false;
endIndex = impSize;
}
spitedRequests.add(
createHttpRequest(bidRequest, requestExt, processedImps.subList(startIndex, endIndex), url));
startIndex = endIndex;
}

return spitedRequests;
return result.isEmpty()
? Collections.singletonList(createHttpRequest(bidRequest, requestExt, imps, url))
: result;
}

private HttpRequest<BidRequest> createHttpRequest(BidRequest bidRequest,
ExtRequest requestExt,
List<Imp> imps,
String url) {

final BidRequest outgoingRequest = bidRequest.toBuilder()
.imp(imps)
.ext(requestExt)
Expand All @@ -342,7 +344,7 @@ private HttpRequest<BidRequest> createHttpRequest(BidRequest bidRequest,
.build();
}

private ImpWithMemberId makeImpWithMemberId(Imp imp, String defaultDisplayManagerVer) {
private ImpWithExtProperties processImp(Imp imp, String defaultDisplayManagerVer) {
if (imp.getAudio() != null) {
throw new PreBidException(
String.format("Appnexus doesn't support audio Imps. Ignoring Imp ID=%s", imp.getId()));
Expand All @@ -369,7 +371,8 @@ private ImpWithMemberId makeImpWithMemberId(Imp imp, String defaultDisplayManage
impBuilder.displaymanagerver(defaultDisplayManagerVer);
}

return ImpWithMemberId.of(impBuilder.build(), appnexusExt.getMember());
return ImpWithExtProperties.of(impBuilder.build(), appnexusExt.getMember(),
appnexusExt.getGenerateAdPodId());
}

private static boolean bidFloorIsValid(BigDecimal bidFloor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

@AllArgsConstructor(staticName = "of")
@Value
public class ImpWithMemberId {
public class ImpWithExtProperties {

Imp imp;

String memberId;

Boolean generateAdPodId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.prebid.server.bidder.medianet;

import org.prebid.server.bidder.Bidder;
import org.prebid.server.bidder.OpenrtbBidder;
import org.prebid.server.json.JacksonMapper;

/**
* Medianet {@link Bidder} implementation.
*/
public class MedianetBidder extends OpenrtbBidder<Void> {

public MedianetBidder(String endpointUrl, JacksonMapper mapper) {
super(endpointUrl,
RequestCreationStrategy.SINGLE_REQUEST,
Void.class,
mapper);
}
}
17 changes: 5 additions & 12 deletions src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import com.iab.openrtb.request.App;
Expand Down Expand Up @@ -88,7 +89,6 @@
import org.prebid.server.proto.openrtb.ext.request.rubicon.RubiconVideoParams;
import org.prebid.server.proto.openrtb.ext.response.BidType;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebid;
import org.prebid.server.proto.openrtb.ext.response.ExtBidPrebidMeta;
import org.prebid.server.util.HttpUtil;

import java.math.BigDecimal;
Expand Down Expand Up @@ -144,7 +144,7 @@ public class RubiconBidder implements Bidder<BidRequest> {
private static final String DMP_STYPE = "dmp";
private static final String XAPI_CURRENCY = "USD";
private static final Set<Integer> USER_SEGTAXES = ImmutableSet.of(4);
private static final Set<Integer> SITE_SEGTAXES = ImmutableSet.of(1, 2);
private static final Set<Integer> SITE_SEGTAXES = ImmutableSet.of(1, 2, 5, 6);

private static final Set<String> STYPE_TO_REMOVE = new HashSet<>(Arrays.asList(PPUID_STYPE, SHA256EMAIL_STYPE,
DMP_STYPE));
Expand Down Expand Up @@ -1278,7 +1278,6 @@ private List<BidderBid> bidsFromResponse(BidRequest prebidRequest,
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(bid -> updateBid(bid, idToImp.get(bid.getImpid()), cpmOverrideFromRequest, bidResponse))
.filter(RubiconBidder::validatePrice)
.map(bid -> BidderBid.of(bid, bidType, bidResponse.getCur()))
.collect(Collectors.toList());
}
Expand Down Expand Up @@ -1306,11 +1305,10 @@ private Bid insertNetworkIdToMeta(Bid bid, int networkId, List<BidderError> erro
return null;
}
final ExtBidPrebid extBidPrebid = extPrebid != null ? extPrebid.getPrebid() : null;
final ExtBidPrebidMeta meta = extBidPrebid != null ? extBidPrebid.getMeta() : null;
final ObjectNode meta = extBidPrebid != null ? extBidPrebid.getMeta() : null;

final ExtBidPrebidMeta updatedMeta = meta != null
? meta.toBuilder().networkId(networkId).build()
: ExtBidPrebidMeta.builder().networkId(networkId).build();
final ObjectNode updatedMeta = meta != null ? meta : mapper.mapper().createObjectNode();
updatedMeta.set("networkId", IntNode.valueOf(networkId));

final ExtBidPrebid modifiedExtBidPrebid = extBidPrebid != null
? extBidPrebid.toBuilder().meta(updatedMeta).build()
Expand All @@ -1330,11 +1328,6 @@ private ExtPrebid<ExtBidPrebid, ObjectNode> getExtPrebid(ObjectNode bidExt, Stri
}
}

private static boolean validatePrice(Bid bid) {
final BigDecimal price = bid.getPrice();
return bid.getDealid() != null ? price.compareTo(BigDecimal.ZERO) >= 0 : price.compareTo(BigDecimal.ZERO) > 0;
}

private Bid updateBid(Bid bid, Imp imp, Float cpmOverrideFromRequest, RubiconBidResponse bidResponse) {
String bidId = bid.getId();
if (generateBidId) {
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/prebid/server/cache/CacheService.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.Imp;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import lombok.Value;
Expand Down Expand Up @@ -61,6 +62,8 @@ public class CacheService {

private static final Logger logger = LoggerFactory.getLogger(CacheService.class);

private static final MultiMap CACHE_HEADERS = HttpUtil.headers();
private static final Map<String, List<String>> DEBUG_HEADERS = HttpUtil.toDebugHeaders(CACHE_HEADERS);
private static final String BID_WURL_ATTRIBUTE = "wurl";

private final CacheTtl mediaTypeCacheTtl;
Expand Down Expand Up @@ -124,7 +127,7 @@ private Future<BidCacheResponse> makeRequest(
}

final long startTime = clock.millis();
return httpClient.post(endpointUrl.toString(), HttpUtil.headers(), mapper.encode(bidCacheRequest),
return httpClient.post(endpointUrl.toString(), CACHE_HEADERS, mapper.encode(bidCacheRequest),
remainingTimeout)
.map(response -> toBidCacheResponse(
response.getStatusCode(), response.getBody(), bidCount, accountId, startTime))
Expand Down Expand Up @@ -307,7 +310,7 @@ private Future<CacheServiceResult> doCacheOpenrtb(List<CacheBid> bids,
final CacheHttpRequest httpRequest = CacheHttpRequest.of(url, body);

final long startTime = clock.millis();
return httpClient.post(url, HttpUtil.headers(), body, remainingTimeout)
return httpClient.post(url, CACHE_HEADERS, body, remainingTimeout)
.map(response -> processResponseOpenrtb(
response, httpRequest, cachedCreatives.size(), bids, videoBids, accountId, startTime))
.otherwise(exception -> failResponseOpenrtb(exception, accountId, httpRequest, startTime));
Expand Down Expand Up @@ -368,6 +371,7 @@ private DebugHttpCall makeDebugHttpCall(String endpoint, CacheHttpRequest httpRe
.responseStatus(httpResponse != null ? httpResponse.getStatusCode() : null)
.responseBody(httpResponse != null ? httpResponse.getBody() : null)
.responseTimeMillis(responseTime(startTime))
.requestHeaders(DEBUG_HEADERS)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import lombok.Builder;
import lombok.Value;

import java.util.List;
import java.util.Map;

/**
* Holds HTTP interaction related data.
*/
Expand All @@ -20,5 +23,7 @@ public class DebugHttpCall {

String responseBody;

Map<String, List<String>> requestHeaders;

Integer responseTimeMillis;
}
Loading

0 comments on commit 8d92124

Please sign in to comment.