Skip to content

Commit

Permalink
Strip eids of certain type in Rubicon bidder (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
BraslavskiyAndrey authored Sep 24, 2020
1 parent 3f78bbb commit 7748869
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 12 deletions.
79 changes: 76 additions & 3 deletions src/main/java/org/prebid/server/bidder/rubicon/RubiconBidder.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ public class RubiconBidder implements Bidder<BidRequest> {
private static final String FPD_DFP_AD_UNIT_CODE_FIELD = "dfp_ad_unit_code";
private static final String FPD_KEYWORDS_FIELD = "keywords";

private static final String PPUID_STYPE = "ppuid";
private static final String SHA256EMAIL_STYPE = "sha256email";
private static final String DMP_STYPE = "dmp";
private static final Set<String> STYPE_TO_REMOVE = new HashSet<>(Arrays.asList(PPUID_STYPE, SHA256EMAIL_STYPE,
DMP_STYPE));
private static final TypeReference<ExtPrebid<ExtImpPrebid, ExtImpRubicon>> RUBICON_EXT_TYPE_REFERENCE =
new TypeReference<ExtPrebid<ExtImpPrebid, ExtImpRubicon>>() {
};
Expand Down Expand Up @@ -677,26 +682,34 @@ private static List<Integer> mapToRubiconSizeIds(List<Format> sizes) {
}

private User makeUser(User user, ExtImpRubicon rubiconImpExt) {
final String userId = user != null ? user.getId() : null;
final ExtUser extUser = user != null ? user.getExt() : null;
final String resolvedId = userId == null ? resolveUserId(extUser) : null;
final List<ExtUserEid> extUserEids = extUser != null ? extUser.getEids() : null;
final Map<String, List<ExtUserEid>> sourceToUserEidExt = extUser != null
? specialExtUserEids(extUser.getEids())
? specialExtUserEids(extUserEids)
: null;
final List<ExtUserTpIdRubicon> userExtTpIds = sourceToUserEidExt != null
? extractExtUserTpIds(sourceToUserEidExt)
: null;
final boolean hasStypeToRemove = hasStypeToRemove(extUserEids);
final List<ExtUserEid> resolvedExtUserEids = hasStypeToRemove
? prepareExtUserEids(extUserEids)
: extUserEids;
final RubiconUserExtRp userExtRp = rubiconUserExtRp(user, rubiconImpExt, sourceToUserEidExt);
final ObjectNode userExtData = extUser != null ? extUser.getData() : null;
final String liverampId = extractLiverampId(sourceToUserEidExt);

if (userExtRp == null && userExtTpIds == null && userExtData == null && liverampId == null) {
if (userExtRp == null && userExtTpIds == null && userExtData == null && liverampId == null
&& resolvedId == null && !hasStypeToRemove) {
return user;
}

final ExtUser userExt = extUser != null
? ExtUser.builder()
.consent(extUser.getConsent())
.digitrust(extUser.getDigitrust())
.eids(extUser.getEids())
.eids(resolvedExtUserEids)
.build()
: ExtUser.builder().build();

Expand All @@ -709,13 +722,73 @@ private User makeUser(User user, ExtImpRubicon rubiconImpExt) {
final User.UserBuilder userBuilder = user != null ? user.toBuilder() : User.builder();

return userBuilder
.id(resolvedId)
.gender(null)
.yob(null)
.geo(null)
.ext(mapper.fillExtension(userExt, rubiconUserExt))
.build();
}

private String resolveUserId(ExtUser extUser) {
final List<ExtUserEid> extUserEids = extUser != null ? extUser.getEids() : null;
return CollectionUtils.emptyIfNull(extUserEids)
.stream()
.map(extUserEid -> getIdFromFirstUuidWithStypePpuid(extUserEid.getUids()))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
}

private String getIdFromFirstUuidWithStypePpuid(List<ExtUserEidUid> extUserEidUids) {
return CollectionUtils.emptyIfNull(extUserEidUids).stream()
.filter(Objects::nonNull)
.filter(extUserEidUid -> Objects.equals(PPUID_STYPE, getUserEidUidStype(extUserEidUid)))
.map(ExtUserEidUid::getId)
.findFirst()
.orElse(null);
}

private String getUserEidUidStype(ExtUserEidUid extUserEidUid) {
final ExtUserEidUidExt extUserEidUidExt = extUserEidUid.getExt();
return extUserEidUidExt != null ? extUserEidUidExt.getStype() : null;
}

private boolean hasStypeToRemove(List<ExtUserEid> extUserEids) {
return CollectionUtils.emptyIfNull(extUserEids).stream()
.filter(Objects::nonNull)
.map(ExtUserEid::getUids)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.map(ExtUserEidUid::getExt)
.filter(Objects::nonNull)
.map(ExtUserEidUidExt::getStype)
.anyMatch(STYPE_TO_REMOVE::contains);
}

private List<ExtUserEid> prepareExtUserEids(List<ExtUserEid> extUserEids) {
return CollectionUtils.emptyIfNull(extUserEids).stream()
.filter(Objects::nonNull)
.map(RubiconBidder::prepareExtUserEid)
.collect(Collectors.toList());
}

private static ExtUserEid prepareExtUserEid(ExtUserEid extUserEid) {
final List<ExtUserEidUid> extUserEidUids = CollectionUtils.emptyIfNull(extUserEid.getUids()).stream()
.filter(Objects::nonNull)
.map(RubiconBidder::cleanExtUserEidUidStype)
.collect(Collectors.toList());
return ExtUserEid.of(extUserEid.getSource(), extUserEid.getId(), extUserEidUids, extUserEid.getExt());
}

private static ExtUserEidUid cleanExtUserEidUidStype(ExtUserEidUid extUserEidUid) {
final ExtUserEidUidExt extUserEidUidExt = extUserEidUid.getExt();
return STYPE_TO_REMOVE.contains(extUserEidUidExt.getStype())
? ExtUserEidUid.of(extUserEidUid.getId(), extUserEidUid.getAtype(),
ExtUserEidUidExt.of(extUserEidUidExt.getRtiPartner(), null))
: extUserEidUid;
}

private static Map<String, List<ExtUserEid>> specialExtUserEids(List<ExtUserEid> eids) {
if (CollectionUtils.isEmpty(eids)) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public class ExtUserEidUidExt {

@JsonProperty("rtiPartner")
String rtiPartner;

String stype;
}
106 changes: 97 additions & 9 deletions src/test/java/org/prebid/server/bidder/rubicon/RubiconBidderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,8 @@ public void makeHttpRequestsShouldCreateUserExtTpIdWithAdServerEidSource() {
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("adserver.org", null,
singletonList(
ExtUserEidUid.of("adServerUid", null, ExtUserEidUidExt.of("TDID"))),
null)))
ExtUserEidUid.of("adServerUid", null,
ExtUserEidUidExt.of("TDID", null))), null)))
.build())
.build()),
builder -> builder.video(Video.builder().build()), identity());
Expand All @@ -774,14 +774,99 @@ public void makeHttpRequestsShouldCreateUserExtTpIdWithAdServerEidSource() {
"adserver.org",
null,
singletonList(ExtUserEidUid.of("adServerUid", null,
ExtUserEidUidExt.of("TDID"))),
ExtUserEidUidExt.of("TDID", null))),
null)))
.build(),
RubiconUserExt.builder()
.tpid(singletonList(ExtUserTpIdRubicon.of("tdid", "adServerUid")))
.build()));
}

