Skip to content

Commit

Permalink
Core: Remove Empty EIDs + add new ortb fields (#3465)
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoxaAntoxic authored Oct 1, 2024
1 parent 075bdf8 commit ecd509d
Show file tree
Hide file tree
Showing 25 changed files with 357 additions and 222 deletions.
27 changes: 9 additions & 18 deletions src/main/java/com/iab/openrtb/request/Eid.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
package com.iab.openrtb.request;

import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Builder;
import lombok.Value;

import java.util.List;

/**
* Extended identifiers support in the OpenRTB specification allows buyers
* to use audience data in real-time bidding. This object can contain one
* or more {@link Uid}s from a single source or a technology provider. The
* exchange should ensure that business agreements allow for the sending
* of this data.
*/
@Value(staticConstructor = "of")
@Value
@Builder(toBuilder = true)
public class Eid {

/**
* Source or technology provider responsible for the set of included IDs. Expressed as a top-level domain.
*/
String source;

/**
* Array of extended ID {@link Uid} objects from the given source.
* Refer to 3.2.28 Extended Identifier UIDs
*/
List<Uid> uids;

/**
* Placeholder for vendor specific extensions to this object
*/
String inserter;

String matcher;

Integer mm;

ObjectNode ext;
}
4 changes: 3 additions & 1 deletion src/main/java/com/iab/openrtb/request/Uid.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.iab.openrtb.request;

import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Builder;
import lombok.Value;

/**
* This object contains a single user identifier provided as part of
* extended identifiers. The exchange should ensure that business
* agreements allow for the sending of this data.
*/
@Value(staticConstructor = "of")
@Value
@Builder(toBuilder = true)
public class Uid {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ private Future<BidRequest> updateBidRequest(AuctionContext auctionContext) {
.map(this::fillExplicitParameters)
.map(bidRequest -> overrideParameters(bidRequest, httpRequest, auctionContext.getPrebidErrors()))
.map(bidRequest -> paramsResolver.resolve(bidRequest, auctionContext, ENDPOINT, true))
.map(bidRequest -> ortb2RequestFactory.removeEmptyEids(bidRequest, auctionContext.getDebugWarnings()))
.compose(resolvedBidRequest -> ortb2RequestFactory.validateRequest(
resolvedBidRequest,
auctionContext.getHttpRequest(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ private Future<BidRequest> updateBidRequest(AuctionStoredResult auctionStoredRes
.map(ortbVersionConversionManager::convertToAuctionSupportedVersion)
.map(bidRequest -> gppService.updateBidRequest(bidRequest, auctionContext))
.map(bidRequest -> paramsResolver.resolve(bidRequest, auctionContext, ENDPOINT, hasStoredBidRequest))
.map(bidRequest -> cookieDeprecationService.updateBidRequestDevice(bidRequest, auctionContext));
.map(bidRequest -> cookieDeprecationService.updateBidRequestDevice(bidRequest, auctionContext))
.map(bidRequest -> ortb2RequestFactory.removeEmptyEids(bidRequest, auctionContext.getDebugWarnings()));
}

private static MetricName requestTypeMetric(BidRequest bidRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Device;
import com.iab.openrtb.request.Dooh;
import com.iab.openrtb.request.Eid;
import com.iab.openrtb.request.Geo;
import com.iab.openrtb.request.Publisher;
import com.iab.openrtb.request.Regs;
import com.iab.openrtb.request.Site;
import com.iab.openrtb.request.Uid;
import com.iab.openrtb.request.User;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
import io.vertx.ext.web.RoutingContext;
Expand All @@ -32,7 +35,6 @@
import org.prebid.server.exception.UnauthorizedAccountException;
import org.prebid.server.execution.Timeout;
import org.prebid.server.execution.TimeoutFactory;
import org.prebid.server.floors.PriceFloorProcessor;
import org.prebid.server.geolocation.CountryCodeMapper;
import org.prebid.server.geolocation.model.GeoInfo;
import org.prebid.server.hooks.execution.HookStageExecutor;
Expand All @@ -51,11 +53,11 @@
import org.prebid.server.model.UpdateResult;
import org.prebid.server.privacy.model.PrivacyContext;
import org.prebid.server.proto.openrtb.ext.FlexibleExtension;
import org.prebid.server.proto.openrtb.ext.request.DsaTransparency;
import org.prebid.server.proto.openrtb.ext.request.ExtPublisher;
import org.prebid.server.proto.openrtb.ext.request.ExtPublisherPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRegs;
import org.prebid.server.proto.openrtb.ext.request.ExtRegsDsa;
import org.prebid.server.proto.openrtb.ext.request.DsaTransparency;
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
import org.prebid.server.proto.openrtb.ext.request.ExtRequestTargeting;
Expand All @@ -73,12 +75,14 @@
import org.prebid.server.validation.model.ValidationResult;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Stream;

public class Ortb2RequestFactory {

Expand All @@ -99,7 +103,6 @@ public class Ortb2RequestFactory {
private final ApplicationSettings applicationSettings;
private final IpAddressHelper ipAddressHelper;
private final HookStageExecutor hookStageExecutor;
private final PriceFloorProcessor priceFloorProcessor;
private final CountryCodeMapper countryCodeMapper;
private final Metrics metrics;

Expand All @@ -115,7 +118,6 @@ public Ortb2RequestFactory(int timeoutAdjustmentFactor,
ApplicationSettings applicationSettings,
IpAddressHelper ipAddressHelper,
HookStageExecutor hookStageExecutor,
PriceFloorProcessor priceFloorProcessor,
CountryCodeMapper countryCodeMapper,
Metrics metrics) {

Expand All @@ -135,7 +137,6 @@ public Ortb2RequestFactory(int timeoutAdjustmentFactor,
this.applicationSettings = Objects.requireNonNull(applicationSettings);
this.ipAddressHelper = Objects.requireNonNull(ipAddressHelper);
this.hookStageExecutor = Objects.requireNonNull(hookStageExecutor);
this.priceFloorProcessor = Objects.requireNonNull(priceFloorProcessor);
this.countryCodeMapper = Objects.requireNonNull(countryCodeMapper);
this.metrics = Objects.requireNonNull(metrics);
}
Expand Down Expand Up @@ -206,6 +207,40 @@ public Future<BidRequest> validateRequest(BidRequest bidRequest,
: Future.succeededFuture(bidRequest);
}

public BidRequest removeEmptyEids(BidRequest bidRequest, List<String> warnings) {
final User user = bidRequest.getUser();

if (user == null) {
return bidRequest;
}

final List<Eid> eids = Stream.ofNullable(user.getEids())
.flatMap(Collection::stream)
.map(eid -> eid.toBuilder().uids(removeEmptyUids(eid, warnings)).build())
.filter(eid -> CollectionUtils.isNotEmpty(eid.getUids()))
.toList();

if (CollectionUtils.isEmpty(eids) && CollectionUtils.isNotEmpty(user.getEids())) {
warnings.add("removed empty EID array");
}

final User modifiedUser = user.toBuilder().eids(CollectionUtils.isEmpty(eids) ? null : eids).build();
return bidRequest.toBuilder().user(modifiedUser).build();
}

private List<Uid> removeEmptyUids(Eid eid, List<String> warnings) {
return CollectionUtils.emptyIfNull(eid.getUids()).stream()
.filter(uid -> {
if (StringUtils.isBlank(uid.getId())) {
warnings.add("removed EID %s due to empty ID".formatted(eid.getSource()));
return false;
}

return true;
})
.toList();
}

public Future<BidRequest> enrichBidRequestWithGeolocationData(AuctionContext auctionContext) {
final BidRequest bidRequest = auctionContext.getBidRequest();
final Device device = bidRequest.getDevice();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,18 @@ public Future<WithPodErrors<AuctionContext>> fromRequest(RoutingContext routingC
Endpoint.openrtb2_video, MetricName.video);

return ortb2RequestFactory.executeEntrypointHooks(routingContext, body, initialAuctionContext)
.compose(httpRequest ->
createBidRequest(httpRequest)
.compose(httpRequest -> createBidRequest(httpRequest)
.map(bidRequest -> removeEmptyEids(bidRequest, initialAuctionContext.getDebugWarnings()))
.compose(bidRequest -> validateRequest(
bidRequest,
httpRequest,
initialAuctionContext.getDebugWarnings()))

.compose(bidRequest -> validateRequest(
bidRequest,
httpRequest,
initialAuctionContext.getDebugWarnings()))
.map(bidRequestWithErrors -> populatePodErrors(
bidRequestWithErrors.getPodErrors(), podErrors, bidRequestWithErrors))

.map(bidRequestWithErrors -> populatePodErrors(
bidRequestWithErrors.getPodErrors(), podErrors, bidRequestWithErrors))

.map(bidRequestWithErrors -> ortb2RequestFactory.enrichAuctionContext(
initialAuctionContext, httpRequest, bidRequestWithErrors.getData(), startTime)))
.map(bidRequestWithErrors -> ortb2RequestFactory.enrichAuctionContext(
initialAuctionContext, httpRequest, bidRequestWithErrors.getData(), startTime)))

.compose(auctionContext -> ortb2RequestFactory.fetchAccountWithoutStoredRequestLookup(auctionContext)
.map(auctionContext::with))
Expand Down Expand Up @@ -154,6 +153,14 @@ public Future<WithPodErrors<AuctionContext>> fromRequest(RoutingContext routingC
.map(auctionContext -> WithPodErrors.of(auctionContext, podErrors));
}

private WithPodErrors<BidRequest> removeEmptyEids(WithPodErrors<BidRequest> requestWithPodErrors,
List<String> debugWarnings) {

return WithPodErrors.of(
ortb2RequestFactory.removeEmptyEids(requestWithPodErrors.getData(), debugWarnings),
requestWithPodErrors.getPodErrors());
}

private String extractAndValidateBody(RoutingContext routingContext) {
final String body = routingContext.getBodyAsString();
if (body == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ private static Eid prepareExtUserEid(Eid extUserEid) {
.filter(Objects::nonNull)
.map(RubiconBidder::cleanExtUserEidUidStype)
.toList();
return Eid.of(extUserEid.getSource(), extUserEidUids, extUserEid.getExt());
return extUserEid.toBuilder().uids(extUserEidUids).build();
}

private static Uid cleanExtUserEidUidStype(Uid extUserEidUid) {
Expand All @@ -1242,10 +1242,7 @@ private static Uid cleanExtUserEidUidStype(Uid extUserEidUid) {
final ObjectNode extUserEidUidExtCopy = extUserEidUidExt.deepCopy();
extUserEidUidExtCopy.remove(STYPE_FIELD);

return Uid.of(
extUserEidUid.getId(),
extUserEidUid.getAtype(),
extUserEidUidExtCopy);
return extUserEidUid.toBuilder().ext(extUserEidUidExtCopy).build();
}

private RubiconUserExtRp rubiconUserExtRp(User user, ExtImpRubicon rubiconImpExt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ Ortb2RequestFactory openRtb2RequestFactory(
IpAddressHelper ipAddressHelper,
HookStageExecutor hookStageExecutor,
CountryCodeMapper countryCodeMapper,
PriceFloorProcessor priceFloorProcessor,
Metrics metrics) {

final List<String> blocklistedAccounts = splitToList(blocklistedAccountsString);
Expand All @@ -403,7 +402,6 @@ Ortb2RequestFactory openRtb2RequestFactory(
applicationSettings,
ipAddressHelper,
hookStageExecutor,
priceFloorProcessor,
countryCodeMapper,
metrics);
}
Expand Down
14 changes: 0 additions & 14 deletions src/main/java/org/prebid/server/validation/RequestValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.request.Regs;
import com.iab.openrtb.request.Site;
import com.iab.openrtb.request.Uid;
import com.iab.openrtb.request.User;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
Expand Down Expand Up @@ -572,19 +571,6 @@ private void validateUser(User user, Map<String, String> aliases) throws Validat
throw new ValidationException(
"request.user.eids[%d] missing required field: \"source\"", index);
}
final List<Uid> eidUids = eid.getUids();
if (CollectionUtils.isEmpty(eidUids)) {
throw new ValidationException(
"request.user.eids[%d].uids must contain at least one element", index);
}
for (int uidsIndex = 0; uidsIndex < eidUids.size(); uidsIndex++) {
final Uid uid = eidUids.get(uidsIndex);
if (StringUtils.isBlank(uid.getId())) {
throw new ValidationException(
"request.user.eids[%d].uids[%d] missing required field: \"id\"", index,
uidsIndex);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.server.functional.model.request.auction

import com.fasterxml.jackson.annotation.JsonProperty
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import org.prebid.server.functional.util.PBSUtils
Expand All @@ -10,11 +11,18 @@ class Eid {

String source
List<Uid> uids
String inserter
String matcher
@JsonProperty("mm")
Integer matchMethod

static Eid getDefaultEid(String source = PBSUtils.randomString) {
new Eid().tap {
it.source = source
it.uids = [Uid.defaultUid]
it.inserter = PBSUtils.randomString
it.matcher = PBSUtils.randomString
it.matchMethod = PBSUtils.randomNumber
}
}
}
Loading

0 comments on commit ecd509d

Please sign in to comment.