Skip to content

Commit ec27779

Browse files
committed
Adapted V3 Identity Map clases to the new endpoint
1 parent 7eade1a commit ec27779

File tree

4 files changed

+216
-150
lines changed

4 files changed

+216
-150
lines changed

src/main/java/com/uid2/client/IdentityMapV3Helper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public EnvelopeV2 createEnvelopeForIdentityMapRequest(IdentityMapV3Input identit
2424
* @param responseString the response body returned by a call to <a href="https://unifiedid.com/docs/endpoints/post-identity-map">/identity/map</a>
2525
* @param envelope the EnvelopeV2 instance returned by {@link #createEnvelopeForIdentityMapRequest}
2626
* @param identityMapInput the same instance that was passed to {@link #createEnvelopeForIdentityMapRequest}.
27-
* @return an IdentityMapResponse instance
27+
* @return an IdentityMapV3Response instance
2828
*/
2929
public IdentityMapV3Response createIdentityMapResponse(String responseString, EnvelopeV2 envelope, IdentityMapV3Input identityMapInput) {
3030
String decryptedResponseString = uid2Helper.decrypt(responseString, envelope.getNonce());

src/main/java/com/uid2/client/IdentityMapV3Input.java

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,99 +2,112 @@
22

33
import com.google.gson.annotations.SerializedName;
44

5-
import java.util.ArrayList;
6-
import java.util.Collections;
7-
import java.util.HashMap;
8-
import java.util.List;
5+
import java.util.*;
96

107
public class IdentityMapV3Input {
118
/**
129
* @param emails a list of normalized or unnormalized email addresses
13-
* @return a IdentityMapInput instance, to be used in {@link IdentityMapHelper#createEnvelopeForIdentityMapRequest}
10+
* @return a IdentityMapV3Input instance, to be used in {@link IdentityMapHelper#createEnvelopeForIdentityMapRequest}
1411
*/
15-
public static IdentityMapV3Input fromEmails(Iterable<String> emails) {
16-
return new IdentityMapV3Input(IdentityType.Email, emails, false);
12+
public static IdentityMapV3Input fromEmails(List<String> emails) {
13+
return new IdentityMapV3Input().withEmails(emails);
1714
}
1815

1916
/**
20-
* @param phones a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-normalization">normalized</a> phone number
21-
* @return an IdentityMapInput instance
17+
* @param hashedEmails a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-normalization">normalized</a> and <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-hash-encoding">hashed</a> email address
18+
* @return an IdentityMapV3Input instance
2219
*/
23-
public static IdentityMapV3Input fromPhones(Iterable<String> phones) {
24-
return new IdentityMapV3Input(IdentityType.Phone, phones, false);
20+
public static IdentityMapV3Input fromHashedEmails(List<String> hashedEmails) {
21+
return new IdentityMapV3Input().withHashedEmails(hashedEmails);
2522
}
2623

2724
/**
28-
* @param hashedEmails a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-normalization">normalized</a> and <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#email-address-hash-encoding">hashed</a> email address
29-
* @return an IdentityMapInput instance
25+
* @param phones a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-normalization">normalized</a> phone number
26+
* @return an IdentityMapV3Input instance
3027
*/
31-
public static IdentityMapV3Input fromHashedEmails(Iterable<String> hashedEmails) {
32-
return new IdentityMapV3Input(IdentityType.Email, hashedEmails, true);
28+
public static IdentityMapV3Input fromPhones(List<String> phones) {
29+
return new IdentityMapV3Input().withPhones(phones);
3330
}
3431

3532
/**
3633
* @param hashedPhones a <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-normalization">normalized</a> and <a href="https://unifiedid.com/docs/getting-started/gs-normalization-encoding#phone-number-hash-encoding">hashed</a> phone number
37-
* @return an IdentityMapInput instance
34+
* @return an IdentityMapV3Input instance
3835
*/
39-
public static IdentityMapV3Input fromHashedPhones(Iterable<String> hashedPhones) {
40-
return new IdentityMapV3Input(IdentityType.Phone, hashedPhones, true);
36+
public static IdentityMapV3Input fromHashedPhones(List<String> hashedPhones) {
37+
return new IdentityMapV3Input().withHashedPhones(hashedPhones);
4138
}
4239

43-
private IdentityMapV3Input(IdentityType identityType, Iterable<String> emailsOrPhones, boolean alreadyHashed) {
44-
if (identityType == IdentityType.Email) {
45-
hashedNormalizedEmails = new ArrayList<>();
46-
for (String email : emailsOrPhones) {
47-
if (alreadyHashed) {
48-
hashedNormalizedEmails.add(new Identity(email));
49-
} else {
50-
String hashedEmail = InputUtil.normalizeAndHashEmail(email);
51-
hashedNormalizedEmails.add(new Identity(hashedEmail));
52-
addHashedToRawDiiMapping(hashedEmail, email);
53-
}
54-
}
55-
} else { //phone
56-
hashedNormalizedPhones = new ArrayList<>();
57-
for (String phone : emailsOrPhones) {
58-
if (alreadyHashed) {
59-
hashedNormalizedPhones.add(new Identity(phone));
60-
} else {
61-
if (!InputUtil.isPhoneNumberNormalized(phone)) {
62-
throw new IllegalArgumentException("phone number is not normalized: " + phone);
63-
}
64-
65-
String hashedNormalizedPhone = InputUtil.getBase64EncodedHash(phone);
66-
addHashedToRawDiiMapping(hashedNormalizedPhone, phone);
67-
hashedNormalizedPhones.add(new Identity(hashedNormalizedPhone));
68-
}
69-
}
40+
private transient final Map<String, List<String>> diiMappings = new HashMap<>();
41+
42+
@SerializedName("email_hash")
43+
private final List<Identity> hashedEmails = new ArrayList<>();
44+
45+
@SerializedName("phone_hash")
46+
private final List<Identity> hashedPhones = new ArrayList<>();
47+
48+
private IdentityMapV3Input() {}
49+
50+
public IdentityMapV3Input withHashedEmails(List<String> hashedEmails) {
51+
for (String hashedEmail : hashedEmails) {
52+
this.hashedEmails.add(new Identity(hashedEmail));
53+
addToDiiMappings(hashedEmail, hashedEmail);
54+
}
55+
return this;
56+
}
57+
58+
public IdentityMapV3Input withHashedPhones(List<String> hashedPhones) {
59+
for (String hashedPhone : hashedPhones) {
60+
this.hashedPhones.add(new Identity(hashedPhone));
61+
addToDiiMappings(hashedPhone, hashedPhone);
7062
}
63+
return this;
7164
}
7265

73-
private void addHashedToRawDiiMapping(String hashedDii, String rawDii) {
74-
hashedDiiToRawDiis.computeIfAbsent(hashedDii, k -> new ArrayList<>()).add(rawDii);
66+
public IdentityMapV3Input withEmails(List<String> emails) {
67+
for (String email : emails) {
68+
String hash = InputUtil.normalizeAndHashEmail(email);
69+
this.hashedEmails.add(new Identity(hash));
70+
addToDiiMappings(hash, email);
71+
}
72+
return this;
7573
}
7674

75+
public IdentityMapV3Input withPhones(List<String> phones) {
76+
for (String phone : phones) {
77+
if (!InputUtil.isPhoneNumberNormalized(phone)) {
78+
throw new IllegalArgumentException("phone number is not normalized: " + phone);
79+
}
7780

78-
List<String> getRawDiis(String identifier) {
79-
final boolean wasInputAlreadyHashed = hashedDiiToRawDiis.isEmpty();
80-
if (wasInputAlreadyHashed)
81-
return Collections.singletonList(identifier);
82-
return hashedDiiToRawDiis.get(identifier);
81+
String hash = InputUtil.getBase64EncodedHash(phone);
82+
this.hashedPhones.add(new Identity(hash));
83+
addToDiiMappings(hash, phone);
84+
}
85+
return this;
8386
}
8487

85-
@SerializedName("email_hash")
86-
private List<Identity> hashedNormalizedEmails;
87-
@SerializedName("phone_hash")
88-
private List<Identity> hashedNormalizedPhones;
88+
private void addToDiiMappings(String hashedDii, String rawDii) {
89+
diiMappings.computeIfAbsent(hashedDii, k -> new ArrayList<>()).add(rawDii);
90+
}
91+
92+
List<String> getRawDiis(String identityType, int i) {
93+
return diiMappings.get(getEncodedDii(identityType, i));
94+
}
95+
96+
private String getEncodedDii(String identityType, int i) {
97+
switch (identityType) {
98+
case "email_hash": return hashedEmails.get(i).identity;
99+
case "phone_hash": return hashedPhones.get(i).identity;
100+
}
101+
throw new Uid2Exception("Unexpected identity type: " + identityType);
102+
}
89103

90-
private final transient HashMap<String, List<String>> hashedDiiToRawDiis = new HashMap<>();
91104

92105
private static class Identity {
93106
@SerializedName("i")
94-
private final String i;
107+
private final String identity;
95108

96109
public Identity(String value) {
97-
this.i = value;
110+
this.identity = value;
98111
}
99112
}
100113
}

src/main/java/com/uid2/client/IdentityMapV3Response.java

Lines changed: 70 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,115 @@
11
package com.uid2.client;
22

33
import com.google.gson.Gson;
4-
import com.google.gson.JsonElement;
5-
import com.google.gson.JsonObject;
64
import com.google.gson.annotations.SerializedName;
75

8-
import java.util.Collections;
96
import java.util.HashMap;
107
import java.util.List;
8+
import java.util.Map;
119

1210
public class IdentityMapV3Response {
1311
IdentityMapV3Response(String response, IdentityMapV3Input identityMapInput) {
14-
JsonObject responseJson = new Gson().fromJson(response, JsonObject.class);
15-
status = responseJson.get("status").getAsString();
12+
ApiResponse apiResponse = new Gson().fromJson(response, ApiResponse.class);
13+
status = apiResponse.status;
1614

1715
if (!isSuccess()) {
1816
throw new Uid2Exception("Got unexpected identity map status: " + status);
1917
}
2018

21-
Gson gson = new Gson();
22-
JsonObject body = getBodyAsJson(responseJson);
23-
24-
Iterable<JsonElement> mapped = getJsonArray(body, "mapped");
25-
for (JsonElement identity : mapped) {
26-
List<String> rawDiis = getRawDiis(identity, identityMapInput);
27-
MappedIdentity mappedIdentity = gson.fromJson(identity, MappedIdentity.class);
28-
for (String rawDii : rawDiis) {
29-
mappedIdentities.put(rawDii, mappedIdentity);
30-
}
31-
}
19+
populateIdentities(apiResponse.body, identityMapInput);
20+
}
3221

33-
Iterable<JsonElement> unmapped = getJsonArray(body, "unmapped");
34-
for (JsonElement identity : unmapped) {
35-
List<String> rawDiis = getRawDiis(identity, identityMapInput);
36-
UnmappedIdentity unmappedIdentity = gson.fromJson(identity, UnmappedIdentity.class);
37-
for (String rawDii : rawDiis) {
38-
unmappedIdentities.put(rawDii, unmappedIdentity);
39-
}
22+
private void populateIdentities(Map<String, List<ApiIdentity>> apiResponse, IdentityMapV3Input identityMapInput) {
23+
for (Map.Entry<String, List<ApiIdentity>> identitiesForType : apiResponse.entrySet()) {
24+
populateIdentitiesForType(identityMapInput, identitiesForType.getKey(), identitiesForType.getValue());
4025
}
4126
}
4227

43-
private static Iterable<JsonElement> getJsonArray(JsonObject body, String header) {
44-
JsonElement jsonElement = body.get(header);
45-
if (jsonElement == null) {
46-
return Collections.emptyList();
28+
private void populateIdentitiesForType(IdentityMapV3Input identityMapInput, String identityType, List<ApiIdentity> identities) {
29+
for (int i = 0; i < identities.size(); i++) {
30+
ApiIdentity apiIdentity = identities.get(i);
31+
List<String> rawDiis = identityMapInput.getRawDiis(identityType, i);
32+
for (String rawDii : rawDiis)
33+
if (apiIdentity.error != null) {
34+
unmappedIdentities.put(rawDii, new UnmappedIdentity(apiIdentity));
35+
} else {
36+
mappedIdentities.put(rawDii, new MappedIdentity(apiIdentity));
37+
}
4738
}
48-
return jsonElement.getAsJsonArray();
4939
}
5040

51-
private List<String> getRawDiis(JsonElement identity, IdentityMapV3Input identityMapInput) {
52-
String identifier = identity.getAsJsonObject().get("identifier").getAsString();
53-
return identityMapInput.getRawDiis(identifier);
41+
private static IdentityMapV3Input getIdentityMapInput(IdentityMapV3Input identityMapInput) {
42+
return identityMapInput;
5443
}
5544

5645
public boolean isSuccess() {
5746
return "success".equals(status);
5847
}
59-
static JsonObject getBodyAsJson(JsonObject jsonResponse) {
60-
return jsonResponse.get("body").getAsJsonObject();
48+
49+
static public class ApiResponse {
50+
@SerializedName("status")
51+
public String status;
52+
53+
@SerializedName("body")
54+
public Map<String, List<ApiIdentity>> body;
55+
}
56+
57+
static public class ApiIdentity {
58+
@SerializedName("u")
59+
public String currentUid;
60+
61+
@SerializedName("p")
62+
public String previousUid;
63+
64+
@SerializedName("r")
65+
public Long refreshFromSeconds;
66+
67+
@SerializedName("e")
68+
public String error;
6169
}
6270

6371
static public class MappedIdentity {
64-
public MappedIdentity(String rawUid, String bucketId) {
65-
this.rawUid = rawUid;
66-
this.bucketId = bucketId;
72+
public MappedIdentity(String currentUid, String previousUid, Long refreshFromSeconds) {
73+
this.currentUid = currentUid;
74+
this.previousUid = previousUid;
75+
this.refreshFromSeconds = refreshFromSeconds;
6776
}
6877

69-
public String getRawUid() {return rawUid;}
70-
public String getBucketId() {return bucketId;}
78+
public MappedIdentity(ApiIdentity apiIdentity) {
79+
this(apiIdentity.currentUid, apiIdentity.previousUid, apiIdentity.refreshFromSeconds);
80+
}
81+
82+
private final String currentUid;
83+
private final String previousUid;
84+
private final Long refreshFromSeconds;
85+
86+
public String getCurrentUid() {
87+
return currentUid;
88+
}
89+
90+
public String getPreviousUid() {
91+
return previousUid;
92+
}
7193

72-
@SerializedName("advertising_id")
73-
private final String rawUid;
74-
@SerializedName("bucket_id")
75-
private final String bucketId;
94+
public Long getRefreshFromSeconds() {
95+
return refreshFromSeconds;
96+
}
7697
}
7798

7899
static public class UnmappedIdentity {
79100
public UnmappedIdentity(String reason) {
80101
this.reason = reason;
81102
}
82103

83-
public String getReason() {return reason;}
104+
public UnmappedIdentity(ApiIdentity apiIdentity) {
105+
this(apiIdentity.error);
106+
}
84107

85108
private final String reason;
109+
110+
public String getReason() {
111+
return reason;
112+
}
86113
}
87114

88115
public HashMap<String, MappedIdentity> getMappedIdentities() {

0 commit comments

Comments
 (0)