|
| 1 | +# AGENTS.md - Development Guidelines for AI Coding Agents |
| 2 | + |
| 3 | +This document provides comprehensive guidelines for AI coding agents working on the **Jikkou** project - an open-source Resource as Code framework for Apache Kafka. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**Jikkou** is a Java based multi-module Maven project that provides Infrastructure as Code management for Apache Kafka resources. It's designed with a kubectl-inspired approach for managing Topics, ACLs, Quotas, Schemas, and Connectors. |
| 8 | + |
| 9 | +- **Language**: Java 25 |
| 10 | +- **Build System**: Maven (multi-module) |
| 11 | +- **Architecture**: Micronaut-based CLI and API server |
| 12 | +- **Distribution**: Native binaries (GraalVM), JAR, Docker |
| 13 | + |
| 14 | +## Project Structure |
| 15 | + |
| 16 | +``` |
| 17 | +jikkou/ |
| 18 | +├── cli/ # Command-line interface (main entry) |
| 19 | +├── core/ # Core APIs and engine |
| 20 | +├── server/ # REST API server components |
| 21 | +├── providers/ # Resource provider implementations |
| 22 | +├── template-jinja/ # Jinja templating support |
| 23 | +├── extension-rest-client/ # REST client extensions |
| 24 | +├── resource-generator/ # Resource generation utilities |
| 25 | +└── processor/ # Processing components |
| 26 | +``` |
| 27 | + |
| 28 | +**Main Entry Points**: |
| 29 | +- CLI: `io.streamthoughts.jikkou.client.Jikkou` |
| 30 | +- Server: `io.streamthoughts.jikkou.rest.JikkouApiServer` |
| 31 | + |
| 32 | +## Build, Test, and Lint Commands |
| 33 | + |
| 34 | +### Build Commands |
| 35 | +```bash |
| 36 | +# Full build with tests |
| 37 | +./mvnw clean verify |
| 38 | + |
| 39 | +# Build without tests |
| 40 | +./mvnw clean verify -DskipTests |
| 41 | + |
| 42 | +# Build specific module |
| 43 | +./mvnw clean verify -pl cli |
| 44 | + |
| 45 | +# Native build (requires GraalVM) |
| 46 | +./mvnw clean verify -Pnative |
| 47 | + |
| 48 | +# Docker image build |
| 49 | +make |
| 50 | +``` |
| 51 | + |
| 52 | +### Test Commands |
| 53 | +```bash |
| 54 | +# Run all tests (unit + integration) |
| 55 | +./mvnw test |
| 56 | + |
| 57 | +# Run unit tests only |
| 58 | +./mvnw surefire:test |
| 59 | + |
| 60 | +# Run integration tests only |
| 61 | +./mvnw failsafe:integration-test |
| 62 | + |
| 63 | +# Run single test class |
| 64 | +./mvnw test -Dtest=ClassNameTest |
| 65 | + |
| 66 | +# Run single test method |
| 67 | +./mvnw test -Dtest=ClassNameTest#methodName |
| 68 | + |
| 69 | +# Run tests for specific module |
| 70 | +./mvnw test -pl core |
| 71 | + |
| 72 | +# Run tests with specific profile |
| 73 | +./mvnw test -P native |
| 74 | +``` |
| 75 | + |
| 76 | +### Lint and Code Quality |
| 77 | +```bash |
| 78 | +# Apply code formatting |
| 79 | +./mvnw spotless:apply |
| 80 | + |
| 81 | +# Check code formatting |
| 82 | +./mvnw spotless:check |
| 83 | + |
| 84 | +# Run SpotBugs analysis |
| 85 | +./mvnw spotbugs:check |
| 86 | + |
| 87 | +# Generate coverage report |
| 88 | +./mvnw jacoco:report |
| 89 | +``` |
| 90 | + |
| 91 | +## Code Style Guidelines |
| 92 | + |
| 93 | +### Import Organization |
| 94 | +- Use **standard import order** (enforced by Spotless) |
| 95 | +- Remove unused imports automatically |
| 96 | +- Static imports should be grouped separately and placed after regular imports |
| 97 | +- Example ordering: |
| 98 | +```java |
| 99 | +import static picocli.CommandLine.Model.CommandSpec; |
| 100 | +import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_COMMAND_LIST; |
| 101 | + |
| 102 | +import io.micronaut.configuration.picocli.MicronautFactory; |
| 103 | +import io.streamthoughts.jikkou.client.banner.Banner; |
| 104 | +import jakarta.inject.Singleton; |
| 105 | +import java.io.PrintWriter; |
| 106 | +import java.util.ArrayList; |
| 107 | +import org.jetbrains.annotations.NotNull; |
| 108 | +``` |
| 109 | + |
| 110 | +### Formatting Standards |
| 111 | +- **Indentation**: 4 spaces (no tabs) |
| 112 | +- **Line Length**: 120 characters maximum |
| 113 | +- **Encoding**: UTF-8 |
| 114 | +- **License Header**: Apache 2.0 (enforced by Spotless) |
| 115 | +```java |
| 116 | +/* |
| 117 | + * SPDX-License-Identifier: Apache-2.0 |
| 118 | + * Copyright (c) The original authors |
| 119 | + * |
| 120 | + * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 |
| 121 | + */ |
| 122 | +``` |
| 123 | + |
| 124 | +### Type System |
| 125 | +- Use **Java 25 features** appropriately (records, pattern matching, etc.) |
| 126 | +- Prefer **immutable objects** and **builder patterns** |
| 127 | +- Use **generic types** with proper bounds |
| 128 | +- Annotate with `@NotNull` and `@Nullable` from JetBrains annotations |
| 129 | +- Example: |
| 130 | +```java |
| 131 | +public interface ApiBuilder<A extends JikkouApi, B extends JikkouApi.ApiBuilder<A, B>> { |
| 132 | + B register(@NotNull ExtensionProvider provider); |
| 133 | +} |
| 134 | +``` |
| 135 | + |
| 136 | +### Naming Conventions |
| 137 | +- **Classes**: PascalCase (e.g., `JikkouApi`, `ResourceTemplateRenderer`) |
| 138 | +- **Methods/Variables**: camelCase (e.g., `getResourceTypes`, `extensionProvider`) |
| 139 | +- **Constants**: SCREAMING_SNAKE_CASE (e.g., `SECTION_KEY_COMMAND_LIST`) |
| 140 | +- **Packages**: lowercase with dots (e.g., `io.streamthoughts.jikkou.core`) |
| 141 | +- **Test Classes**: Suffix with `Test` (e.g., `JikkouApiTest`) |
| 142 | +- **Integration Tests**: Suffix with `IT` (e.g., `KafkaProviderIT`) |
| 143 | + |
| 144 | +### Error Handling |
| 145 | +- Use **custom exception hierarchies** extending `JikkouApiException` |
| 146 | +- Include **meaningful error messages** with context |
| 147 | +- Prefer **checked exceptions** for recoverable errors |
| 148 | +- Use **runtime exceptions** for programming errors |
| 149 | +- Example: |
| 150 | +```java |
| 151 | +public class ResourceNotFoundException extends JikkouApiException { |
| 152 | + public ResourceNotFoundException(String message, Object... args) { |
| 153 | + super(String.format(message, args)); |
| 154 | + } |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +### Dependency Injection |
| 159 | +- Use **Micronaut annotations** (`@Singleton`, `@Inject`) |
| 160 | +- Prefer **constructor injection** over field injection |
| 161 | +- Use **factory patterns** for complex object creation |
| 162 | +- Example: |
| 163 | +```java |
| 164 | +@Singleton |
| 165 | +public class ApiExtensionCommand { |
| 166 | + private final JikkouApi api; |
| 167 | + |
| 168 | + public ApiExtensionCommand(JikkouApi api) { |
| 169 | + this.api = api; |
| 170 | + } |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +## Testing Guidelines |
| 175 | + |
| 176 | +### Test Structure |
| 177 | +- **Unit Tests**: `src/test/java/` |
| 178 | +- **Integration Tests**: `src/integration-test/java/` |
| 179 | +- Use **JUnit 5** as primary testing framework |
| 180 | +- Use **TestContainers** for integration tests requiring external services |
| 181 | +- Use **Mockito** for mocking dependencies |
| 182 | + |
| 183 | +### Test Naming |
| 184 | +```java |
| 185 | +class JikkouApiTest { |
| 186 | + @Test |
| 187 | + void shouldReturnResourceTypes_whenValidProviderRegistered() { |
| 188 | + // Test implementation |
| 189 | + } |
| 190 | + |
| 191 | + @Test |
| 192 | + void shouldThrowResourceNotFoundException_whenResourceNotFound() { |
| 193 | + // Test implementation |
| 194 | + } |
| 195 | +} |
| 196 | +``` |
| 197 | + |
| 198 | +### Test Categories |
| 199 | +- **@Test**: Standard unit tests |
| 200 | +- **@ParameterizedTest**: Data-driven tests |
| 201 | +- **@TestMethodOrder**: For ordered test execution |
| 202 | +- **@TestContainers**: For integration tests with Docker |
| 203 | + |
| 204 | +## Documentation Standards |
| 205 | + |
| 206 | +### JavaDoc |
| 207 | +- **Public APIs** must have comprehensive JavaDoc |
| 208 | +- Include `@param`, `@return`, `@throws` annotations |
| 209 | +- Use `@since` for version information |
| 210 | +- Example: |
| 211 | +```java |
| 212 | +/** |
| 213 | + * Registers an extension provider with the given configuration. |
| 214 | + * <p> |
| 215 | + * This method is responsible for registering all extensions and resources |
| 216 | + * provided by the given provider. |
| 217 | + * |
| 218 | + * @param provider the provider. |
| 219 | + * @param configuration the configuration. |
| 220 | + * @return the builder. |
| 221 | + * @throws ConflictingExtensionDefinitionException if provider conflicts |
| 222 | + * @since 0.35.0 |
| 223 | + */ |
| 224 | +``` |
| 225 | + |
| 226 | +### Code Comments |
| 227 | +- Use `//` for single-line comments |
| 228 | +- Use `/* */` for multi-line explanations |
| 229 | +- Explain **why**, not **what** |
| 230 | +- Document complex algorithms and business logic |
| 231 | + |
| 232 | +## Configuration Management |
| 233 | + |
| 234 | +### Application Configuration |
| 235 | +- Use **TypeSafe Config** for configuration management |
| 236 | +- Support **YAML** and **properties** formats |
| 237 | +- Environment variable overrides supported |
| 238 | +- Configuration validation with Jakarta Validation |
| 239 | + |
| 240 | +### Module Configuration |
| 241 | +Each provider module follows this pattern: |
| 242 | +``` |
| 243 | +providers/jikkou-provider-{name}/ |
| 244 | +├── src/main/java/io/streamthoughts/jikkou/provider/{name}/ |
| 245 | +├── src/test/java/ |
| 246 | +├── src/integration-test/java/ |
| 247 | +└── pom.xml |
| 248 | +``` |
| 249 | + |
| 250 | +## Key Dependencies |
| 251 | + |
| 252 | +### Core Dependencies |
| 253 | +- **Micronaut**: Dependency injection and framework |
| 254 | +- **Picocli**: Command-line interface |
| 255 | +- **Jackson**: JSON/YAML serialization |
| 256 | +- **Kafka Client**: Apache Kafka integration |
| 257 | +- **Jinja**: Template rendering engine |
| 258 | + |
| 259 | +### Development Tools |
| 260 | +- **Spotless**: Code formatting and license headers |
| 261 | +- **SpotBugs**: Static analysis with security rules |
| 262 | +- **JaCoCo**: Code coverage reporting |
| 263 | +- **TestContainers**: Integration testing |
| 264 | + |
| 265 | +## Common Pitfalls and Best Practices |
| 266 | + |
| 267 | +### Performance Considerations |
| 268 | +- Use **reactive programming** with Reactor Core for I/O operations |
| 269 | +- Implement **proper resource management** (try-with-resources) |
| 270 | +- Consider **GraalVM native compilation** constraints |
| 271 | +- Avoid blocking operations in reactive streams |
| 272 | + |
| 273 | +### Security Guidelines |
| 274 | +- **Validate all inputs** with Jakarta Validation |
| 275 | +- Use **secure coding practices** (SpotBugs security rules enforced) |
| 276 | +- Handle **sensitive configuration** properly |
| 277 | +- Follow **least privilege** principle |
| 278 | + |
| 279 | +### Concurrency |
| 280 | +- Use **thread-safe collections** when needed |
| 281 | +- Prefer **immutable objects** to reduce synchronization |
| 282 | +- Use **CompletableFuture** for async operations |
| 283 | +- Consider **reactive patterns** over traditional threading |
| 284 | + |
| 285 | +## Pre-commit Checklist |
| 286 | + |
| 287 | +Before committing code, ensure: |
| 288 | +- [ ] Code compiles successfully: `./mvnw compile` |
| 289 | +- [ ] All tests pass: `./mvnw test` |
| 290 | +- [ ] Code formatting applied: `./mvnw spotless:apply` |
| 291 | +- [ ] No SpotBugs violations: `./mvnw spotbugs:check` |
| 292 | +- [ ] Integration tests pass (if applicable): `./mvnw verify` |
| 293 | +- [ ] License headers present on new files |
| 294 | +- [ ] JavaDoc added for public APIs |
| 295 | +- [ ] Commit message follows conventional format |
| 296 | + |
| 297 | +## Pull request guidelines |
| 298 | + |
| 299 | +Always add tests, keep your branch rebased instead of merged, |
| 300 | +and adhere to the commit message recommendations from https://www.conventionalcommits.org/en/v1.0.0. |
| 301 | + |
| 302 | +--- |
| 303 | + |
| 304 | +This document should be updated as the project evolves. For the most current information, refer to the [official documentation](https://streamthoughts.github.io/jikkou/). |
0 commit comments