27
27
public class UserMetadata {
28
28
static final int MAX_ATTRIBUTES = 64 ;
29
29
static final int MAX_ATTRIBUTE_SIZE = 1024 ;
30
+ static final int MAX_INTERNAL_KEY_SIZE = 8192 ;
30
31
31
32
private String userId = null ;
32
33
private final Map <String , String > attributes = new HashMap <>();
34
+ private final Map <String , String > internalKeys = new HashMap <>();
33
35
34
36
public UserMetadata () {}
35
37
@@ -39,7 +41,7 @@ public String getUserId() {
39
41
}
40
42
41
43
public void setUserId (String identifier ) {
42
- userId = sanitizeAttribute (identifier );
44
+ userId = sanitizeAttribute (identifier , MAX_ATTRIBUTE_SIZE );
43
45
}
44
46
45
47
@ NonNull
@@ -51,18 +53,31 @@ public void setCustomKey(String key, String value) {
51
53
setSyncCustomKeys (
52
54
new HashMap <String , String >() {
53
55
{
54
- put (sanitizeKey ( key ), sanitizeAttribute ( value ) );
56
+ put (key , value );
55
57
}
56
- });
58
+ }, attributes , MAX_ATTRIBUTE_SIZE );
57
59
}
58
60
59
61
public void setCustomKeys (Map <String , String > keysAndValues ) {
60
- setSyncCustomKeys (keysAndValues );
62
+ setSyncCustomKeys (keysAndValues , attributes , MAX_ATTRIBUTE_SIZE );
61
63
}
62
64
63
- /** Gatekeeper function for access to attributes */
64
- private synchronized void setSyncCustomKeys (Map <String , String > keysAndValues ) {
65
- // We want all access to the attributes hashmap to be locked so that there is no way to create
65
+ public Map <String , String > getInternalKeys () {
66
+ return Collections .unmodifiableMap (internalKeys );
67
+ }
68
+
69
+ public void setInternalKey (String key , String value ) {
70
+ setSyncCustomKeys (
71
+ new HashMap <String , String >() {
72
+ {
73
+ put (key , value );
74
+ }
75
+ }, internalKeys , MAX_INTERNAL_KEY_SIZE );
76
+ }
77
+
78
+ /** Gatekeeper function for access to attributes or internalKeys */
79
+ private synchronized void setSyncCustomKeys (Map <String , String > keysAndValues , Map <String , String > keys_map , int maxAttributeSize ) {
80
+ // We want all access to the keys_map hashmap to be locked so that there is no way to create
66
81
// a race condition and add more than MAX_ATTRIBUTES keys.
67
82
68
83
// Update any existing keys first, then add any additional keys
@@ -71,42 +86,42 @@ private synchronized void setSyncCustomKeys(Map<String, String> keysAndValues) {
71
86
72
87
// Split into current and new keys
73
88
for (Map .Entry <String , String > entry : keysAndValues .entrySet ()) {
74
- String key = sanitizeKey (entry .getKey ());
75
- String value = (entry .getValue () == null ) ? "" : sanitizeAttribute (entry .getValue ());
76
- if (attributes .containsKey (key )) {
89
+ String key = sanitizeKey (entry .getKey (), maxAttributeSize );
90
+ String value = (entry .getValue () == null ) ? "" : sanitizeAttribute (entry .getValue (), maxAttributeSize );
91
+ if (keys_map .containsKey (key )) {
77
92
currentKeys .put (key , value );
78
93
} else {
79
94
newKeys .put (key , value );
80
95
}
81
96
}
82
97
83
- attributes .putAll (currentKeys );
98
+ keys_map .putAll (currentKeys );
84
99
85
100
// Add new keys if there is space
86
- if (attributes .size () + newKeys .size () > MAX_ATTRIBUTES ) {
87
- int keySlotsLeft = MAX_ATTRIBUTES - attributes .size ();
101
+ if (keys_map .size () + newKeys .size () > MAX_ATTRIBUTES ) {
102
+ int keySlotsLeft = MAX_ATTRIBUTES - keys_map .size ();
88
103
Logger .getLogger ()
89
104
.v ("Exceeded maximum number of custom attributes (" + MAX_ATTRIBUTES + ")." );
90
105
List <String > newKeyList = new ArrayList <>(newKeys .keySet ());
91
106
newKeys .keySet ().retainAll (newKeyList .subList (0 , keySlotsLeft ));
92
107
}
93
- attributes .putAll (newKeys );
108
+ keys_map .putAll (newKeys );
94
109
}
95
110
96
111
/** Checks that the key is not null then sanitizes it. */
97
- private static String sanitizeKey (String key ) {
112
+ private static String sanitizeKey (String key , int maxAttributeSize ) {
98
113
if (key == null ) {
99
114
throw new IllegalArgumentException ("Custom attribute key must not be null." );
100
115
}
101
- return sanitizeAttribute (key );
116
+ return sanitizeAttribute (key , maxAttributeSize );
102
117
}
103
118
104
119
/** Trims the string and truncates it to MAX_ATTRIBUTE_SIZE. */
105
- private static String sanitizeAttribute (String input ) {
120
+ private static String sanitizeAttribute (String input , int maxAttributeSize ) {
106
121
if (input != null ) {
107
122
input = input .trim ();
108
- if (input .length () > MAX_ATTRIBUTE_SIZE ) {
109
- input = input .substring (0 , MAX_ATTRIBUTE_SIZE );
123
+ if (input .length () > maxAttributeSize ) {
124
+ input = input .substring (0 , maxAttributeSize );
110
125
}
111
126
}
112
127
return input ;
0 commit comments