@Test
public void makeHttpRequestsShouldCreateUserIdIfMissingFromFirstUidStypePpuid() {
// given
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of(null, null,
asList(
ExtUserEidUid.of("id1", null, ExtUserEidUidExt.of(null, "other")),
ExtUserEidUid.of("id2", null, ExtUserEidUidExt.of(null, "ppuid")),
ExtUserEidUid.of("id3", null, ExtUserEidUidExt.of(null, "ppuid"))),
null)))
.build())
.build()),
builder -> builder.video(Video.builder().build()), identity());

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

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue()).hasSize(1).doesNotContainNull()
.extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class))
.extracting(request -> request.getUser().getId())
.containsOnly("id2");
}

@Test
public void makeHttpRequestsShouldNotCreateUseIdIfMissingWhenNoUidWithPpuidType() {
// given
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of(null, null,
asList(
ExtUserEidUid.of("id1", null, ExtUserEidUidExt.of(null, "other")),
ExtUserEidUid.of("id2", null, ExtUserEidUidExt.of(null, "other"))),
null)))
.build())
.build()),
builder -> builder.video(Video.builder().build()), identity());

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

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue()).hasSize(1).doesNotContainNull()
.extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class))
.extracting(request -> request.getUser().getId()).element(0).isNull();
}

