Skip to content

Commit 3076c84

Browse files
committed
WIP
1 parent 4748ee5 commit 3076c84

File tree

6 files changed

+196
-8
lines changed

6 files changed

+196
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package org.socialsignin.spring.data.dynamodb.domain.sample;
2+
3+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
4+
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
5+
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
6+
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
7+
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
8+
import com.amazonaws.services.dynamodbv2.model.KeyType;
9+
import com.amazonaws.services.dynamodbv2.model.Projection;
10+
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
11+
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
12+
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
13+
import org.junit.Before;
14+
import org.junit.Test;
15+
import org.junit.runner.RunWith;
16+
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
17+
import org.socialsignin.spring.data.dynamodb.utils.DynamoDBLocalResource;
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.context.annotation.Configuration;
20+
import org.springframework.test.context.ContextConfiguration;
21+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
22+
23+
import java.util.ArrayList;
24+
import java.util.List;
25+
import java.util.UUID;
26+
27+
import static org.junit.Assert.assertEquals;
28+
29+
@RunWith(SpringJUnit4ClassRunner.class)
30+
@ContextConfiguration(classes = {DynamoDBLocalResource.class, DuplicateColumnUsageTest.DuplicateColumnUsageTestConfig.class})
31+
public class DuplicateColumnUsageTest {
32+
33+
34+
@Configuration
35+
@EnableDynamoDBRepositories(basePackages = "org.socialsignin.spring.data.dynamodb.domain.sample")
36+
static class DuplicateColumnUsageTestConfig {
37+
38+
}
39+
40+
41+
@Before
42+
public void setUp() {
43+
// DynamoDBLocalResource.createTable(ddb, Playlist.class);
44+
List<AttributeDefinition> ad = new ArrayList<>();
45+
ad.add(new AttributeDefinition("Genre", ScalarAttributeType.S));
46+
ad.add(new AttributeDefinition("PlaylistName", ScalarAttributeType.S));
47+
ad.add(new AttributeDefinition("UserName", ScalarAttributeType.S));
48+
49+
List<KeySchemaElement> ks = new ArrayList<>();
50+
ks.add(new KeySchemaElement("UserName", KeyType.HASH));
51+
ks.add(new KeySchemaElement("PlaylistName", KeyType.RANGE));
52+
53+
List<KeySchemaElement> gsiks = new ArrayList<>();
54+
gsiks.add(new KeySchemaElement("Genre", KeyType.HASH));
55+
gsiks.add(new KeySchemaElement("PlaylistName", KeyType.RANGE));
56+
57+
List<GlobalSecondaryIndex> gsis = new ArrayList<>();
58+
gsis.add(new GlobalSecondaryIndex()
59+
.withIndexName("Genre-PlaylistName-index")
60+
.withKeySchema(gsiks)
61+
.withProjection(new Projection().withProjectionType(ProjectionType.ALL))
62+
.withProvisionedThroughput(new ProvisionedThroughput(10L, 10L)));
63+
64+
CreateTableRequest ctr = new CreateTableRequest();
65+
ctr.withTableName("playlist");
66+
ctr.withAttributeDefinitions(ad);
67+
ctr.withKeySchema(ks);
68+
ctr.withGlobalSecondaryIndexes(gsis);
69+
ctr.withProvisionedThroughput(new ProvisionedThroughput(10L, 10L));
70+
71+
ddb.createTable(ctr);
72+
}
73+
74+
75+
@Autowired
76+
private PlaylistRepository playlistRepository;
77+
@Autowired
78+
private AmazonDynamoDB ddb;
79+
80+
81+
private Playlist generatePlaylist(String genre, String playlistName) {
82+
final String userName = "userName-" + UUID.randomUUID().toString();
83+
final String displayName = "displayName-" + UUID.randomUUID().toString();
84+
PlaylistId id = new PlaylistId(userName, playlistName);
85+
86+
Playlist playlist = new Playlist(id);
87+
playlist.setDisplayName(displayName);
88+
playlist.setGenre(genre);
89+
90+
return playlist;
91+
}
92+
93+
@Test
94+
public void testGsiSharedRange() {
95+
final String GENRE = "GENRE";
96+
playlistRepository.save(generatePlaylist(GENRE, "1"));
97+
playlistRepository.save(generatePlaylist(GENRE, "2"));
98+
playlistRepository.save(generatePlaylist(GENRE, "3"));
99+
try {
100+
Thread.sleep(2000L);
101+
} catch (InterruptedException e) {
102+
e.printStackTrace();
103+
}
104+
105+
assertEquals(3, playlistRepository.findByGenre(GENRE).size());
106+
107+
assertEquals(1, playlistRepository.findByGenreAndPlaylistName(GENRE, "2").size());
108+
109+
List<Playlist> actual = playlistRepository.findByGenreAndPlaylistNameBetween(GENRE, "2", "3");
110+
111+
assertEquals(2, actual.size());
112+
}
113+
114+
}

