Skip to content

Commit 1efa7de

Browse files
author
Yuriy Bezsonov
committed
restrcuturing
1 parent be49404 commit 1efa7de

37 files changed

Lines changed: 2570 additions & 0 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# EditorConfig for consistent coding styles across IDEs
2+
# https://editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
end_of_line = lf
9+
indent_style = space
10+
indent_size = 4
11+
insert_final_newline = true
12+
trim_trailing_whitespace = true
13+
14+
[*.java]
15+
indent_size = 4
16+
17+
[*.xml]
18+
indent_size = 4
19+
20+
[*.{yml,yaml}]
21+
indent_size = 2
22+
23+
[*.md]
24+
trim_trailing_whitespace = true
25+
26+
[Dockerfile*]
27+
indent_size = 4
4 Bytes
Binary file not shown.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM public.ecr.aws/docker/library/maven:3-amazoncorretto-25-al2023 AS builder
2+
3+
RUN yum install -y shadow-utils
4+
5+
COPY store-spring.jar store-spring.jar
6+
7+
RUN groupadd --system spring -g 1000
8+
RUN adduser spring -u 1000 -g 1000
9+
10+
USER 1000:1000
11+
12+
EXPOSE 8080
13+
ENTRYPOINT ["java","-jar","-Dserver.port=8080","/store-spring.jar"]
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Unicorn Store - Java 25 + Spring Boot 4
2+
3+
A REST API for managing unicorns, built to showcase modern Java features and container optimization techniques.
4+
5+
## Architecture
6+
7+
```
8+
┌─────────────────────────────────────────────────────────────┐
9+
│ HTTP Request │
10+
└─────────────────────────────────────────────────────────────┘
11+
12+
13+
┌─────────────────────────────────────────────────────────────┐
14+
│ RequestContextFilter │
15+
│ - Generates unique request ID │
16+
│ - Binds to ScopedValue (JEP 506) for request duration │
17+
└─────────────────────────────────────────────────────────────┘
18+
19+
20+
┌─────────────────────────────────────────────────────────────┐
21+
│ UnicornController │
22+
│ - REST endpoints: GET/POST/PUT/DELETE /unicorns │
23+
│ - Input validation, error handling │
24+
└─────────────────────────────────────────────────────────────┘
25+
26+
27+
┌─────────────────────────────────────────────────────────────┐
28+
│ UnicornService │
29+
│ - Business logic, validation │
30+
│ - Reads request ID from ScopedValue for log correlation │
31+
│ - Publishes events to EventBridge │
32+
└─────────────────────────────────────────────────────────────┘
33+
34+
┌───────────────┴───────────────┐
35+
▼ ▼
36+
┌─────────────────────────┐ ┌─────────────────────────┐
37+
│ UnicornRepository │ │ UnicornPublisher │
38+
│ - Spring Data JPA │ │ - EventBridge async │
39+
│ - PostgreSQL │ │ - CRUD events │
40+
└─────────────────────────┘ └─────────────────────────┘
41+
```
42+
43+
## Project Structure
44+
45+
```
46+
src/main/java/com/unicorn/store/
47+
├── StoreApplication.java # Spring Boot entry point
48+
├── context/
49+
│ └── RequestContext.java # ScopedValue holder (JEP 506)
50+
├── filter/
51+
│ └── RequestContextFilter.java # Binds request ID to ScopedValue
52+
├── controller/
53+
│ └── UnicornController.java # REST API endpoints
54+
├── service/
55+
│ └── UnicornService.java # Business logic
56+
├── data/
57+
│ ├── UnicornRepository.java # Spring Data JPA
58+
│ └── UnicornPublisher.java # EventBridge integration
59+
├── model/
60+
│ └── Unicorn.java # JPA entity
61+
└── config/
62+
└── MonitoringConfig.java # Metrics for EKS/ECS
63+
```
64+
65+
## Modern Java Features
66+
67+
| Feature | JEP | Location | Description |
68+
|---------|-----|----------|-------------|
69+
| Scoped Values | [506](https://openjdk.org/jeps/506) | `RequestContext`, `RequestContextFilter` | Thread-safe request context without ThreadLocal |
70+
| Flexible Constructor Bodies | [513](https://openjdk.org/jeps/513) | `Unicorn` constructor | Validation before super() call |
71+
| Unnamed Variables | 456 | catch blocks | `catch (Exception _)` when variable unused |
72+
| Sequenced Collections | 431 | `UnicornService.getAllUnicorns()` | `getFirst()`, `getLast()` methods |
73+
| Pattern Matching | 441 | `UnicornService.validateUnicorn()` | Switch with guarded patterns |
74+
| Virtual Threads | 444 | `application.yaml` | `spring.threads.virtual.enabled: true` |
75+
| Text Blocks | 378 | `UnicornController` | Multi-line strings |
76+
77+
## Testing
78+
79+
```bash
80+
# Run all tests (26 total)
81+
mvn test
82+
83+
# Tests use Testcontainers 2.0 with H2 fallback when Docker unavailable
84+
```
85+
86+
**Test Infrastructure:**
87+
- `@TestInfrastructure` - unified annotation for integration tests
88+
- PostgreSQL via Testcontainers, H2 fallback without Docker
89+
- LocalStack for EventBridge
90+
- Property-based tests with jqwik for validation logic
91+
92+
## Building
93+
94+
```bash
95+
mvn package # Standard JAR
96+
mvn package -Pnative # Native image (GraalVM)
97+
mvn jib:dockerBuild # Container with Jib
98+
```
99+
100+
## API Endpoints
101+
102+
| Method | Endpoint | Description |
103+
|--------|----------|-------------|
104+
| GET | `/unicorns` | List all unicorns |
105+
| POST | `/unicorns` | Create unicorn |
106+
| GET | `/unicorns/{id}` | Get by ID |
107+
| PUT | `/unicorns/{id}` | Update unicorn |
108+
| DELETE | `/unicorns/{id}` | Delete unicorn |
109+
| GET | `/actuator/health` | Health check |
110+
| GET | `/actuator/prometheus` | Metrics |

0 commit comments

Comments
 (0)