Skip to content

Commit 4020b1f

Browse files
authored
use newer API for Java SDK 4.12.0 and above (#7)
1 parent 2d7ff2e commit 4020b1f

File tree

11 files changed

+361
-117
lines changed

11 files changed

+361
-117
lines changed

README.md

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
[![Circle CI](https://circleci.com/gh/launchdarkly/java-server-sdk-dynamodb.svg?style=shield)](https://circleci.com/gh/launchdarkly/java-server-sdk-dynamodb)
44
[![Javadocs](http://javadoc.io/badge/com.launchdarkly/launchdarkly-java-server-sdk-dynamodb-store.svg)](http://javadoc.io/doc/com.launchdarkly/launchdarkly-java-server-sdk-dynamodb-store)
55

6-
This library provides a DynamoDB-backed persistence mechanism (feature store) for the [LaunchDarkly Java SDK](https://github.com/launchdarkly/java-server-sdk), replacing the default in-memory feature store.
6+
This library provides a DynamoDB-backed persistence mechanism (data store) for the [LaunchDarkly Java SDK](https://github.com/launchdarkly/java-server-sdk), replacing the default in-memory data store.
77

8-
This version of the library requires at least version 2.1 of the AWS SDK for Java, and at least version 4.6.4 of the LaunchDarkly Java SDK. The minimum Java version is 8 (because that is the minimum Java version of the AWS SDK 2.x). If you need to use Java 7, or if you are already using AWS SDK 1.x for some other purpose, you can use the 1.x releases of this library (which are developed on the "aws-v1" branch of the repository).
8+
This version of the library requires at least version 2.1 of the AWS SDK for Java, and at least version 4.12.0 of the LaunchDarkly Java SDK. The minimum Java version is 8 (because that is the minimum Java version of the AWS SDK 2.x). If you need to use Java 7, or if you are already using AWS SDK 1.x for some other purpose, you can use the 1.x releases of this library (which are developed on the "aws-v1" branch of the repository).
99

1010
See the [API documentation](https://launchdarkly.github.io/java-server-sdk-dynamodb) for details on classes and methods.
1111

12-
For more information, see also: [Using a persistent feature store](https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store).
12+
For more information, see also: [Using a persistent data store](https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store).
1313

1414
## Quick setup
1515

@@ -36,32 +36,42 @@ This assumes that you have already installed the LaunchDarkly Java SDK.
3636
4. Import the LaunchDarkly package and the package for this library:
3737

3838
import com.launchdarkly.client.*;
39-
import com.launchdarkly.client.dynamodb.*;
39+
import com.launchdarkly.client.integrations.*;
4040

4141
5. When configuring your SDK client, add the DynamoDB feature store:
4242

43-
DynamoDbFeatureStoreBuilder store = DynamoDbComponents.dynamoDbFeatureStore("my-table-name")
44-
.caching(FeatureStoreCacheConfig.enabled().ttlSeconds(30));
43+
DynamoDbDataStoreBuilder dynamoDbStore = DynamoDb.dataStore("my-table-name");
4544
4645
LDConfig config = new LDConfig.Builder()
47-
.featureStoreFactory(store)
46+
.dataStore(Components.persistentDataStore(dynamoDbStore))
4847
.build();
4948
5049
LDClient client = new LDClient("YOUR SDK KEY", config);
5150

52-
By default, the DynamoDB client will try to get your AWS credentials and region name from environment variables and/or local configuration files, as described in the AWS SDK documentation. There are methods in `DynamoDBFeatureStoreBuilder` for changing the configuration options. Alternatively, if you already have a fully configured DynamoDB client object, you can tell LaunchDarkly to use that:
51+
By default, the DynamoDB client will try to get your AWS credentials and region name from environment variables and/or local configuration files, as described in the AWS SDK documentation. There are methods in `DynamoDbDataStoreBuilder` for changing the configuration options. Alternatively, if you already have a fully configured DynamoDB client object, you can tell LaunchDarkly to use that:
5352

54-
DynamoDbFeatureStoreBuilder store = DynamoDbComponents.dynamoDbFeatureStore("my-table-name")
53+
DynamoDbDataStoreBuilder dynamoDbStore = DynamoDb.dataStore("my-table-name")
5554
.existingClient(myDynamoDbClientInstance);
5655

5756
## Caching behavior
5857

5958
To reduce traffic to DynamoDB, there is an optional in-memory cache that retains the last known data for a configurable amount of time. This is on by default; to turn it off (and guarantee that the latest feature flag data will always be retrieved from DynamoDB for every flag evaluation), configure the store as follows:
6059

61-
DynamoDbFeatureStoreBuilder store = DynamoDbComponents.dynamoDbFeatureStore("my-table-name")
62-
.caching(FeatureStoreCacheConfig.disabled());
60+
By default, for any persistent data store, the Java SDK uses an in-memory cache to reduce traffic to the database; this retains the last known data for a configurable amount of time. To change the caching behavior or disable caching, use the `PersistentDataStoreBuilder` methods:
6361

64-
For other ways to control the behavior of the cache, see `DynamoDbFeatureStoreBuilder.caching()`.
62+
LDConfig configWithLongerCacheTtl = new LDConfig.Builder()
63+
.dataStore(
64+
Components.persistentDataStore(dynamoDbStore).cacheSeconds(60)
65+
)
66+
.build();
67+
68+
LDConfig configWithNoCaching = new LDConfig.Builder()
69+
.dataStore(
70+
Components.persistentDataStore(dynamoDbStore).noCaching()
71+
)
72+
.build();
73+
74+
For other ways to control the behavior of the cache, see `PersistentDataStoreBuilder` in the Java SDK.
6575

6676
## About LaunchDarkly
6777

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ libraries.internal = [
4444
// global state that must be shared between the SDK and the caller. These are not embedded
4545
// in the uberjar; the caller must provide them on the classpath at runtime.
4646
libraries.external = [
47-
"com.launchdarkly:launchdarkly-java-server-sdk:4.6.4",
47+
"com.launchdarkly:launchdarkly-java-server-sdk:4.12.0",
4848
"software.amazon.awssdk:dynamodb:2.10.32",
4949
"org.slf4j:slf4j-api:1.7.21"
5050
]
@@ -54,7 +54,7 @@ libraries.test = [
5454
"org.hamcrest:hamcrest-all:1.3",
5555
"junit:junit:4.12",
5656
"ch.qos.logback:logback-classic:1.1.7",
57-
"com.launchdarkly:launchdarkly-java-server-sdk:4.6.4:test" // our unit tests use helper classes from the SDK
57+
"com.launchdarkly:launchdarkly-java-server-sdk:4.12.0:test" // our unit tests use helper classes from the SDK
5858
]
5959

6060
dependencies {

src/main/java/com/launchdarkly/client/dynamodb/DynamoDbComponents.java

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

33
/**
4-
* Entry point for using the DynamoDB feature store.
4+
* Deprecated entry point for the DynamoDB data store. This is for use with the older feature store API
5+
* in Java SDK 4.11.x and below. For Java SDK 4.12 and above, use {@link com.launchdarkly.client.integrations.DynamoDb}.
6+
*
7+
* @deprecated Use {@link com.launchdarkly.client.integrations.DynamoDb}.
58
*/
9+
@Deprecated
610
public abstract class DynamoDbComponents {
711
/**
812
* Creates a builder for a DynamoDB feature store. You can modify any of the store's properties with
@@ -12,7 +16,9 @@ public abstract class DynamoDbComponents {
1216
* @param tableName The table name in DynamoDB. This table must already exist (see package
1317
* documentation).
1418
* @return the builder
19+
* @deprecated Use {@link com.launchdarkly.client.integrations.DynamoDb#dataStore(String)}
1520
*/
21+
@Deprecated
1622
public static DynamoDbFeatureStoreBuilder dynamoDbFeatureStore(String tableName) {
1723
return new DynamoDbFeatureStoreBuilder(tableName);
1824
}
Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,44 @@
11
package com.launchdarkly.client.dynamodb;
22

3+
import com.launchdarkly.client.Components;
34
import com.launchdarkly.client.FeatureStore;
45
import com.launchdarkly.client.FeatureStoreCacheConfig;
56
import com.launchdarkly.client.FeatureStoreFactory;
6-
import com.launchdarkly.client.utils.CachingStoreWrapper;
7+
import com.launchdarkly.client.LDConfig;
8+
import com.launchdarkly.client.integrations.DynamoDbDataStoreBuilder;
9+
import com.launchdarkly.client.integrations.PersistentDataStoreBuilder;
10+
import com.launchdarkly.client.interfaces.DiagnosticDescription;
11+
import com.launchdarkly.client.value.LDValue;
712

813
import java.net.URI;
914

1015
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
1116
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
1217
import software.amazon.awssdk.regions.Region;
1318
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
14-
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;
1519

1620
/**
17-
* Builder/factory class for the DynamoDB feature store.
21+
* Deprecated builder class for the DynamoDB-based persistent data store.
1822
* <p>
19-
* Create this builder by calling {@link DynamoDbComponents#dynamoDbFeatureStore(String)}, then
20-
* optionally modify its properties with builder methods, and then include it in your client
21-
* configuration with {@link com.launchdarkly.client.LDConfig.Builder#featureStoreFactory(FeatureStoreFactory)}.
22-
* <p>
23-
* The AWS SDK provides many configuration options for a DynamoDB client. This class has
24-
* corresponding methods for some of the most commonly used ones. If you need more sophisticated
25-
* control over the DynamoDB client, you can construct one of your own and pass it in with the
26-
* {@link #existingClient(DynamoDbClient)} method.
23+
* The replacement for this class is {@link com.launchdarkly.client.integrations.DynamoDb}.
24+
* This class is retained for backward compatibility with older Java SDK versions and will be removed in a
25+
* future version.
26+
*
27+
* @deprecated Use {@link com.launchdarkly.client.integrations.DynamoDb#dataStore(String)}
2728
*/
28-
public class DynamoDbFeatureStoreBuilder implements FeatureStoreFactory {
29-
private final String tableName;
30-
31-
private String prefix;
32-
private DynamoDbClient existingClient;
33-
private DynamoDbClientBuilder clientBuilder;
34-
35-
private FeatureStoreCacheConfig caching = FeatureStoreCacheConfig.DEFAULT;
29+
@Deprecated
30+
public class DynamoDbFeatureStoreBuilder implements FeatureStoreFactory, DiagnosticDescription {
31+
private final PersistentDataStoreBuilder wrappedOuterBuilder;
32+
private final DynamoDbDataStoreBuilder wrappedBuilder;
3633

3734
DynamoDbFeatureStoreBuilder(String tableName) {
38-
this.tableName = tableName;
39-
clientBuilder = DynamoDbClient.builder();
35+
wrappedBuilder = com.launchdarkly.client.integrations.DynamoDb.dataStore(tableName);
36+
wrappedOuterBuilder = Components.persistentDataStore(wrappedBuilder);
4037
}
4138

4239
@Override
43-
public FeatureStore createFeatureStore() {
44-
DynamoDbClient client = (existingClient != null) ? existingClient : clientBuilder.build();
45-
DynamoDbFeatureStoreCore core = new DynamoDbFeatureStoreCore(client, tableName, prefix);
46-
CachingStoreWrapper wrapper = CachingStoreWrapper.builder(core).caching(caching).build();
47-
return wrapper;
40+
public FeatureStore createFeatureStore() {
41+
return wrappedOuterBuilder.createFeatureStore();
4842
}
4943

5044
/**
@@ -54,7 +48,7 @@ public FeatureStore createFeatureStore() {
5448
* @return the builder
5549
*/
5650
public DynamoDbFeatureStoreBuilder clientOverrideConfiguration(ClientOverrideConfiguration config) {
57-
clientBuilder.overrideConfiguration(config);
51+
wrappedBuilder.clientOverrideConfiguration(config);
5852
return this;
5953
}
6054

@@ -66,7 +60,7 @@ public DynamoDbFeatureStoreBuilder clientOverrideConfiguration(ClientOverrideCon
6660
* @return the builder
6761
*/
6862
public DynamoDbFeatureStoreBuilder credentials(AwsCredentialsProvider credentialsProvider) {
69-
clientBuilder.credentialsProvider(credentialsProvider);
63+
wrappedBuilder.credentials(credentialsProvider);
7064
return this;
7165
}
7266

@@ -79,7 +73,7 @@ public DynamoDbFeatureStoreBuilder credentials(AwsCredentialsProvider credential
7973
* @return the builder
8074
*/
8175
public DynamoDbFeatureStoreBuilder endpoint(URI endpointUri) {
82-
clientBuilder.endpointOverride(endpointUri);
76+
wrappedBuilder.endpoint(endpointUri);
8377
return this;
8478
}
8579

@@ -91,7 +85,7 @@ public DynamoDbFeatureStoreBuilder endpoint(URI endpointUri) {
9185
* @return the builder
9286
*/
9387
public DynamoDbFeatureStoreBuilder region(Region region) {
94-
clientBuilder.region(region);
88+
wrappedBuilder.region(region);
9589
return this;
9690
}
9791

@@ -104,7 +98,7 @@ public DynamoDbFeatureStoreBuilder region(Region region) {
10498
* @return the builder
10599
*/
106100
public DynamoDbFeatureStoreBuilder prefix(String prefix) {
107-
this.prefix = prefix;
101+
wrappedBuilder.prefix(prefix);
108102
return this;
109103
}
110104

@@ -117,7 +111,7 @@ public DynamoDbFeatureStoreBuilder prefix(String prefix) {
117111
* @return the builder
118112
*/
119113
public DynamoDbFeatureStoreBuilder existingClient(DynamoDbClient existingClient) {
120-
this.existingClient = existingClient;
114+
wrappedBuilder.existingClient(existingClient);
121115
return this;
122116
}
123117

@@ -130,7 +124,13 @@ public DynamoDbFeatureStoreBuilder existingClient(DynamoDbClient existingClient)
130124
* @return the builder
131125
*/
132126
public DynamoDbFeatureStoreBuilder caching(FeatureStoreCacheConfig caching) {
133-
this.caching = caching;
127+
wrappedOuterBuilder.cacheTime(caching.getCacheTime(), caching.getCacheTimeUnit());
128+
wrappedOuterBuilder.staleValuesPolicy(caching.getStaleValuesPolicy().toNewEnum());
134129
return this;
135130
}
131+
132+
@Override
133+
public LDValue describeConfiguration(LDConfig config) {
134+
return LDValue.of("DynamoDB");
135+
}
136136
}
Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,4 @@
11
/**
2-
* This package provides a DynamoDB-backed feature store for the LaunchDarkly Java SDK.
3-
* <p>
4-
* For more details about how and why you can use a persistent feature store, see:
5-
* https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store
6-
* <p>
7-
* To use the DynamoDB feature store with the LaunchDarkly client, you will first obtain a
8-
* builder by calling {@link com.launchdarkly.client.dynamodb.DynamoDbComponents#dynamoDbFeatureStore(String)}, then optionally
9-
* modify its properties, and then include it in your client configuration. For example:
10-
*
11-
* <pre>
12-
* import com.launchdarkly.client.*;
13-
* import com.launchdarkly.client.dynamodb.*;
14-
15-
* DynamoDbFeatureStoreBuilder store = DatabaseComponents.dynamoDbFeatureStore("my-table-name")
16-
* .caching(FeatureStoreCacheConfig.enabled().ttlSeconds(30));
17-
* LDConfig config = new LDConfig.Builder()
18-
* .featureStoreFactory(store)
19-
* .build();
20-
* </pre>
21-
*
22-
* Note that the specified table must already exist in DynamoDB. It must have a partition key
23-
* of "namespace", and a sort key of "key".
24-
* <p>
25-
* By default, the feature store uses a basic DynamoDB client configuration that takes its
26-
* AWS credentials and region from AWS environment variables and/or local configuration files.
27-
* There are options in the builder for changing some configuration options, or you can
28-
* configure the DynamoDB client yourself and pass it to the builder with
29-
* {@link com.launchdarkly.client.dynamodb.DynamoDbFeatureStoreBuilder#existingClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient)}.
30-
* <p>
31-
* If you are using the same DynamoDB table as a feature store for multiple LaunchDarkly
32-
* environments, use the {@link com.launchdarkly.client.dynamodb.DynamoDbFeatureStoreBuilder#prefix(String)}
33-
* option and choose a different prefix string for each, so they will not interfere with each
34-
* other's data.
2+
* Deprecated package replaced by {@link com.launchdarkly.client.integrations.DynamoDb}.
353
*/
364
package com.launchdarkly.client.dynamodb;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.launchdarkly.client.integrations;
2+
3+
/**
4+
* Integration between the LaunchDarkly SDK and DynamoDB.
5+
* <p>
6+
* This API uses the persistent data store model that was introduced in version 4.12.0 of the LaunchDarkly Java SDK.
7+
* If you are using an older Java SDK version, use {@link com.launchdarkly.client.dynamodb.DynamoDbComponents}.
8+
*
9+
* @since 2.1.0
10+
*/
11+
public abstract class DynamoDb {
12+
/**
13+
* Returns a builder object for creating a DynamoDB-backed data store.
14+
* <p>
15+
* This object can be modified with {@link DynamoDbDataStoreBuilder} methods for any desired
16+
* custom DynamoDB options. Then, pass it to
17+
* {@link com.launchdarkly.client.Components#persistentDataStore(com.launchdarkly.client.interfaces.PersistentDataStoreFactory)}
18+
* and set any desired caching options. Finally, pass the result to
19+
* {@link com.launchdarkly.client.LDConfig.Builder#dataStore(com.launchdarkly.client.FeatureStoreFactory)}.
20+
* For example:
21+
*
22+
* <pre><code>
23+
* LDConfig config = new LDConfig.Builder()
24+
* .dataStore(
25+
* Components.persistentDataStore(
26+
* DynamoDb.dataStore("my-table-name")
27+
* ).cacheSeconds(15)
28+
* )
29+
* .build();
30+
* </code></pre>
31+
*
32+
* Note that the specified table must already exist in DynamoDB. It must have a partition key
33+
* of "namespace", and a sort key of "key".
34+
* <p>
35+
* By default, the data store uses a basic DynamoDB client configuration that takes its
36+
* AWS credentials and region from AWS environment variables and/or local configuration files.
37+
* There are options in the builder for changing some configuration options, or you can
38+
* configure the DynamoDB client yourself and pass it to the builder with
39+
* {@link DynamoDbDataStoreBuilder#existingClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient)}.
40+
* <p>
41+
* If you are using the same DynamoDB table as a feature store for multiple LaunchDarkly
42+
* environments, use the {@link DynamoDbDataStoreBuilder#prefix(String)} option and choose a
43+
* different prefix string for each, so they will not interfere with each other's data.
44+
*
45+
* @param tableName the table name in DynamoDB (must already exist)
46+
* @return a data store configuration object
47+
*/
48+
public static DynamoDbDataStoreBuilder dataStore(String tableName) {
49+
return new DynamoDbDataStoreBuilder(tableName);
50+
}
51+
}

0 commit comments

Comments
 (0)