Skip to content

Commit 7795035

Browse files
authored
Merge pull request #1 from launchdarkly/eb/initial
initial version of Java DynamoDB store
2 parents d92cc24 + 6b23c49 commit 7795035

File tree

18 files changed

+1275
-0
lines changed

18 files changed

+1275
-0
lines changed

.circleci/config.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: 2
2+
3+
workflows:
4+
version: 2
5+
test:
6+
jobs:
7+
- build
8+
9+
jobs:
10+
build:
11+
docker:
12+
- image: circleci/java
13+
- image: amazon/dynamodb-local
14+
steps:
15+
- checkout
16+
- run: cp gradle.properties.example gradle.properties
17+
- run: ./gradlew test
18+
- run:
19+
name: Save test results
20+
command: |
21+
mkdir -p ~/junit/;
22+
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \;
23+
when: always
24+
- store_test_results:
25+
path: ~/junit
26+
- store_artifacts:
27+
path: ~/junit

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Change log
2+
3+
All notable changes to the LaunchDarkly Java SDK DynamoDB integration will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).
4+
5+
## [1.0.0] - 2018-12-10
6+
7+
Initial release.

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Contributing to this library
2+
============================
3+
4+
The source code for this library is [here](https://github.com/launchdarkly/java-dynamodb-store). We encourage pull-requests and other contributions from the community. Since this library is meant to be used in conjunction with the LaunchDarkly Java SDK, you may want to look at the [Java SDK source code](https://github.com/launchdarkly/java-client) and our [SDK contributor's guide](http://docs.launchdarkly.com/docs/sdk-contributors-guide).

LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2018 Catamorphic, Co.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
LaunchDarkly SDK for Java - DynamoDB integration
2+
================================================
3+
4+
[![Circle CI](https://circleci.com/gh/launchdarkly/java-dynamodb-store.svg?style=shield)](https://circleci.com/gh/launchdarkly/java-dynamodb-store)
5+
[![Javadocs](http://javadoc.io/badge/com.launchdarkly/launchdarkly-client.svg)](http://javadoc.io/doc/com.launchdarkly/launchdarkly-client-dynamodb-store)
6+
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Flaunchdarkly%2Fjava-dynamodb-store.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Flaunchdarkly%2Fjava-dynamodb-store?ref=badge_shield)
7+
8+
This library provides a DynamoDB-backed persistence mechanism (feature store) for the [LaunchDarkly Java SDK](https://github.com/launchdarkly/java-client), replacing the default in-memory feature store.
9+
10+
The minimum version of the LaunchDarkly Java SDK for use with this library is 4.6.0. It is compatible with Java 7 and above.
11+
12+
It uses version 1.11 of the AWS SDK for Java; a future release will use version 2.x.
13+
14+
For more information, see also: [Using a persistent feature store](https://docs.launchdarkly.com/v2.0/docs/using-a-persistent-feature-store).
15+
16+
Quick setup
17+
-----------
18+
19+
This assumes that you have already installed the LaunchDarkly Java SDK.
20+
21+
0. Add this library to your project:
22+
23+
<dependency>
24+
<groupId>com.launchdarkly</groupId>
25+
<artifactId>launchdarkly-client-dynamodb-store</artifactId>
26+
<version>1.0.0</version>
27+
</dependency>
28+
29+
1. If you do not already have the AWS SDK in your project, add the DynamoDB part of it. (This needs to be added separately, rather than being included in the LaunchDarkly jar, because AWS classes are exposed in the public interface.)
30+
31+
<dependency>
32+
<groupId>com.amazonaws</groupId>
33+
<artifactId>com.amazonaws:aws-java-sdk-dynamodb</artifactId>
34+
<version>1.11.327</version>
35+
</dependency>
36+
37+
2. Import the LaunchDarkly package and the package for this library:
38+
39+
import com.launchdarkly.client.*;
40+
import com.launchdarkly.client.dynamodb.*;
41+
42+
3. When configuring your SDK client, add the DynamoDB feature store:
43+
44+
DynamoDbFeatureStoreBuilder store = DatabaseComponents.dynamoDbFeatureStore("my-table-name")
45+
.caching(FeatureStoreCaching.enabled().ttlSeconds(30));
46+
47+
LDConfig config = new LDConfig.Builder()
48+
.featureStoreFactory(store)
49+
.build();
50+
51+
LDClient client = new LDClient("YOUR SDK KEY", config);
52+
53+
The specified table must already exist in DynamoDB. It must have a partition key called "namespace" and a sort key called "key".
54+
55+
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:
56+
57+
DynamoDbFeatureStoreBuilder store = DatabaseComponents.dynamoDbFeatureStore("my-table-name")
58+
.existingClient(myDynamoDbClientInstance);
59+
60+
Caching behavior
61+
----------------
62+
63+
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:
64+
65+
DynamoDbFeatureStoreBuilder store = DatabaseComponents.dynamoDbFeatureStore("my-table-name")
66+
.caching(FeatureStoreCaching.disabled());
67+
68+
For other ways to control the behavior of the cache, see `DynamoDbFeatureStoreBuilder.caching()`.
69+
70+
About LaunchDarkly
71+
-----------
72+
73+
* LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely. We allow you to easily flag your features and manage them from the LaunchDarkly dashboard. With LaunchDarkly, you can:
74+
* Roll out a new feature to a subset of your users (like a group of users who opt-in to a beta tester group), gathering feedback and bug reports from real-world use cases.
75+
* Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?).
76+
* Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file.
77+
* Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). Disable parts of your application to facilitate maintenance, without taking everything offline.
78+
* LaunchDarkly provides feature flag SDKs for
79+
* [Java](http://docs.launchdarkly.com/docs/java-sdk-reference "Java SDK")
80+
* [JavaScript](http://docs.launchdarkly.com/docs/js-sdk-reference "LaunchDarkly JavaScript SDK")
81+
* [PHP](http://docs.launchdarkly.com/docs/php-sdk-reference "LaunchDarkly PHP SDK")
82+
* [Python](http://docs.launchdarkly.com/docs/python-sdk-reference "LaunchDarkly Python SDK")
83+
* [Go](http://docs.launchdarkly.com/docs/go-sdk-reference "LaunchDarkly Go SDK")
84+
* [Node.JS](http://docs.launchdarkly.com/docs/node-sdk-reference "LaunchDarkly Node SDK")
85+
* [Electron](http://docs.launchdarkly.com/docs/electron-sdk-reference "LaunchDarkly Electron SDK")
86+
* [.NET](http://docs.launchdarkly.com/docs/dotnet-sdk-reference "LaunchDarkly .Net SDK")
87+
* [Ruby](http://docs.launchdarkly.com/docs/ruby-sdk-reference "LaunchDarkly Ruby SDK")
88+
* [iOS](http://docs.launchdarkly.com/docs/ios-sdk-reference "LaunchDarkly iOS SDK")
89+
* [Android](http://docs.launchdarkly.com/docs/android-sdk-reference "LaunchDarkly Android SDK")
90+
* Explore LaunchDarkly
91+
* [launchdarkly.com](http://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information
92+
* [docs.launchdarkly.com](http://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDKs
93+
* [apidocs.launchdarkly.com](http://apidocs.launchdarkly.com/ "LaunchDarkly API Documentation") for our API documentation
94+
* [blog.launchdarkly.com](http://blog.launchdarkly.com/ "LaunchDarkly Blog Documentation") for the latest product updates
95+
* [Feature Flagging Guide](https://github.com/launchdarkly/featureflags/ "Feature Flagging Guide") for best practices and strategies
96+

build.gradle

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
apply plugin: 'java'
2+
apply plugin: 'maven-publish'
3+
apply plugin: 'signing'
4+
apply plugin: 'idea'
5+
apply plugin: 'com.github.johnrengelman.shadow'
6+
apply plugin: 'io.codearte.nexus-staging'
7+
8+
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
9+
10+
configurations.all {
11+
// check for updates every build for dependencies with: 'changing: true'
12+
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
13+
}
14+
15+
repositories {
16+
mavenLocal()
17+
// Before LaunchDarkly release artifacts get synced to Maven Central they are here along with snapshots:
18+
maven { url "https://oss.sonatype.org/content/groups/public/" }
19+
mavenCentral()
20+
}
21+
22+
allprojects {
23+
group = 'com.launchdarkly'
24+
version = "${version}"
25+
sourceCompatibility = 1.7
26+
targetCompatibility = 1.7
27+
}
28+
29+
ext {
30+
sdkBasePackage = "com.launchdarkly.client.dynamodb"
31+
sdkBaseName = "launchdarkly-client-dynamodb-store"
32+
}
33+
34+
ext.libraries = [:]
35+
36+
// Add dependencies to "libraries.internal" that are not exposed in our public API. These
37+
// will be embedded with shaded names in the uberjar.
38+
libraries.internal = [
39+
"com.google.guava:guava:19.0"
40+
]
41+
42+
// Add dependencies to "libraries.external" that are exposed in our public API, or that have
43+
// global state that must be shared between the SDK and the caller. These are not embedded
44+
// in the uberjar; the caller must provide them on the classpath at runtime.
45+
libraries.external = [
46+
"com.launchdarkly:launchdarkly-client:4.6.0-SNAPSHOT",
47+
"com.amazonaws:aws-java-sdk-dynamodb:1.11.327",
48+
"org.slf4j:slf4j-api:1.7.21"
49+
]
50+
51+
// Add dependencies to "libraries.test" that are used only in unit tests.
52+
libraries.test = [
53+
"org.hamcrest:hamcrest-all:1.3",
54+
"junit:junit:4.12",
55+
"ch.qos.logback:logback-classic:1.1.7",
56+
"com.launchdarkly:launchdarkly-client:4.6.0-SNAPSHOT:test" // our unit tests use helper classes from the SDK
57+
]
58+
59+
dependencies {
60+
implementation libraries.internal
61+
compileClasspath libraries.external
62+
runtime libraries.internal
63+
testImplementation libraries.test, libraries.internal, libraries.external
64+
65+
// Unlike what the name might suggest, the "shadow" configuration specifies dependencies that
66+
// should *not* be shaded by the Shadow plugin when we build our shaded jars.
67+
shadow libraries.external
68+
}
69+
70+
buildscript {
71+
repositories {
72+
jcenter()
73+
mavenCentral()
74+
mavenLocal()
75+
}
76+
dependencies {
77+
classpath 'org.ajoberstar:gradle-git:1.5.0-rc.1'
78+
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
79+
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.8.0"
80+
}
81+
}
82+
83+
task sourcesJar(type: Jar, dependsOn: classes) {
84+
classifier = 'sources'
85+
from sourceSets.main.allSource
86+
}
87+
88+
task javadocJar(type: Jar, dependsOn: javadoc) {
89+
classifier = 'javadoc'
90+
from javadoc.destinationDir
91+
}
92+
93+
shadowJar {
94+
baseName = sdkBaseName
95+
96+
// No classifier means that the shaded jar becomes the default artifact
97+
classifier = ''
98+
99+
manifest {
100+
attributes("Implementation-Version": version)
101+
}
102+
}
103+
104+
task relocateShadowJar(type: ConfigureShadowRelocation) {
105+
target = tasks.shadowJar
106+
prefix = "com.launchdarkly.shaded"
107+
}
108+
109+
tasks.shadowJar.dependsOn tasks.relocateShadowJar
110+
111+
artifacts {
112+
archives sourcesJar, javadocJar, shadowJar
113+
}
114+
115+
test {
116+
testLogging {
117+
events "passed", "skipped", "failed", "standardOut", "standardError"
118+
showStandardStreams = true
119+
exceptionFormat = 'full'
120+
}
121+
}
122+
123+
idea {
124+
module {
125+
downloadJavadoc = true
126+
downloadSources = true
127+
}
128+
}
129+
130+
nexusStaging {
131+
packageGroup = "com.launchdarkly"
132+
}
133+
134+
def pomConfig = {
135+
name 'LaunchDarkly Java SDK DynamoDB integration'
136+
packaging 'jar'
137+
url 'https://github.com/launchdarkly/java-dynamodb-store'
138+
139+
licenses {
140+
license {
141+
name 'The Apache License, Version 2.0'
142+
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
143+
}
144+
}
145+
146+
developers {
147+
developer {
148+
id 'jkodumal'
149+
name 'John Kodumal'
150+
email 'john@launchdarkly.com'
151+
}
152+
}
153+
154+
scm {
155+
connection 'scm:git:git://github.com/launchdarkly/java-dynamodb-store.git'
156+
developerConnection 'scm:git:ssh:git@github.com:launchdarkly/java-dynamodb-store.git'
157+
url 'https://github.com/launchdarkly/java-dynamodb-store'
158+
}
159+
}
160+
161+
publishing {
162+
publications {
163+
shadow(MavenPublication) { publication ->
164+
project.shadow.component(publication)
165+
166+
artifactId = sdkBaseName
167+
artifact sourcesJar
168+
artifact javadocJar
169+
170+
pom.withXml {
171+
def root = asNode()
172+
root.appendNode('description', 'DynamoDB-backed feature store for the LaunchDarkly Java SDK')
173+
asNode().children().last() + pomConfig
174+
}
175+
}
176+
}
177+
repositories {
178+
mavenLocal()
179+
maven {
180+
def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
181+
def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
182+
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
183+
credentials {
184+
username ossrhUsername
185+
password ossrhPassword
186+
}
187+
}
188+
}
189+
}
190+
191+
signing {
192+
sign publishing.publications.shadow
193+
}

gradle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version=1.0.0-SNAPSHOT
2+
ossrhUsername=
3+
ossrhPassword=

gradle.properties.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
githubUser = YOUR_GITHUB_USERNAME
2+
githubPassword = YOUR_GITHUB_PASSWORD
3+
signing.keyId = 5669D902
4+
signing.password = SIGNING_PASSWORD
5+
signing.secretKeyRingFile = SECRET_RING_FILE
6+
ossrhUsername = launchdarkly
7+
ossrhPassword = OSSHR_PASSWORD

gradle/wrapper/gradle-wrapper.jar

53.4 KB
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
zipStoreBase=GRADLE_USER_HOME
4+
zipStorePath=wrapper/dists
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip

0 commit comments

Comments
 (0)