Skip to content

Commit c535e24

Browse files
author
AncaGhenade
committed
shipment-list-demo app:
- backend for CRUD (not ready) operations on shipment entity - backend setup for saving images to S3 - entities are saved to a configured dynamodb - frontend react app that displays information and saves images - script for creating new S3 bucket to help user set up faster - application-prod.yml used to connect to real aws services
1 parent 56d3183 commit c535e24

39 files changed

+30768
-10
lines changed

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,27 @@ build/
3131

3232
### VS Code ###
3333
.vscode/
34+
35+
### Frontend ###
36+
37+
# dependencies
38+
src/main/shipment-list-frontend/node_modules
39+
src/main/shipment-list-frontend/.pnp
40+
src/main/shipment-list-frontend/.pnp.js
41+
42+
# testing
43+
src/main/shipment-list-frontend/coverage
44+
45+
# production
46+
src/main/shipment-list-frontend/build
47+
48+
# misc
49+
src/main/shipment-list-frontend/.DS_Store
50+
src/main/shipment-list-frontend/.env.local
51+
src/main/shipment-list-frontend/.env.development.local
52+
src/main/shipment-list-frontend/.env.test.local
53+
src/main/shipment-list-frontend/.env.production.local
54+
55+
src/main/shipment-list-frontend/npm-debug.log*
56+
src/main/shipment-list-frontend/yarn-debug.log*
57+
src/main/shipment-list-frontend/yarn-error.log*

new-bucket.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
3+
# For demo purpose only;
4+
# Access key and secret key are set and using `aws configure` to manage the aws cli on your local machine
5+
6+
# Set the name of the S3 bucket
7+
bucket_name="shipment-list-demo-bucket"
8+
aws_region="eu-central-1"
9+
10+
# Create the S3 bucket
11+
aws s3 mb s3://$bucket_name
12+
13+
# Set the region for the S3 bucket
14+
aws s3api create-bucket --bucket $bucket_name --region $aws_region
15+
16+
# Set the bucket policy
17+
aws s3api put-bucket-acl --bucket $bucket_name --acl private

pom.xml

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,67 @@
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
55
<modelVersion>4.0.0</modelVersion>
6+
67
<parent>
78
<groupId>org.springframework.boot</groupId>
89
<artifactId>spring-boot-starter-parent</artifactId>
910
<version>3.0.1</version>
10-
<relativePath/> <!-- lookup parent from repository -->
1111
</parent>
12+
1213
<groupId>dev.ancaghenade</groupId>
1314
<artifactId>user-profile-demo</artifactId>
1415
<version>0.0.1-SNAPSHOT</version>
16+
1517
<name>user-profile-demo</name>
16-
<description>user-profile-demo</description>
18+
<description>User Profile Service</description>
19+
1720
<properties>
1821
<java.version>17</java.version>
22+
<maven.compiler.source>17</maven.compiler.source>
23+
<maven.compiler.target>17</maven.compiler.target>
24+
<maven-checkstyle-plugin.version>3.2.0</maven-checkstyle-plugin.version>
25+
<!-- <checkstyle.version>10.5.0</checkstyle.version>-->
26+
27+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
28+
<com.amazonaws.s3-sdk>1.12.376</com.amazonaws.s3-sdk>
1929
</properties>
30+
31+
32+
<!-- Dependencies-->
2033
<dependencies>
2134
<dependency>
2235
<groupId>org.springframework.boot</groupId>
2336
<artifactId>spring-boot-starter-web</artifactId>
2437
</dependency>
25-
2638
<dependency>
2739
<groupId>org.projectlombok</groupId>
2840
<artifactId>lombok</artifactId>
2941
<optional>true</optional>
3042
</dependency>
43+
<dependency>
44+
<groupId>com.amazonaws</groupId>
45+
<artifactId>aws-java-sdk-s3</artifactId>
46+
<version>${com.amazonaws.s3-sdk}</version>
47+
</dependency>
48+
<dependency>
49+
<groupId>com.amazonaws</groupId>
50+
<artifactId>aws-java-sdk-dynamodb</artifactId>
51+
<version>1.12.383</version>
52+
</dependency>
53+
<dependency>
54+
<groupId>com.github.dynamobee</groupId>
55+
<artifactId>dynamobee</artifactId>
56+
<version>0.6</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.springframework.boot</groupId>
60+
<artifactId>spring-boot-autoconfigure</artifactId>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.springframework.boot</groupId>
64+
<artifactId>spring-boot-starter-logging</artifactId>
65+
</dependency>
66+
<!-- Test -->
3167
<dependency>
3268
<groupId>org.springframework.boot</groupId>
3369
<artifactId>spring-boot-starter-test</artifactId>
@@ -49,7 +85,38 @@
4985
</excludes>
5086
</configuration>
5187
</plugin>
88+
89+
<!-- TBD? -->
90+
<!-- <plugin>-->
91+
<!-- <groupId>org.apache.maven.plugins</groupId>-->
92+
<!-- <artifactId>maven-checkstyle-plugin</artifactId>-->
93+
<!-- <version>${maven-checkstyle-plugin.version}</version>-->
94+
<!-- <dependencies>-->
95+
<!-- <dependency>-->
96+
<!-- <groupId>com.puppycrawl.tools</groupId>-->
97+
<!-- <artifactId>checkstyle</artifactId>-->
98+
<!-- <version>${checkstyle.version}</version>-->
99+
<!-- </dependency>-->
100+
<!-- </dependencies>-->
101+
<!-- <configuration>-->
102+
<!-- <configLocation>google_checks.xml</configLocation>-->
103+
<!-- <encoding>UTF-8</encoding>-->
104+
<!-- <consoleOutput>true</consoleOutput>-->
105+
<!-- <failsOnError>true</failsOnError>-->
106+
<!-- <linkXRef>false</linkXRef>-->
107+
<!-- <violationSeverity>warning</violationSeverity>-->
108+
<!-- </configuration>-->
109+
<!-- <executions>-->
110+
<!-- <execution>-->
111+
<!-- <id>validate</id>-->
112+
<!-- <phase>validate</phase>-->
113+
<!-- <goals>-->
114+
<!-- <goal>check</goal>-->
115+
<!-- </goals>-->
116+
<!-- </execution>-->
117+
<!-- </executions>-->
118+
<!-- </plugin>-->
52119
</plugins>
53120
</build>
54-
55121
</project>
122+