@Test
public void makeHttpRequestsShouldRemoveStypesPpuidSha256emailDmp() {
// given
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("source", "id",
asList(
ExtUserEidUid.of("id1", null, ExtUserEidUidExt.of(null, "other")),
ExtUserEidUid.of("id2", null, ExtUserEidUidExt.of(null, "ppuid")),
ExtUserEidUid.of("id3", null, ExtUserEidUidExt.of(null, "sha256email")),
ExtUserEidUid.of("id4", null, ExtUserEidUidExt.of(null, "dmp"))),
null)))
.build())
.build()),
builder -> builder.video(Video.builder().build()), identity());

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

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue()).hasSize(1).doesNotContainNull()
.extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class))
.extracting(request -> request.getUser().getExt()).hasSize(1).element(0)
.isEqualTo(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("source", "id",
asList(
ExtUserEidUid.of("id1", null, ExtUserEidUidExt.of(null, "other")),
ExtUserEidUid.of("id2", null, ExtUserEidUidExt.of(null, null)),
ExtUserEidUid.of("id3", null, ExtUserEidUidExt.of(null, null)),
ExtUserEidUid.of("id4", null, ExtUserEidUidExt.of(null, null))),
null)))
.build());
}

@Test
public void makeHttpRequestsShouldCreateUserExtTpIdForFirstLiveintentAndAdserver() {
// given
Expand All @@ -792,9 +877,9 @@ public void makeHttpRequestsShouldCreateUserExtTpIdForFirstLiveintentAndAdserver
final ExtUserEid liveintentUid2 = ExtUserEid.of("liveintent.com", null,
singletonList(ExtUserEidUid.of("liveintentUid2", null, null)), null);
final ExtUserEid adserverUid = ExtUserEid.of("adserver.org", null,
singletonList(ExtUserEidUid.of("adServerUid", null, ExtUserEidUidExt.of("TDID"))), null);
singletonList(ExtUserEidUid.of("adServerUid", null, ExtUserEidUidExt.of("TDID", null))), null);
final ExtUserEid notSpecialSource = ExtUserEid.of("notSpecialSource", null,
singletonList(ExtUserEidUid.of("notSpecialSource", null, ExtUserEidUidExt.of("TDID"))), null);
singletonList(ExtUserEidUid.of("notSpecialSource", null, ExtUserEidUidExt.of("TDID", null))), null);
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(Arrays.asList(liveintentUid1, liveintentUid2, adserverUid, notSpecialSource))
Expand Down Expand Up @@ -897,7 +982,8 @@ public void makeHttpRequestsShouldNotCreateUserExtTpIdWithAdServerEidSourceIfExt
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("adserver.org", null,
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of(null))), null)))
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of(null, null))),
null)))
.build())
.build()),
builder -> builder.video(Video.builder().build()), identity());
Expand All @@ -912,7 +998,7 @@ public void makeHttpRequestsShouldNotCreateUserExtTpIdWithAdServerEidSourceIfExt
.extracting(request -> request.getUser().getExt())
.containsOnly(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("adserver.org", null,
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of(null))), null)))
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of(null, null))), null)))
.build());
}

Expand Down Expand Up @@ -978,7 +1064,8 @@ public void makeHttpRequestsShouldNotCreateUserExtTpIdWithUnknownEidSource() {
final BidRequest bidRequest = givenBidRequest(builder -> builder.user(User.builder()
.ext(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("unknownSource", null,
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of("eidUidId"))),
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of("eidUidId",
null))),
null)))
.build())
.build()),
Expand All @@ -994,7 +1081,8 @@ public void makeHttpRequestsShouldNotCreateUserExtTpIdWithUnknownEidSource() {
.extracting(request -> request.getUser().getExt())
.containsOnly(ExtUser.builder()
.eids(singletonList(ExtUserEid.of("unknownSource", null,
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of("eidUidId"))), null)))
singletonList(ExtUserEidUid.of("id", null, ExtUserEidUidExt.of("eidUidId", null))),
null)))
.build());
}

Expand Down

0 comments on commit 7748869

Please sign in to comment.