Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip eids of certain type #926

Merged
merged 2 commits into from
Sep 24, 2020
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
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