Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.

Commit 673fba0

Browse files
committed
Move AWS grails 3 plugins into a single multi-project build (Work in Progress)
1 parent fc8adf7 commit 673fba0

File tree

123 files changed

+10919
-1966
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+10919
-1966
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ plugin.xml
2020
*.sha1
2121

2222
# "temporary" build files
23-
/target
24-
/build
23+
target
24+
build
2525
.gradle
2626
.nb-gradle
2727
*.iml

aws-sdk-dynamodb/README.md

+287
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
Grails AWS SDK DynamoDB Plugin
2+
==============================
3+
4+
[![Build Status](https://travis-ci.org/agorapulse/grails-aws-sdk-dynamodb.svg?branch=master)](https://travis-ci.org/agorapulse/grails-aws-sdk-dynamodb)
5+
[![Download](https://api.bintray.com/packages/agorapulse/plugins/aws-sdk-dynamodb/images/download.svg)](https://bintray.com/agorapulse/plugins/aws-sdk-dynamodb/_latestVersion)
6+
7+
The [AWS SDK Plugins for Grails3](https://medium.com/@benorama/aws-sdk-plugins-for-grails-3-cc7f910fdc0d#.5gdwdxei3) are a suite of plugins that adds support for the [Amazon Web Services](http://aws.amazon.com/) infrastructure services.
8+
9+
The aim is to to get you started quickly by providing friendly lightweight utility [Grails](http://grails.org) service wrappers, around the official [AWS SDK for Java](http://aws.amazon.com/sdkforjava/) (which is great but very “java-esque”).
10+
See [this article](https://medium.com/@benorama/aws-sdk-plugins-for-grails-3-cc7f910fdc0d#.5gdwdxei3) for more info.
11+
12+
The following services are currently supported:
13+
14+
* [AWS SDK DynamoDB Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-dynamodb)
15+
* [AWS SDK Kinesis Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-kinesis)
16+
* [AWS SDK S3 Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-s3)
17+
* [AWS SDK SES Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-ses)
18+
* [AWS SDK SNS Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-sns)
19+
* [AWS SDK SQS Grails Plugin](http://github.com/agorapulse/grails-aws-sdk-sqs)
20+
21+
# Introduction
22+
23+
This plugin adds support for [Amazon DynamoDB](https://aws.amazon.com/dynamodb/), a fast and flexible NoSQL database service for all applications that need consistent, single-digit millisecond latency at any scale.
24+
It is a fully managed cloud database and supports both document and key-value store models.
25+
26+
27+
# Installation
28+
29+
Add plugin dependency to your `build.gradle`:
30+
31+
```groovy
32+
dependencies {
33+
...
34+
compile 'org.grails.plugins:aws-sdk-dynamodb:2.0.4'
35+
...
36+
```
37+
38+
# Config
39+
40+
Create an AWS account [Amazon Web Services](http://aws.amazon.com/), in order to get your own credentials accessKey and secretKey.
41+
42+
43+
## AWS SDK for Java version
44+
45+
You can override the default AWS SDK for Java version by setting it in your _gradle.properties_:
46+
47+
```
48+
awsJavaSdkVersion=1.10.66
49+
```
50+
51+
## Credentials
52+
53+
Add your AWS credentials parameters to your _grails-app/conf/application.yml_:
54+
55+
```yml
56+
grails:
57+
plugin:
58+
awssdk:
59+
accessKey: {ACCESS_KEY}
60+
secretKey: {SECRET_KEY}
61+
```
62+
63+
If you do not provide credentials, a credentials provider chain will be used that searches for credentials in this order:
64+
65+
* Environment Variables - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_KEY`
66+
* Java System Properties - `aws.accessKeyId and `aws.secretKey`
67+
* Instance profile credentials delivered through the Amazon EC2 metadata service (IAM role)
68+
69+
## Region
70+
71+
The default region used is **us-east-1**. You might override it in your config:
72+
73+
```yml
74+
grails:
75+
plugin:
76+
awssdk:
77+
region: eu-west-1
78+
```
79+
80+
If you're using multiple AWS SDK Grails plugins, you can define specific settings for each services.
81+
82+
```yml
83+
grails:
84+
plugin:
85+
awssdk:
86+
accessKey: {ACCESS_KEY} # Global default setting
87+
secretKey: {SECRET_KEY} # Global default setting
88+
region: us-east-1 # Global default setting
89+
dynamodb:
90+
accessKey: {ACCESS_KEY} # Service setting (optional)
91+
secretKey: {SECRET_KEY} # Service setting (optional)
92+
region: eu-west-1 # Service setting (optional)
93+
94+
```
95+
96+
# Usage
97+
98+
## Data modeling
99+
100+
The plugin is based on [DynamoDBMapper](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.html) to model data.
101+
Just create simple groovy beans in `src/main/groovy` with specific DynamoDB java annotations (no GORM here).
102+
103+
Please check the documentation to see all the available mapper [java annotations](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Annotations.html).
104+
105+
Here is an example.
106+
107+
```groovy
108+
import com.amazonaws.services.dynamodbv2.datamodeling.*
109+
110+
@DynamoDBTable(tableName="FooItem")
111+
@ToString(includeNames=true, includeFields=true)
112+
class FooItem {
113+
114+
@DynamoDBHashKey
115+
Long accountId // Hash key
116+
@DynamoDBRangeKey
117+
@DynamoDBAutoGeneratedKey
118+
String id // Range key, with an automatically generated ID
119+
120+
@DynamoDBAttribute
121+
int count = 0
122+
@DynamoDBAttribute
123+
@DynamoDBIndexRangeKey(localSecondaryIndexName="creationDate")
124+
Date creationDate
125+
@DynamoDBAttribute
126+
String message
127+
@DynamoDBAttribute
128+
String title
129+
130+
}
131+
```
132+
133+
## Service definition
134+
135+
Once you have modeled your data, create one DB Grails service per bean by extending `AbstractDBService`.
136+
137+
```groovy
138+
import grails.plugins.awssdk.dynamodb.AbstractDBService
139+
140+
class FooItemDBService extends AbstractDBService<FooItem> {
141+
142+
FooItemDBService() {
143+
super(FooItem)
144+
}
145+
146+
}
147+
```
148+
149+
## Table management
150+
151+
If your table does not exist yet, the DB service provides a method for that.
152+
153+
```groovy
154+
// Create table
155+
ctx.fooItemDBService.createTable()
156+
```
157+
158+
## Creating or updating items
159+
160+
The DB service provides plenty of methods to manipulate your data.
161+
Here are some common examples.
162+
163+
```groovy
164+
hashKey = 123456789L
165+
rangeKey = '6733308f-5f64-48d2-824d-665290664ae0'
166+
167+
// Save item
168+
foo = new FooItem(
169+
accountId: hashKey,
170+
creationDate: new Date(),
171+
message: 'Some message...',
172+
title: 'Some title'
173+
)
174+
ctx.fooItemDBService.save(foo)
175+
176+
// Saving multiple items
177+
ctx.fooItemDBService.saveAll(foo, bar)
178+
179+
// Updating a single attribute
180+
ctx.fooItemDBService.updateItemAttribute(hashKey, rangeKey, 'title', 'Some title updated')
181+
182+
// Decrementing a numeric attribute (atomic operation)
183+
ctx.fooItemDBService.decrement(hashKey, rangeKey, 'count', 2)
184+
// Incrementing a numeric attribute (atomic operation)
185+
ctx.fooItemDBService.increment(hashKey, rangeKey, 'count', 10)
186+
```
187+
188+
## Loading items
189+
190+
```groovy
191+
// Load an item
192+
foo = ctx.fooItemDBService.get(hashKey, rangeKey)
193+
194+
// Load multiple items
195+
items = ctx.fooItemDBService.get(hashKey, [rangeKey1, rangeKey2])
196+
```
197+
198+
## Deleting items
199+
200+
To avoid to consume too much read units, all delete methods use the following settings by default:
201+
202+
```groovy
203+
settings = [
204+
limit: 100
205+
]
206+
```
207+
208+
You can override those settings when calling each methods by passing a settings map (last parameter).
209+
210+
```groovy
211+
// Delete an item
212+
ctx.fooItemDBService.delete(foo)
213+
// Or by hash and range keys
214+
ctx.fooItemDBService.delete(hashKey, rangeKey)
215+
216+
// Delete a list of items
217+
ctx.fooItemDBService.deleteAll([foo, bar])
218+
219+
// Delete all items for a given hashKey (WARNING: deleting can consume a lot of write units)
220+
ctx.fooItemDBService.deleteAll(hashKey)
221+
222+
// Delete all items by simple condition
223+
ctx.fooItemDBService.deleteAll(hashKey, 'id', '4532432-', ComparisonOperator.BEGINS_WITH)
224+
225+
// Delete all items by conditions (with a Map<String, Condition>)
226+
ctx.fooItemDBService.deleteAllByConditions(hashKey, rangeKeyConditions)
227+
```
228+
229+
## Counting items
230+
231+
To avoid to consume too much read units, all count methods use the following settings by default:
232+
233+
* `consistentRead` (default to false)
234+
* `limit` (default to 100)
235+
236+
You can override those settings when calling each methods by passing a settings map (last method parameter).
237+
238+
```groovy
239+
// Count items by simple condition
240+
ctx.fooItemDBService.count(hashKey, 'id', '4532432-', ComparisonOperator.BEGINS_WITH)
241+
242+
// Count items by conditions (with a Map<String, Condition>)
243+
ctx.fooItemDBService.countByConditions(hashKey, rangeKeyConditions)
244+
245+
// Count items by dates range
246+
ctx.fooItemDBService.countByDates(hashKey, 'creationDate', [after: new Date() - 7, before: new Date() - 1])
247+
```
248+
249+
## Querying items
250+
251+
To avoid to consume too much read units, all count methods use the following settings by default:
252+
253+
* `batchGetDisabled` (only when secondary indexes are used, useful for count when all item attributes are not required)
254+
* `consistentRead` (default to false)
255+
* `exclusiveStartKey` a map with the rangeKey (ex: [id: 2555]), with optional indexRangeKey when using LSI (ex.: [id: 2555, totalCount: 45])
256+
* `limit` (default to 100)
257+
* `returnAll` disable paging to return all items, WARNING: can be expensive in terms of throughput (default to false)
258+
* `scanIndexForward` (default to false)
259+
260+
```groovy
261+
// Query items by hash key
262+
items = ctx.fooItemDBService.query(hashKey).results
263+
264+
// Query items by simple condition
265+
items = ctx.fooItemDBService.query(hashKey, 'id', '4532432-', ComparisonOperator.BEGINS_WITH).results
266+
267+
// Query items by conditions (with a Map<String, Condition>)
268+
items = ctx.fooItemDBService.queryByConditions(hashKey, rangeKeyConditions).results
269+
270+
// Query items by dates range
271+
items = ctx.fooItemDBService.queryByDates(hashKey, 'creationDate', [after: new Date() - 7, before: new Date() - 1]).results
272+
```
273+
274+
## Advanced usage
275+
276+
If required, you can also directly use **AmazonDynamoDBClient** instance available at **fooItemDBService.client** and **DynamoDBMapper** instance available at **fooItemDBService.mapper**.
277+
278+
For more info, AWS SDK for Java documentation is located here:
279+
280+
* [AWS SDK for Java](http://docs.amazonwebservices.com/AWSJavaSDK/latest/javadoc/index.html)
281+
282+
283+
# Bugs
284+
285+
To report any bug, please use the project [Issues](http://github.com/agorapulse/grails-aws-sdk-dynamodb/issues) section on GitHub.
286+
287+
Feedback and pull requests are welcome!

aws-sdk-dynamodb/build.gradle

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apply from: "../gradle/grails.commons.gradle"
2+
3+
dependencies {
4+
// Latest Joda Time
5+
compile 'joda-time:joda-time:2.9.4'
6+
7+
// Latest AWS SDK DynamoDB lib
8+
compile "com.amazonaws:aws-java-sdk-dynamodb:$awsJavaSdkVersion"
9+
}
10+
11+
grailsPublish {
12+
user = System.getenv("BINTRAY_USER") ?: ''
13+
key = System.getenv("BINTRAY_KEY") ?: ''
14+
userOrg = 'agorapulse'
15+
githubSlug = "agorapulse/grails-aws-sdk"
16+
license {
17+
name = 'Apache-2.0'
18+
}
19+
title = "AWS SDK DynamoDB"
20+
desc = "Grails AWS SDK DynamoDB plugin"
21+
developers = [benorama:"Benoit Hediard", jvdrean:"Jean-Vincent Drean"]
22+
portalUser = System.getenv("GRAILS_PORTAL_USER") ?: ''
23+
portalPassword = System.getenv("GRAILS_PORTAL_PASSWORD") ?: ''
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
grails:
3+
profile: plugin
4+
codegen:
5+
defaultPackage: grails.plugins.awssdk
6+
spring:
7+
transactionManagement:
8+
proxies: false
9+
info:
10+
app:
11+
name: '@info.app.name@'
12+
version: '@info.app.version@'
13+
grailsVersion: '@info.app.grailsVersion@'
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import grails.util.BuildSettings
2+
import grails.util.Environment
3+
4+
// See http://logback.qos.ch/manual/groovy.html for details on configuration
5+
appender('STDOUT', ConsoleAppender) {
6+
encoder(PatternLayoutEncoder) {
7+
pattern = "%level %logger - %msg%n"
8+
}
9+
}
10+
11+
root(ERROR, ['STDOUT'])
12+
13+
def targetDir = BuildSettings.TARGET_DIR
14+
if (Environment.isDevelopmentMode() && targetDir) {
15+
appender("FULL_STACKTRACE", FileAppender) {
16+
file = "${targetDir}/stacktrace.log"
17+
append = true
18+
encoder(PatternLayoutEncoder) {
19+
pattern = "%level %logger - %msg%n"
20+
}
21+
}
22+
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
23+
// Debug
24+
logger 'grails.plugins.awssdk', DEBUG, ['STDOUT'], false
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package grails.plugin.awssdk.dynamodb
2+
3+
import grails.boot.*
4+
import grails.boot.config.GrailsAutoConfiguration
5+
import grails.plugins.metadata.*
6+
7+
@PluginSource
8+
class Application extends GrailsAutoConfiguration {
9+
static void main(String[] args) {
10+
GrailsApp.run(Application, args)
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package grails.plugin.awssdk.test
2+
3+
import grails.plugin.awssdk.dynamodb.AbstractDBService
4+
5+
class FooItemDBService extends AbstractDBService<FooItem> {
6+
7+
FooItemDBService() {
8+
super(FooItem)
9+
}
10+
11+
}

0 commit comments

Comments
 (0)