src/main/java/dev/ancaghenade/userprofiledemo/UserProfileDemoApplication.java renamed to src/main/java/dev/ancaghenade/shipmentlistdemo/ShipmentListDemoApplication.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package dev.ancaghenade.userprofiledemo;
1+
package dev.ancaghenade.shipmentlistdemo;
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
55

66
@SpringBootApplication
7-
public class UserProfileDemoApplication {
7+
public class ShipmentListDemoApplication {
88

99
public static void main(String[] args) {
10-
SpringApplication.run(UserProfileDemoApplication.class, args);
10+
SpringApplication.run(ShipmentListDemoApplication.class, args);
1111
}
1212

1313
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package dev.ancaghenade.shipmentlistdemo.buckets;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public enum BucketName {
7+
8+
SHIPMENT_PICTURE("shipment-list-demo-bucket");
9+
10+
private final String bucketName;
11+
12+
BucketName(String bucketName) {
13+
this.bucketName = bucketName;
14+
}
15+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package dev.ancaghenade.shipmentlistdemo.changelogs;
2+
3+
import static java.lang.String.*;
4+
5+
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
6+
import com.amazonaws.services.dynamodbv2.document.Table;
7+
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
8+
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
9+
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
10+
import com.amazonaws.services.dynamodbv2.model.KeyType;
11+
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
12+
import java.util.ArrayList;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
public class ChangelogHelper {
17+
18+
private static final Logger logger = LoggerFactory.getLogger(ChangelogHelper.class);
19+
20+
public static void createTable(DynamoDB dynamoDB, String tableName, long readCapacityUnits,
21+
long writeCapacityUnits,
22+
String partitionKeyName, String partitionKeyType) {
23+
24+
createTable(dynamoDB, tableName, readCapacityUnits, writeCapacityUnits,
25+
partitionKeyName, partitionKeyType, null, null);
26+
}
27+
28+
public static void createTable(DynamoDB dynamoDB, String tableName, long readCapacityUnits,
29+
long writeCapacityUnits,
30+
String partitionKeyName, String partitionKeyType, String sortKeyName, String sortKeyType) {
31+
32+
try {
33+
34+
ArrayList<KeySchemaElement> keySchema = new ArrayList<>();
35+
keySchema.add(new KeySchemaElement().withAttributeName(partitionKeyName)
36+
.withKeyType(KeyType.HASH)); // Partition key + type
37+
38+
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<>();
39+
attributeDefinitions
40+
.add(new AttributeDefinition().withAttributeName(partitionKeyName)
41+
.withAttributeType(partitionKeyType));
42+
43+
if (sortKeyName != null) {
44+
keySchema.add(new KeySchemaElement().withAttributeName(sortKeyName)
45+
.withKeyType(KeyType.RANGE)); // Sort
46+
// key
47+
attributeDefinitions
48+
.add(new AttributeDefinition().withAttributeName(sortKeyName)
49+
.withAttributeType(sortKeyType));
50+
}
51+
52+
CreateTableRequest request = new CreateTableRequest().withTableName(tableName)
53+
.withKeySchema(keySchema)
54+
.withProvisionedThroughput(
55+
new ProvisionedThroughput().withReadCapacityUnits(readCapacityUnits)
56+
.withWriteCapacityUnits(writeCapacityUnits));
57+
58+
request.setAttributeDefinitions(attributeDefinitions);
59+
60+
logger.info(format("Issuing CreateTable request for %s", tableName));
61+
Table table = dynamoDB.createTable(request);
62+
logger.info(format("Waiting for \"%s\" to be created...this may take a while...", tableName));
63+
64+
table.waitForActive();
65+
66+
} catch (Exception e) {
67+
logger.error(format("CreateTable request failed for %s",tableName));
68+
throw new RuntimeException(e.getMessage());
69+
}
70+
}
71+
72+
73+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package dev.ancaghenade.shipmentlistdemo.changelogs;
2+
3+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
4+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
5+
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.github.dynamobee.changeset.ChangeLog;
8+
import com.github.dynamobee.changeset.ChangeSet;
9+
import dev.ancaghenade.shipmentlistdemo.entity.Shipment;
10+
import dev.ancaghenade.shipmentlistdemo.util.ResourceReader;
11+
import java.io.IOException;
12+
13+
@ChangeLog
14+
public class DatabaseChangelog {
15+
16+
17+
@ChangeSet(order = "001", id = "createShipmentTable", author = "anca")
18+
public void createShipmentTable(AmazonDynamoDB amazonDynamoDB) {
19+
DynamoDB dynamoDB = new DynamoDB(amazonDynamoDB);
20+
21+
ChangelogHelper.createTable(dynamoDB, "shipment", 10L,
22+
5L, "shipmentId", "S");
23+
}
24+
25+
@ChangeSet(order = "002", id = "createShipmentData", author = "anca")
26+
public void createShipmentData(AmazonDynamoDB amazonDynamoDB, DynamoDBMapper dynamoDBMapper)
27+
throws IOException {
28+
29+
// Some sample data to have at startup
30+
final ObjectMapper objectMapper = new ObjectMapper();
31+
Shipment[] shipmentList = objectMapper.readValue(
32+
ResourceReader.readFileToString("data/sample_shipments.json"), Shipment[].class);
33+
dynamoDBMapper.batchSave(shipmentList);
34+
}
35+
}
36+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package dev.ancaghenade.shipmentlistdemo.config;
2+
3+
import com.amazonaws.auth.AWSCredentials;
4+
import com.amazonaws.auth.AWSStaticCredentialsProvider;
5+
import com.amazonaws.auth.BasicAWSCredentials;
6+
import com.amazonaws.services.s3.AmazonS3;
7+
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
8+
import org.springframework.beans.factory.annotation.Value;
9+
import org.springframework.context.annotation.Bean;
10+
import org.springframework.context.annotation.Configuration;
11+
12+
@Configuration
13+
public class AmazonS3Config {
14+
15+
@Value("${aws.access.key}")
16+
private String awsAccessKey;
17+
18+
@Value("${aws.access.secret-key}")
19+
private String awsSecretKey;
20+
21+
@Value("${aws.region}")
22+
private String awsRegion;
23+
24+
@Bean
25+
public AmazonS3 s3() {
26+
AWSCredentials awsCredentials = new BasicAWSCredentials(
27+
awsAccessKey,
28+
awsSecretKey
29+
);
30+
return AmazonS3ClientBuilder
31+
.standard()
32+
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
33+
.withRegion(awsRegion)
34+
.build();
35+
}
36+
37+
}

0 commit comments

Comments
 (0)