일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- awscli
- 스프링테스트
- annotation
- 자바
- 도메인
- 다이나모디비
- secondaryindex
- Springsecurity
- AWS
- Java
- 자바스프링
- query
- 오류
- Route53
- 테스트코드
- awscloud
- testresttemplate
- MockMvc
- markerinterface
- partiql
- 개발
- 로드밸런서
- compositekey
- 스프링
- EmbeddedId
- IdClass
- javaspring
- Spring
- DynamoDB
- filterexpression
- Today
- Total
아장아장 개발 일기
Spring + Local DynamoDB 본문
Spring Gradle에서 Local DynamoDB configuration 하기
이번 포트에서는 스프링에서 Local DynamoDB를 세팅 후 User 테이블에 아이템을 등록하는 테스트를 하려 합니다.
먼저 아래의 세 개 의존성을 주입합니다.(맨 아래 baeldung 소스 참고함)
build.gradle
dependencies{
...
implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.12.205'
implementation 'org.springframework.data:spring-data-releasetrain:Lovelace-RELEASE'
implementation 'com.github.derjust:spring-data-dynamodb:5.1.0'
...
}
properties 파일에 로컬 DynamoDB의 엔드포인트인 ‘http://localhost:8000/’와 본인의 aws 액세스 키와 시크릿 키를 입력합니다.
이는 아래 configuration 클래스에서 가져다 dynamoDB를 세팅하는데 사용됩니다.
properties
amazon.dynamodb.endpoint=http://localhost:8000/
amazon.aws.accesskey=key
amazon.aws.secretkey=key2
아래는 properties 파일의 aws 엔드포인트, 액세스키, 시크릿키 정보를 활용해 AmazonDynamoDB, DynamoDB 클래스를 빈으로 등록 하는 소스입니다.
여기서 등록된 빈들은 이후 테스트 코드에서 활용됩니다. 각 코드 블럭에 대한 설명은 주석 참고 부탁 드립니다.
Configuration 클래스
@Configuration
@PropertySource("classpath:aws.properties")
@EnableDynamoDBRepositories(basePackages = "com.example.dynamodbtest.repository")
public class DynamoDBConfig {
@Value("${aws.dynamodb.endpoint}")
private String amazonDynamoDBEndpoint;
@Value("${aws.accessKey}")
private String amazonAWSAccessKey;
@Value("${aws.secretKey}")
private String amazonAWSSecretKey;
@Value("${region}")
private String region;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
// aws 엔드포인트 설정.
// 따로 설정하지 않을시에는 디폴트 주소로 연결됨
// (<https://dynamodb.ap-northeast-2.amazonaws.com>)
AwsClientBuilder.EndpointConfiguration endpointConfiguration =
new AwsClientBuilder.EndpointConfiguration(amazonDynamoDBEndpoint, region);
// AWSCredentials 및 엔드포인트 설정
return AmazonDynamoDBClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(amazonAWSCredentials()))
.withEndpointConfiguration(endpointConfiguration)
.build();
}
@Bean
public DynamoDB dynamoDB() {
return new DynamoDB(amazonDynamoDB());
}
@Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(
amazonAWSAccessKey, amazonAWSSecretKey);
}
}
테이블 생성 및 테스트를 진행할 도메인 클래스입니다.
Domain 클래스
@AllArgsConstructor
@NoArgsConstructor
@DynamoDBTable(tableName = "User") // 클래스를 DynamoDB 테이블로 표시하는 어노테이션
public class User {
private String id;
private String username;
private String password;
private String email;
private String role;
// property를 해쉬키로 등록하는 어노테이션. getter나 클래스 필드에 적용됨.
// 클래스 필드에 적용하는 경우 getter, setter가 같은 클래스 내에 선언되어야함.
// 필수 어노테이션
@DynamoDBHashKey
// 해쉬키 혹은 레인지 키 특성을 지정하기 위한 어노테이션으로 UUID 키가 자동 생성됨.
// String 타입의 키만 자동 생성 가능.(다른 타입에 해당 어노테이션을 적용하면 타입 오류 발생)
// 역시나 클래스 필드에 적용하는 경우 getter, setter가 같은 클래스 내에 선언되어야함.
@DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// 테이블의 attribute로 지정하는 어노테이션.
// 클래스의 property 명이 테이블의 attribute 명과 일치하면 옵션으로 사용 가능.
// 다를경우 @DynamoDBAttribute(attributeName = "username") 와 같이 표시 필요.
@DynamoDBAttribute
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@DynamoDBAttribute
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@DynamoDBAttribute
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@DynamoDBAttribute
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
- Partition/Hash Key : 데이터를 파티션에 고르게 분포 시키기 위한 DynamoDB의 내부 hash 기능에서 나온 표현. 아이템의 키 값을 토대로 파티션에 위치 시킨다.
- Sort/Range Key : DynamoDB내에는 같은 파티션 키를 가진 아이템들이 물리적으로 가까이 저장되는데, sort key 기준으로 정렬된 순서로 저장된다.
- 참고 : https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-keyschema.html
마지막으로 테이블을 생성하고, 해당 테이블에 User 아이템을 등록 후, 테이블을 삭제하는 테스트 코드입니다.
코드를 잘 보시면, 테이블을 생성하고 삭제할 때 해당 동작이 완성될 때까지 기다리는 코드가 있습니다.(waitForActive(), waitForDelete())
해당 코드 없이 테스트를 진행하면 테이블 생성과 삭제가 완료되기 전에 다음 코드가 실행돼서 Resources Not Found 오류가 발생하니 안정적인 테스트 진행을 위해 해당 코드가 꼭 필요해 보입니다.
Test 클래스
@SpringBootTest(classes = DynamoDbTestApplication.class)
@WebAppConfiguration
class UserRepositoryTest {
@Autowired
private DynamoDB dynamoDB;
@Autowired
private AmazonDynamoDB amazonDynamoDB;
@Autowired
private UserRepository repository;
private final Class<User> tableClass = User.class;
private Table table;
private String tableName;
@BeforeEach
public void 테이블_생성() {
try {
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
CreateTableRequest tableRequest = dynamoDBMapper.generateCreateTableRequest(tableClass);
tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));
table = dynamoDB.createTable(tableRequest);
tableName = table.getTableName();
System.out.println(tableName + " 테이블을 생성중입니다. 다소 시간이 걸릴 수 있습니다.");
table.waitForActive();
}
catch (InterruptedException e) {
System.err.println(tableName + " 테이블 생성 요청에 실패했습니다.");
}
}
@AfterEach
void 테이블_삭제() {
try {
Table table = dynamoDB.getTable(tableName);
table.delete();
System.out.println(tableName + " 테이블 삭제 요청중입니다. 다소 시간이 걸릴 수 있습니다.");
table.waitForDelete();
}
catch (InterruptedException e) {
System.err.println(tableName + " 테이블 삭제요청에 실패했습니다.");
}
}
@Test
public void 유저_등록() {
User user = new User();
user.setUsername("test");
user.setEmail("test@test.com");
user.setPassword("test");
user.setRole("USER");
repository.save(user);
Iterable<User> all = repository.findAll();
for (User u : all) {
String id = u.getId();
String username = u.getUsername();
String role = u.getRole();
System.out.println("id = " + id);
System.out.println("username = " + username);
System.out.println("role = " + role);
}
}
}
테스트를 실행하기 전, cmd에서 http://localhost:8000을 실행시킵니다.
- dynamoDB 로컬 폴더가 설치된 위치로 이동합니다.
- 아래 명령문을 입력합니다.
- java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
- java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
테스트 결과
>> 참고
https://www.baeldung.com/spring-data-dynamodb
https://stackoverflow.com/questions/33801460/dynamo-db-local-connection-refused
'개발 > AWS' 카테고리의 다른 글
AWS 클라우드 활용, 도메인에 SSL 적용하기 A to Z(Route53, Certificate Manager, Load Balancer) (0) | 2022.08.01 |
---|---|
AWS Route53에서 도메인 연결 및 Host zone 관리 방법 (0) | 2022.07.29 |
Spring + AWS Cognito 세팅 및 로그인, 회원가입, 로그아웃 구현 (0) | 2022.06.15 |
AWS DynamoDB 관리 AWS Cli 명령어(Window) (0) | 2022.04.26 |
AWS DynamoDB Local에 설치하기 (0) | 2022.04.25 |