src/test/java/org/socialsignin/spring/data/dynamodb/domain/sample/HashRangeKeyIT.java

+28-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.test.context.ContextConfiguration;
2222
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
2323

24+
import java.util.List;
2425
import java.util.Optional;
2526
import java.util.UUID;
2627

@@ -37,20 +38,28 @@
3738
public class HashRangeKeyIT {
3839

3940
@Autowired
40-
PlaylistRepository playlistRepository;
41+
private PlaylistRepository playlistRepository;
4142

42-
@Test
43-
public void runCrudOperations() {
44-
final String displayName = "displayName" + UUID.randomUUID().toString();
43+
private Playlist generatePlaylist(String genre, String displayName) {
4544
final String userName = "userName-" + UUID.randomUUID().toString();
4645
final String playlistName = "playlistName-" + UUID.randomUUID().toString();
4746
PlaylistId id = new PlaylistId(userName, playlistName);
4847

49-
Optional<Playlist> actual = playlistRepository.findById(id);
50-
assertFalse(actual.isPresent());
51-
5248
Playlist playlist = new Playlist(id);
5349
playlist.setDisplayName(displayName);
50+
playlist.setGenre(genre);
51+
52+
return playlist;
53+
}
54+
55+
@Test
56+
public void runCrudOperations() {
57+
String displayName = "displayName" + UUID.randomUUID().toString();
58+
Playlist playlist = generatePlaylist("genre-" + UUID.randomUUID().toString(), displayName);
59+
PlaylistId id = playlist.getId();
60+
61+
Optional<Playlist> actual = playlistRepository.findById(id);
62+
assertFalse(actual.isPresent());
5463

5564
playlistRepository.save(playlist);
5665

@@ -60,4 +69,16 @@ public void runCrudOperations() {
6069
assertEquals(id.getPlaylistName(), actual.get().getPlaylistName());
6170
assertEquals(id.getUserName(), actual.get().getUserName());
6271
}
72+
73+
@Test
74+
public void testGsiSharedRange() {
75+
final String GENRE = "GENRE";
76+
playlistRepository.save(generatePlaylist(GENRE, "1"));
77+
playlistRepository.save(generatePlaylist(GENRE, "2"));
78+
playlistRepository.save(generatePlaylist(GENRE, "3"));
79+
80+
List<Playlist> actual = playlistRepository.findByGenreAndPlaylistNameBetween(GENRE, "2", "3");
81+
82+
assertEquals(2, actual.size());
83+
}
6384
}

src/test/java/org/socialsignin/spring/data/dynamodb/domain/sample/Playlist.java

+19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
1919
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
20+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore;
21+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexHashKey;
22+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexRangeKey;
2023
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
2124
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
2225
import org.springframework.data.annotation.Id;
@@ -27,13 +30,19 @@ public class Playlist {
2730
@Id
2831
private PlaylistId playlistId;
2932
private String displayName;
33+
private String genre;
3034

3135
public Playlist() {
3236
}
3337

3438
public Playlist(PlaylistId playlistId) {
3539
this.playlistId = playlistId;
3640
}
41+
42+
@DynamoDBIgnore
43+
public PlaylistId getId() {
44+
return this.playlistId;
45+
}
3746

3847
@DynamoDBAttribute(attributeName="DisplayName")
3948
public String getDisplayName() {
@@ -57,6 +66,7 @@ public void setUserName(String userName) {
5766
}
5867

5968
@DynamoDBRangeKey(attributeName = "PlaylistName")
69+
@DynamoDBIndexRangeKey(attributeName = "PlaylistName", globalSecondaryIndexName="Genre-PlaylistName-index")
6070
public String getPlaylistName() {
6171
return playlistId != null ? playlistId.getPlaylistName() : null;
6272
}
@@ -67,4 +77,13 @@ public void setPlaylistName(String playlistName) {
6777
}
6878
playlistId.setPlaylistName(playlistName);
6979
}
80+
81+
@DynamoDBIndexHashKey(attributeName = "Genre", globalSecondaryIndexName="Genre-PlaylistName-index")
82+
public String getGenre() {
83+
return this.genre;
84+
}
85+
86+
public void setGenre(String genre) {
87+
this.genre = genre;
88+
}
7089
}

src/test/java/org/socialsignin/spring/data/dynamodb/domain/sample/PlaylistRepository.java

+7
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@
1515
*/
1616
package org.socialsignin.spring.data.dynamodb.domain.sample;
1717

18+
import java.util.List;
19+
20+
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
1821
import org.springframework.data.repository.CrudRepository;
1922

23+
@EnableScan
2024
public interface PlaylistRepository extends CrudRepository<Playlist, PlaylistId> {
25+
List<Playlist> findByGenre(String genre);
26+
List<Playlist> findByGenreAndPlaylistName(String genre, String playlistName);
27+
List<Playlist> findByGenreAndPlaylistNameBetween(String genre, String startPlaylistName, String endPlaylistName);
2128

2229
}

src/test/java/org/socialsignin/spring/data/dynamodb/utils/DynamoDBLocalResource.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public static <T> CreateTableResult createTable(AmazonDynamoDB ddb, Class<T> dom
5757

5858
Optional<String> rangeKey = Optional.empty();
5959
if (entityInfo instanceof DynamoDBIdIsHashAndRangeKeyEntityInformation) {
60-
rangeKey = Optional.of(((DynamoDBIdIsHashAndRangeKeyEntityInformation)entityInfo).getRangeKeyPropertyName());
60+
rangeKey = Optional.of(((DynamoDBIdIsHashAndRangeKeyEntityInformation)entityInfo).getRangeKeyPropertyName())
61+
.flatMap(e -> entityInfo.getOverriddenAttributeName(e));
6162
}
6263

6364
return createTable(ddb, tableName, hashKey, rangeKey);

src/test/resources/playlist_table.json

+26
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,34 @@
77
{
88
"AttributeName": "PlaylistName",
99
"AttributeType": "S"
10+
},
11+
{
12+
"AttributeName": "Genre",
13+
"AttributeType": "S"
1014
}
1115
],
16+
"GlobalSecondaryIndexes": [
17+
{
18+
"IndexName": "Genre-PlaylistName-index",
19+
"KeySchema": [
20+
{
21+
"AttributeName": "Genre",
22+
"KeyType": "HASH"
23+
},
24+
{
25+
"AttributeName": "PlaylistName",
26+
"KeyType": "RANGE"
27+
}
28+
],
29+
"Projection": {
30+
"ProjectionType": "ALL"
31+
},
32+
"ProvisionedThroughput": {
33+
"ReadCapacityUnits": "10",
34+
"WriteCapacityUnits": "10"
35+
}
36+
}
37+
],
1238
"KeySchema": [
1339
{
1440
"AttributeName": "UserName",

0 commit comments

Comments
 (0)