Skip to content

Commit bbc4f0f

Browse files
authored
Merge pull request #2966 from adobe/5.0.0-maintenance-ctd-2
5.0.0 maintenance
2 parents 78ccc39 + 29d656c commit bbc4f0f

File tree

20 files changed

+1458
-1168
lines changed

20 files changed

+1458
-1168
lines changed

.claude/skills/document/SKILL.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
name: document
3+
description: Generate or update project documentation. Use when asked to document code, create docs, or explain features.
4+
---
5+
6+
# Documentation Skill — S3Mock
7+
8+
Generate and maintain documentation for the S3Mock project.
9+
10+
## When to Use
11+
12+
- Creating or updating README.md
13+
- Updating the CHANGELOG.md for new features/fixes
14+
- Updating the S3 operations support table
15+
- Documenting new configuration options
16+
- Updating AGENTS.md files when architecture changes
17+
18+
## Pre-Flight Checklist
19+
20+
- [ ] Read existing `AGENTS.md` for project conventions and structure
21+
- [ ] Review the documentation being updated for current style and tone
22+
- [ ] Identify target audience (end users for README, agents for AGENTS.md, contributors for CONTRIBUTING.md)
23+
24+
## S3Mock Documentation Structure
25+
26+
| File | Audience | Purpose |
27+
|------|----------|---------|
28+
| `README.md` | End users & contributors | Usage, configuration, quick start |
29+
| `CHANGELOG.md` | End users | Version history, breaking changes, migration notes |
30+
| `AGENTS.md` (root) | AI agents & contributors | Architecture, code style, DO/DON'T guardrails |
31+
| `server/AGENTS.md` | AI agents | Server module implementation details |
32+
| `integration-tests/AGENTS.md` | AI agents | Integration test patterns and helpers |
33+
| `testsupport/AGENTS.md` | AI agents | Test framework integration details |
34+
| `.github/CONTRIBUTING.md` | Contributors | How to contribute, dev setup, code reviews |
35+
| `.github/SECURITY.md` | Security researchers | Vulnerability reporting, supported versions |
36+
| `.github/CODEOWNERS` | GitHub | Automatic PR review assignment |
37+
| `.github/ISSUE_TEMPLATE/*.yml` | Users & contributors | Structured bug reports and feature requests |
38+
39+
## Documentation Tasks
40+
41+
### When a New S3 Operation is Implemented
42+
1. Update the **operations table** in `README.md` — change `:x:` to `:white_check_mark:` for the operation
43+
2. Add a CHANGELOG entry under the current version section in `CHANGELOG.md`
44+
3. Update `server/AGENTS.md` if the implementation introduces new patterns
45+
46+
### When Configuration Changes
47+
1. Update the **Configuration table** in `README.md`
48+
2. Update the **Configuration section** in `AGENTS.md`
49+
3. Add a CHANGELOG entry
50+
51+
### When Architecture Changes
52+
1. Update the relevant module's `AGENTS.md`
53+
2. Update the root `AGENTS.md` if the change affects the overall structure
54+
3. Add a CHANGELOG entry for breaking changes
55+
56+
### CHANGELOG Format
57+
Follow the existing pattern in `CHANGELOG.md`:
58+
- Group changes under the current version heading (e.g., `## 5.0.0`)
59+
- Use clear, user-facing language
60+
- Note breaking changes prominently
61+
- Reference related GitHub issues or PRs
62+
63+
## Writing Style
64+
65+
- **Concise**: Short sentences, active voice
66+
- **Code examples**: Include runnable examples where possible (Kotlin for API, shell for CLI)
67+
- **Links**: Reference AWS S3 API docs for operations, link to source files for implementations
68+
- **Consistent**: Match existing formatting — Markdown headings, table alignment, badge style
69+
70+
## Post-Flight Checklist
71+
72+
- [ ] Technical accuracy verified against source code
73+
- [ ] Code examples compile/run correctly
74+
- [ ] Links are valid (internal file paths, external URLs)
75+
- [ ] Consistent style with surrounding documentation
76+
- [ ] Markdown renders correctly (tables, code blocks, badges)
77+
- [ ] No outdated version numbers or deprecated references
78+
79+
## Output
80+
81+
Provide documentation ready to integrate into the appropriate project files, matching existing conventions.

