Skip to content

Commit

Permalink
Provision dynamodb table
Browse files Browse the repository at this point in the history
  • Loading branch information
jordansimsmith committed Aug 8, 2024
1 parent 70e467b commit a98806d
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 25 deletions.
5 changes: 5 additions & 0 deletions immersion_tracker_api/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ java_binary(
name = "get-progress-handler",
srcs = glob(["src/main/java/com/jordansimsmith/immersiontracker/GetProgressHandler.java"]),
create_executable = False,
resources = glob([
"src/main/resources/logback.xml",
]),
deps = [
":lib",
"@maven//:ch_qos_logback_logback_classic",
"@maven//:ch_qos_logback_logback_core",
"@maven//:com_amazonaws_aws_lambda_java_core",
"@maven//:com_google_guava_guava",
"@maven//:software_amazon_awssdk_dynamodb",
Expand Down
89 changes: 78 additions & 11 deletions immersion_tracker_api/infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,37 @@ provider "aws" {
region = "ap-southeast-2"
}

data "external" "get_progress_handler_location" {
program = ["bash", "${path.module}/resolve_location.sh"]

query = {
target = "//immersion_tracker_api:get-progress-handler_deploy.jar"
locals {
application_id = "immersion_tracker_api"
tags = {
application_id = local.application_id
}
}

data "local_file" "get_progress_handler_file" {
filename = data.external.get_progress_handler_location.result.location
resource "aws_dynamodb_table" "immersion_tracker_table" {
name = "immersion_tracker"
billing_mode = "PAY_PER_REQUEST"
hash_key = "pk"
range_key = "sk"

attribute {
name = "pk"
type = "S"
}

attribute {
name = "sk"
type = "S"
}

point_in_time_recovery {
enabled = true
}

tags = local.tags
}

data "aws_iam_policy_document" "lambda_policy_document" {
data "aws_iam_policy_document" "lambda_sts_allow_policy_document" {
statement {
effect = "Allow"

Expand All @@ -44,17 +62,66 @@ data "aws_iam_policy_document" "lambda_policy_document" {
}
}

data "aws_iam_policy_document" "lambda_dynamodb_allow_policy_document" {
statement {
effect = "Allow"

resources = [
aws_dynamodb_table.immersion_tracker_table.arn
]

actions = [
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:BatchWriteItem",
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:ConditionCheckItem",
]
}
}

resource "aws_iam_policy" "lambda_dynamodb_allow_policy_document" {
name = "${local.application_id}_lambda_dynamodb_allow"
policy = data.aws_iam_policy_document.lambda_dynamodb_allow_policy_document.json
tags = local.tags
}

resource "aws_iam_role" "lambda_role" {
name = "lambda_role"
assume_role_policy = data.aws_iam_policy_document.lambda_policy_document.json
name = "${local.application_id}_lambda_exec"
assume_role_policy = data.aws_iam_policy_document.lambda_sts_allow_policy_document.json
tags = local.tags
}

resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {
role = aws_iam_role.lambda_role.name
policy_arn = aws_iam_policy.lambda_dynamodb_allow_policy_document.arn
}

data "external" "get_progress_handler_location" {
program = ["bash", "${path.module}/resolve_location.sh"]

query = {
target = "//immersion_tracker_api:get-progress-handler_deploy.jar"
}
}

data "local_file" "get_progress_handler_file" {
filename = data.external.get_progress_handler_location.result.location
}

resource "aws_lambda_function" "get_progress_handler_lambda" {
filename = data.local_file.get_progress_handler_file.filename
function_name = "get_progress_handler"
function_name = "${local.application_id}_get_progress_handler"
role = aws_iam_role.lambda_role.arn
source_code_hash = data.local_file.get_progress_handler_file.content_base64sha256
handler = "com.jordansimsmith.immersiontracker.GetProgressHandler"
runtime = "java17"
memory_size = 512
timeout = 10
tags = local.tags
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class DynamoDbModule {

@Provides
public DynamoDbClient dynamoDbClient(@Nullable @Named("dynamoDbEndpoint") URI dynamoDbEndpoint) {
public DynamoDbClient dynamoDbClient(@Named("dynamoDbEndpoint") @Nullable URI dynamoDbEndpoint) {
var builder = DynamoDbClient.builder();
if (dynamoDbEndpoint != null) {
builder.endpointOverride(dynamoDbEndpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.google.common.annotations.VisibleForTesting;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

public class GetProgressHandler implements RequestHandler<Object, String> {
Expand All @@ -22,6 +23,10 @@ public GetProgressHandler() {

@Override
public String handleRequest(Object s, Context context) {
return dynamoDbClient.listTables().toString();

var schema = TableSchema.fromBean(ImmersionTrackerRecord.class);
var table = dynamoDbEnhancedClient.table("immersion_tracker", schema);

return table.scan().items().stream().toList().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dagger.BindsInstance;
import dagger.Component;
import java.net.URI;
import javax.annotation.Nullable;
import javax.inject.Named;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
Expand All @@ -17,7 +18,7 @@ public interface ImmersionTrackerFactory {
@Component.Builder
interface Builder {
@BindsInstance
Builder dynamoDbEndpoint(@Named("dynamoDbEndpoint") URI dynamoDbEndpoint);
Builder dynamoDbEndpoint(@Named("dynamoDbEndpoint") @Nullable URI dynamoDbEndpoint);

ImmersionTrackerFactory build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.jordansimsmith.immersiontracker;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

@DynamoDbBean
public class ImmersionTrackerRecord {
private String pk;
private String sk;

@DynamoDbPartitionKey
public String getPk() {
return pk;
}

public void setPk(String pk) {
this.pk = pk;
}

@DynamoDbSortKey
public String getSk() {
return sk;
}

public void setSk(String sk) {
this.sk = sk;
}
}
11 changes: 11 additions & 0 deletions immersion_tracker_api/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>

<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@ void setUp() {

var req =
CreateTableRequest.builder()
.tableName("my_table")
.keySchema(KeySchemaElement.builder().keyType(KeyType.HASH).attributeName("pk").build())
.tableName("immersion_tracker")
.keySchema(
KeySchemaElement.builder().keyType(KeyType.HASH).attributeName("pk").build(),
KeySchemaElement.builder().keyType(KeyType.RANGE).attributeName("sk").build())
.attributeDefinitions(
AttributeDefinition.builder()
.attributeName("pk")
.attributeType(ScalarAttributeType.S)
.build(),
AttributeDefinition.builder()
.attributeName("sk")
.attributeType(ScalarAttributeType.S)
.build())
.provisionedThroughput(
ProvisionedThroughput.builder()
.readCapacityUnits(1L)
.writeCapacityUnits(1L)
.build())
.billingMode(BillingMode.PAY_PER_REQUEST)
.build();
dynamodbClient.createTable(req);

Expand All @@ -52,13 +54,17 @@ void setUp() {

@Test
void test1() {
getProgressHandler.handleRequest(null, null);
assertThat(dynamodbClient.listTables().tableNames()).contains("my_table");
assertThat(dynamodbClient.listTables().tableNames()).contains("immersion_tracker");

var res = getProgressHandler.handleRequest(null, null);
assertThat(res).isEqualTo("[]");
}

@Test
void test2() {
getProgressHandler.handleRequest(null, null);
assertThat(dynamodbClient.listTables().tableNames()).doesNotContain("my_table_2");
assertThat(dynamodbClient.listTables().tableNames()).doesNotContain("my_nonexisting_table");

var res = getProgressHandler.handleRequest(null, null);
assertThat(res).isEqualTo("[]");
}
}

0 comments on commit a98806d

Please sign in to comment.