Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 6b2f967

Browse files
authored
4.1.0 (#127)
1 parent bea66ad commit 6b2f967

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

src/main/java/com/launchdarkly/client/LDUser.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,28 @@ public Builder customNumber(String k, List<Number> vs) {
690690
custom.put(k, array);
691691
return this;
692692
}
693-
693+
694+
/**
695+
* Add a custom attribute with a list of arbitrary JSON values. When set to one of the
696+
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">built-in
697+
* user attribute keys</a>, this custom attribute will be ignored.
698+
*
699+
* @param k the key for the list
700+
* @param vs the values for the attribute
701+
* @return the builder
702+
*/
703+
public Builder customValues(String k, List<JsonElement> vs) {
704+
checkCustomAttribute(k);
705+
JsonArray array = new JsonArray();
706+
for (JsonElement v : vs) {
707+
if (v != null) {
708+
array.add(v);
709+
}
710+
}
711+
custom.put(k, array);
712+
return this;
713+
}
714+
694715
/**
695716
* Add a {@link java.lang.String}-valued custom attribute that will not be sent back to LaunchDarkly.
696717
* When set to one of the
@@ -766,6 +787,21 @@ public Builder privateCustomNumber(String k, List<Number> vs) {
766787
return customNumber(k, vs);
767788
}
768789

790+
/**
791+
* Add a custom attribute with a list of arbitrary JSON values. When set to one of the
792+
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
793+
* built-in user attribute keys</a>, this custom attribute will be ignored. The custom attribute value will not be sent
794+
* back to LaunchDarkly in analytics events.
795+
*
796+
* @param k the key for the list
797+
* @param vs the values for the attribute
798+
* @return the builder
799+
*/
800+
public Builder privateCustomValues(String k, List<JsonElement> vs) {
801+
privateAttrNames.add(k);
802+
return customValues(k, vs);
803+
}
804+
769805
private void checkCustomAttribute(String key) {
770806
for (UserAttribute a : UserAttribute.values()) {
771807
if (a.name().equals(key)) {

src/main/java/com/launchdarkly/client/VersionedDataKind.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
package com.launchdarkly.client;
22

3+
import com.google.common.collect.ImmutableList;
4+
35
/**
46
* The descriptor for a specific kind of {@link VersionedData} objects that may exist in a {@link FeatureStore}.
7+
* You will not need to refer to this type unless you are directly manipulating a {@code FeatureStore}
8+
* or writing your own {@code FeatureStore} implementation. If you are implementing a custom store, for
9+
* maximum forward compatibility you should only refer to {@link VersionedData}, {@link VersionedDataKind},
10+
* and {@link VersionedDataKind#ALL}, and avoid any dependencies on specific type descriptor instances
11+
* or any specific fields of the types they describe.
512
* @since 3.0.0
613
*/
714
public abstract class VersionedDataKind<T extends VersionedData> {
@@ -41,7 +48,9 @@ String getKeyFromStreamApiPath(String path) {
4148
return path.startsWith(getStreamApiPath()) ? path.substring(getStreamApiPath().length()) : null;
4249
}
4350

44-
51+
/**
52+
* The {@link VersionedDataKind} instance that describes feature flag data.
53+
*/
4554
public static VersionedDataKind<FeatureFlag> FEATURES = new VersionedDataKind<FeatureFlag>() {
4655

4756
public String getNamespace() {
@@ -61,6 +70,9 @@ public FeatureFlag makeDeletedItem(String key, int version) {
6170
}
6271
};
6372

73+
/**
74+
* The {@link VersionedDataKind} instance that describes user segment data.
75+
*/
6476
public static VersionedDataKind<Segment> SEGMENTS = new VersionedDataKind<Segment>() {
6577

6678
public String getNamespace() {
@@ -79,4 +91,10 @@ public Segment makeDeletedItem(String key, int version) {
7991
return new Segment.Builder(key).deleted(true).version(version).build();
8092
}
8193
};
94+
95+
/**
96+
* A list of all existing instances of {@link VersionedDataKind}.
97+
* @since 4.1.0
98+
*/
99+
public static Iterable<VersionedDataKind<?>> ALL = ImmutableList.of(FEATURES, SEGMENTS);
82100
}

src/test/java/com/launchdarkly/client/LDUserTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.launchdarkly.client;
22

3+
import com.google.common.collect.ImmutableList;
34
import com.google.gson.Gson;
5+
import com.google.gson.JsonArray;
46
import com.google.gson.JsonElement;
7+
import com.google.gson.JsonObject;
58
import com.google.gson.JsonPrimitive;
69
import com.google.gson.reflect.TypeToken;
710

@@ -10,6 +13,10 @@
1013
import java.lang.reflect.Type;
1114
import java.util.Map;
1215

16+
import static com.launchdarkly.client.TestUtil.jbool;
17+
import static com.launchdarkly.client.TestUtil.jdouble;
18+
import static com.launchdarkly.client.TestUtil.jint;
19+
import static com.launchdarkly.client.TestUtil.js;
1320
import static org.junit.Assert.assertEquals;
1421
import static org.junit.Assert.assertNull;
1522

@@ -233,4 +240,44 @@ public void getValueReturnsNullIfNotFound() {
233240
.build();
234241
assertNull(user.getValueForEvaluation("height"));
235242
}
243+
244+
@Test
245+
public void canAddCustomAttrWithListOfStrings() {
246+
LDUser user = new LDUser.Builder("key")
247+
.customString("foo", ImmutableList.of("a", "b"))
248+
.build();
249+
JsonElement expectedAttr = makeCustomAttrWithListOfValues("foo", js("a"), js("b"));
250+
JsonObject jo = LDConfig.DEFAULT.gson.toJsonTree(user).getAsJsonObject();
251+
assertEquals(expectedAttr, jo.get("custom"));
252+
}
253+
254+
@Test
255+
public void canAddCustomAttrWithListOfNumbers() {
256+
LDUser user = new LDUser.Builder("key")
257+
.customNumber("foo", ImmutableList.<Number>of(new Integer(1), new Double(2)))
258+
.build();
259+
JsonElement expectedAttr = makeCustomAttrWithListOfValues("foo", jint(1), jdouble(2));
260+
JsonObject jo = LDConfig.DEFAULT.gson.toJsonTree(user).getAsJsonObject();
261+
assertEquals(expectedAttr, jo.get("custom"));
262+
}
263+
264+
@Test
265+
public void canAddCustomAttrWithListOfMixedValues() {
266+
LDUser user = new LDUser.Builder("key")
267+
.customValues("foo", ImmutableList.<JsonElement>of(js("a"), jint(1), jbool(true)))
268+
.build();
269+
JsonElement expectedAttr = makeCustomAttrWithListOfValues("foo", js("a"), jint(1), jbool(true));
270+
JsonObject jo = LDConfig.DEFAULT.gson.toJsonTree(user).getAsJsonObject();
271+
assertEquals(expectedAttr, jo.get("custom"));
272+
}
273+
274+
private JsonElement makeCustomAttrWithListOfValues(String name, JsonElement... values) {
275+
JsonObject ret = new JsonObject();
276+
JsonArray a = new JsonArray();
277+
for (JsonElement v: values) {
278+
a.add(v);
279+
}
280+
ret.add(name, a);
281+
return ret;
282+
}
236283
}

0 commit comments

Comments
 (0)