.claude/skills/implement/SKILL.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
name: implement
3+
description: Implement features, fix bugs, or refactor code. Use when asked to add functionality, modify code, or improve structure.
4+
---
5+
6+
# Implementation Skill — S3Mock
7+
8+
Implement features and fix bugs in the S3Mock project (Kotlin 2.3, Spring Boot 4.0.x, Maven).
9+
10+
## When to Use
11+
12+
- Adding new S3 API operations
13+
- Fixing bugs in existing operations
14+
- Refactoring server, service, or store layers
15+
- Updating DTOs or XML serialization
16+
17+
## Pre-Flight Checklist
18+
19+
- [ ] Read the root `AGENTS.md` — especially the DO/DON'T section
20+
- [ ] Read the module-specific `AGENTS.md` (`server/AGENTS.md`, etc.)
21+
- [ ] Check `CHANGELOG.md` for planned changes or deprecations
22+
- [ ] Identify which S3 API operation is being implemented (check [AWS docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html))
23+
- [ ] Review existing similar implementations in the codebase
24+
25+
## Implementation Flow for New S3 Operations
26+
27+
Follow the **DTO → Store → Service → Controller** layered architecture:
28+
29+
### 1. DTO (`server/src/main/kotlin/com/adobe/testing/s3mock/dto/`)
30+
- Create request/response data classes with Jackson XML annotations
31+
- Use `@JacksonXmlRootElement(localName = "...")` matching the AWS API element name exactly
32+
- Use `@JacksonXmlProperty(localName = "...")` for properties
33+
- Use `@JacksonXmlElementWrapper(useWrapping = false)` for collections
34+
- Verify naming against [AWS S3 API docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
35+
36+
### 2. Store (`server/src/main/kotlin/com/adobe/testing/s3mock/store/`)
37+
- Add filesystem operations to `BucketStore` or `ObjectStore`
38+
- Follow existing patterns for metadata JSON and binary data storage
39+
- Handle file I/O with proper error handling
40+
41+
### 3. Service (`server/src/main/kotlin/com/adobe/testing/s3mock/service/`)
42+
- Add business logic, validation, and store coordination
43+
- Throw S3 exceptions (`NoSuchBucketException`, `NoSuchKeyException`, etc.)
44+
- Use constructor injection for dependencies
45+
46+
### 4. Controller (`server/src/main/kotlin/com/adobe/testing/s3mock/controller/`)
47+
- Add HTTP endpoint mapping (`@GetMapping`, `@PutMapping`, etc.)
48+
- Controllers only map HTTP — delegate all logic to services
49+
- Return proper HTTP status codes and headers (ETag, Content-Type, etc.)
50+
51+
## Code Standards
52+
53+
- **Language**: Kotlin 2.3, JVM target 17
54+
- **DI**: Constructor injection only — never `@Autowired` or field injection
55+
- **DTOs**: Data classes with `val` properties
56+
- **Null safety**: Use `?`, `?.`, `?:` — avoid `!!`
57+
- **Functions**: Expression bodies for simple functions
58+
- **Dependencies**: Prefer Kotlin stdlib over third-party libraries
59+
- **Versions**: All dependency versions in root `pom.xml` only
60+
61+
## Post-Flight Checklist
62+
63+
- [ ] Run `./mvnw ktlint:format` to fix code style
64+
- [ ] Run `./mvnw clean install` to verify build
65+
- [ ] Verify no checkstyle violations
66+
- [ ] Add/update unit tests (`*Test.kt`) for new service/store logic
67+
- [ ] Add/update integration tests (`*IT.kt`) for new endpoints
68+
- [ ] Update `CHANGELOG.md` under the current version section
69+
- [ ] Update the operations table in `README.md` if a new S3 operation was added
70+
71+
## Troubleshooting
72+
73+
- **Build fails**: Check Java version (`java -version` — needs 25), run `./mvnw ktlint:format`
74+
- **Checkstyle fails**: Review rules in `etc/checkstyle.xml` — common issues are import ordering and missing Javadoc
75+
- **Tests fail after changes**: Ensure XML serialization matches AWS API exactly — compare element names against [AWS docs](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
76+
- **Docker build fails**: Try `./mvnw clean install -DskipDocker` first to isolate the issue
77+
78+
## Output
79+
80+
Provide clean, well-structured Kotlin code following the layered architecture and project conventions defined in AGENTS.md.

.claude/skills/test/SKILL.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
name: test
3+
description: Write, update, or fix tests. Use when asked to test code, create test cases, or debug failing tests.
4+
---
5+
6+
# Test Skill — S3Mock
7+
8+
Create and maintain tests for S3Mock (JUnit 5, Mockito, AssertJ, AWS SDK v2).
9+
10+
## When to Use
11+
12+
- Writing new unit or integration tests
13+
- Fixing failing tests
14+
- Adding test coverage for S3 operations
15+
- Creating test fixtures or helpers
16+
17+
## Pre-Flight Checklist
18+
19+
- [ ] Read `AGENTS.md` — especially DO/DON'T and Testing sections
20+
- [ ] Identify test type needed (unit vs. integration — see below)
21+
- [ ] Review existing test patterns in the target module
22+
- [ ] For integration tests, review `S3TestBase` for available helpers
23+
24+
## Test Types in S3Mock
25+
26+
### Unit Tests (`*Test.kt`)
27+
- **Location**: `server/src/test/kotlin/com/adobe/testing/s3mock/`
28+
- **Framework**: JUnit 5 + `@SpringBootTest` with `@MockitoBean` for mocking
29+
- **Assertions**: AssertJ (`assertThat(...)`)
30+
- **Purpose**: Test services and stores in isolation with Spring context and mocked dependencies
31+
- **Pattern**:
32+
```kotlin
33+
@SpringBootTest(classes = [ServiceConfiguration::class], webEnvironment = SpringBootTest.WebEnvironment.NONE)
34+
@MockitoBean(types = [BucketService::class, MultipartService::class, MultipartStore::class])
35+
internal class ObjectServiceTest : ServiceTestBase() {
36+
@Autowired
37+
private lateinit var iut: ObjectService
38+
39+
@Test
40+
fun `should delete object`() {
41+
val bucketName = "bucket"
42+
val key = "key"
43+
givenBucketWithContents(bucketName, "", listOf(givenS3Object(key)))
44+
45+
iut.deleteObject(bucketName, key)
46+
47+
assertThat(iut.getObject(bucketName, key)).isNull()
48+
}
49+
}
50+
```
51+
52+
### Integration Tests (`*IT.kt`)
53+
- **Location**: `integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/`
54+
- **Base class**: Extend `S3TestBase` for access to pre-configured `s3Client` (AWS SDK v2)
55+
- **Assertions**: AssertJ
56+
- **Purpose**: Test S3Mock end-to-end with real AWS SDK clients against the Docker container
57+
- **Pattern**:
58+
```kotlin
59+
internal class MyFeatureIT : S3TestBase() {
60+
@Test
61+
fun `should perform operation`(testInfo: TestInfo) {
62+
// Arrange — always use unique bucket names
63+
val bucketName = givenBucket(testInfo)
64+
65+
// Act
66+
s3Client.putObject(
67+
PutObjectRequest.builder().bucket(bucketName).key("key").build(),
68+
RequestBody.fromString("content")
69+
)
70+
71+
// Assert
72+
val response = s3Client.getObject(
73+
GetObjectRequest.builder().bucket(bucketName).key("key").build()
74+
)
75+
assertThat(response.readAllBytes().decodeToString()).isEqualTo("content")
76+
}
77+
}
78+
```
79+
80+
## Test Standards
81+
82+
- **Naming**: Use backtick names with descriptive sentences: `` fun `should create bucket successfully`() ``
83+
- Legacy `testSomething` camelCase naming exists in older tests — refactor to backtick style when touching those tests
84+
- **Independence**: Each test creates its own resources — never share state between tests
85+
- **Bucket names**: Use `givenBucket(testInfo)` from `S3TestBase` in integration tests for unique names
86+
- **Arrange-Act-Assert**: Follow this pattern consistently
87+
- **Both paths**: Test success cases AND error/exception cases
88+
- **Error assertions**: Use `assertThatThrownBy { ... }.isInstanceOf(AwsServiceException::class.java)` (AssertJ), not `assertThrows`
89+
- **SDK version**: Use AWS SDK v2 (`s3Client`) only — SDK v1 has been removed
90+
- **No JUnit 4**: Use JUnit 5 exclusively (`@Test` from `org.junit.jupiter.api`)
91+
- **Visibility**: Mark test classes as `internal`
92+
- **No MockitoExtension**: Use `@SpringBootTest` with `@MockitoBean` for mocking — never `@ExtendWith(MockitoExtension::class)`
93+
- **Mocking**: Use `@MockitoBean` (class-level `types` or field-level) instead of `@Mock` / `@InjectMocks`
94+
- **Injection**: Use `@Autowired` for the class under test in Spring Boot tests
95+
96+
## Running Tests
97+
98+
```bash
99+
# Unit tests (server module)
100+
./mvnw test -pl server
101+
102+
# All integration tests
103+
./mvnw verify -pl integration-tests
104+
105+
# Specific integration test class
106+
./mvnw verify -pl integration-tests -Dit.test=BucketIT
107+
108+
# Specific test method
109+
./mvnw verify -pl integration-tests -Dit.test=BucketIT#shouldCreateBucket
110+
111+
# Skip Docker (for unit tests only)
112+
./mvnw test -pl server -DskipDocker
113+
```
114+
115+
## Post-Flight Checklist
116+
117+
- [ ] Tests pass locally (`./mvnw test` or `./mvnw verify`)
118+
- [ ] Tests are independent (can run in any order)
119+
- [ ] Both success and failure cases covered
120+
- [ ] Assertions are specific (not just `isNotNull()`)
121+
- [ ] No hardcoded bucket names (use UUID)
122+
- [ ] Code style passes (`./mvnw ktlint:format`)
123+
124+
## Troubleshooting Failing Tests
125+
126+
- **Docker not running**: Integration tests require Docker — start Docker Desktop
127+
- **Port conflict**: Ports 9090/9191 may be in use — check with `lsof -i :9090`
128+
- **Flaky test**: Ensure test independence — check for shared state or ordering dependencies
129+
- **Compilation error**: Run `./mvnw clean install -DskipDocker -DskipTests` first
130+
131+
## Output
132+
133+
Provide complete, runnable Kotlin tests following S3Mock conventions and the Arrange-Act-Assert pattern.

.github/CODEOWNERS

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Default owner for everything in the repo
2+
* @afranken
3+
4+
# Core server implementation
5+
/server/ @afranken
6+
7+
# Integration tests
8+
/integration-tests/ @afranken
9+
10+
# Test support modules
11+
/testsupport/ @afranken
12+
13+
# Docker configuration
14+
/docker/ @afranken
15+
16+
# CI/CD and GitHub configuration
17+
/.github/ @afranken
18+
19+
# Build configuration
20+
/build-config/ @afranken

.github/CONTRIBUTING.md

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,66 @@ This project adheres to the Adobe [code of conduct](../CODE_OF_CONDUCT.md). By p
1212

1313
All third-party contributions to this project must be accompanied by a signed contributor license. This gives Adobe permission to redistribute your contributions as part of the project. Sign our [CLA](http://adobe.github.io/cla.html). You only need to submit an Adobe CLA one time, so if you have submitted one previously, you are good to go!
1414

15+
## Development Setup
16+
17+
**Prerequisites:**
18+
- Java 25 (compile version; targets JVM 17)
19+
- Maven 3.9+ (use the included `./mvnw` wrapper)
20+
- Docker (for Docker build and integration tests)
21+
22+
**Build and verify:**
23+
```shell
24+
# Full build with Docker
25+
./mvnw clean install
26+
27+
# Skip Docker (faster, for unit tests only)
28+
./mvnw clean install -DskipDocker
29+
30+
# Run integration tests
31+
./mvnw verify -pl integration-tests
32+
33+
# Format Kotlin code
34+
./mvnw ktlint:format
35+
```
36+
37+
## Architecture
38+
39+
S3Mock follows a **Controller - Service - Store** layered architecture. For detailed architecture documentation, code style guidelines, and project conventions, see the [AGENTS.md](../AGENTS.md) in the project root.
40+
41+
Module-specific documentation:
42+
- [Server Module](../server/AGENTS.md) - core implementation
43+
- [Integration Tests](../integration-tests/AGENTS.md) - test patterns
44+
- [Test Support](../testsupport/AGENTS.md) - framework integrations
45+
46+
## Code Style
47+
48+
- **Kotlin**: Enforced by ktlint - run `./mvnw ktlint:format` before submitting
49+
- **XML/Java**: Enforced by Checkstyle - configuration in [`etc/checkstyle.xml`](../etc/checkstyle.xml)
50+
- **Key conventions**: Constructor injection, data classes for DTOs, backtick test names, `val` over `var`
51+
- See the DO / DON'T section in [AGENTS.md](../AGENTS.md) for the full list
52+
1553
## Code Reviews
1654

1755
All submissions should come in the form of pull requests and need to be reviewed by project committers. Read [GitHub's pull request documentation](https://help.github.com/articles/about-pull-requests/) for more information on sending pull requests.
1856

19-
All submissions must include unit tests for any new functionality or bug fixes. If you are adding a new feature, please include a test that demonstrates the feature.
20-
S3Mock uses Unit tests for function coverage, Spring Boot tests for component coverage, and integration tests against the Docker container artefact for end-to-end coverage. Please ensure that your code is covered by at least one of these test types.
57+
## Testing
58+
59+
All submissions must include tests for any new functionality or bug fixes.
60+
61+
S3Mock uses three test levels:
62+
1. **Unit tests** (`*Test.kt`) - Spring Boot tests with `@MockitoBean` for mocking, in `server/src/test/`
63+
2. **Spring Boot tests** - component-level coverage with Spring context
64+
3. **Integration tests** (`*IT.kt`) - end-to-end tests against the Docker container using real AWS SDK v2 clients, in `integration-tests/src/test/`
65+
66+
Please ensure that your code is covered by at least one of these test types.
67+
68+
## Submitting Changes
69+
70+
1. Ensure all CI gates pass (build, tests, ktlint, checkstyle, Docker)
71+
2. Update [CHANGELOG.md](../CHANGELOG.md) under the current version section for user-facing changes
72+
3. Update documentation if applicable (README.md, AGENTS.md)
73+
4. Follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting
74+
75+
## Security
2176

22-
Lastly, please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting a pull request!
77+
To report security vulnerabilities, see the [Security Policy](SECURITY.md).

.github/ISSUE_TEMPLATE.md

Whitespace-only changes.

0 commit comments

Comments
 (0)