Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# AI Agents Guide for Java Operator SDK

This document provides guidance for AI coding agents working with the Java Operator SDK codebase.

## Project Overview

Java Operator SDK is a production-ready framework for building Kubernetes Operators in Java. It provides:
- A controller runtime for reconciliation loops
- Support for dependent resources and workflows
- Testing utilities for operator development
- Integration with Fabric8 Kubernetes Client

**Key Technologies:**
- Java 17+ (currently Java 25)
- Maven for build management
- Fabric8 Kubernetes Client for K8s API access
- JUnit 5 for testing
- GitHub Actions for CI/CD

## Project Structure

### Core Modules

```
java-operator-sdk/
├── operator-framework-core/ # Core reconciliation engine and API
├── operator-framework/ # Main operator framework implementation
├── operator-framework-junit5/ # Testing utilities and extensions
├── operator-framework-bom/ # Bill of Materials for dependency management
├── micrometer-support/ # Metrics integration
├── open-telemetry-support/ # Distributed tracing support
├── caffeine-bounded-cache-support/ # Caching implementation
├── bootstrapper-maven-plugin/ # Maven plugin for bootstrapping
└── test-index-processor/ # Test utilities for annotation processing
```

### Key Packages

- `io.javaoperatorsdk.operator.api.reconciler` - Core reconciler interfaces and annotations
- `io.javaoperatorsdk.operator.processing` - Event processing and workflow engine
- `io.javaoperatorsdk.operator.processing.dependent` - Dependent resource management
- `io.javaoperatorsdk.operator.api.config` - Configuration interfaces
- `io.javaoperatorsdk.operator.junit` - Testing support classes

## Building and Testing

### Build Commands

```bash
# Full build with tests
./mvnw clean install

# Build without tests
./mvnw clean install -DskipTests

# Build without annotation processing (faster for development)
./mvnw clean install -Pno-apt

# Parallel build (uses 1 thread per CPU core)
./mvnw -T1C clean install

# Check code formatting
./mvnw spotless:check

# Apply code formatting
./mvnw spotless:apply

# Check license headers
./mvnw -N license:check
```

### Test Execution

```bash
# Run unit tests only
./mvnw test

# Run integration tests
./mvnw verify -Pit

# Run specific test class
./mvnw test -Dtest=ClassName

# Run specific test method
./mvnw test -Dtest=ClassName#methodName
```

### Performance Tests

Performance tests are located in `operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/performance/`

Results are saved to `target/performance_test_result.json` and include:
- Test duration in milliseconds
- Number of processors
- Maximum memory allocation
- Dynamic test parameters

## Code Conventions

### Code Style

- **Formatting:** The project uses Spotless with Google Java Format
- **License Headers:** All source files must have Apache 2.0 license headers
- **Line Length:** 100 characters maximum
- **Indentation:** 2 spaces (no tabs)

### Naming Conventions

- **Reconcilers:** End with `Reconciler` (e.g., `MyResourceReconciler`)
- **Dependent Resources:** End with `DependentResource` (e.g., `ConfigMapDependentResource`)
- **Test Classes:** End with `Test` for unit tests, `IT` for integration tests
- **Custom Resources:** Typically structured as `{Name}Spec`, `{Name}Status`, `{Name}` (the CR class)

### API Design

- Use builder patterns for complex configurations
- Prefer immutable objects where possible
- Use annotations for declarative configuration (`@ControllerConfiguration`, `@KubernetesDependent`, etc.)
- Follow fluent API design for DSLs

## Testing Guidelines

### Unit Tests

- Use JUnit 5
- Mock Kubernetes API interactions using Fabric8's mock server or Mockito
- Test reconciliation logic in isolation
- Place in `src/test/java`

### Integration Tests

- Use `LocallyRunOperatorExtension` or `OperatorExtension` from `operator-framework-junit5`
- Test against real Kubernetes API (typically via test cluster or mock server)
- Suffix with `IT` (e.g., `MyReconcilerIT`)
- Located in `src/test/java` or `src/it/java`

### Test Resources

- Kubernetes manifests in `src/test/resources` or `src/it/resources`
- Use `@KubernetesResourceYaml` annotation to load test resources
- Custom resources should extend `CustomResource<Spec, Status>`

## Common Patterns

### Reconciler Implementation

Reconcilers implement the `Reconciler<T>` interface:

```java
@ControllerConfiguration
public class MyReconciler implements Reconciler<MyCustomResource> {

@Override
public UpdateControl<MyCustomResource> reconcile(
MyCustomResource resource, Context<MyCustomResource> context) {
// Reconciliation logic
return UpdateControl.noUpdate();
}
}
```

### Dependent Resources

Dependent resources use the `DependentResource` interface or extend base classes:

```java
@KubernetesDependent
public class ConfigMapDependent extends CRUDKubernetesDependentResource<ConfigMap, Primary> {

@Override
protected ConfigMap desired(Primary primary, Context<Primary> context) {
// Return desired state
}
}
```

### Error Handling

- Use `UpdateControl` with `rescheduleAfter()` for retriable errors
- Throw `RuntimeException` for non-retriable errors
- Update resource status to reflect error conditions
- Use structured logging (SLF4J)

## Making Changes

### Before Submitting a PR

1. Run `./mvnw spotless:apply` to format code
2. Run `./mvnw clean install` to ensure all tests pass
3. Add tests for new functionality
4. Update documentation if adding/changing APIs
5. Follow existing code patterns and conventions

### PR Guidelines

- Keep changes focused and atomic
- Write clear commit messages (imperative mood: "Add feature" not "Added feature")
- Reference issues in commit messages when applicable
- Ensure CI checks pass (format, license, tests)

## Common Issues and Solutions

### Build Issues

- **Annotation processing errors:** Try building with `-Pno-apt` first
- **Test failures:** Check if Kubernetes context is needed for ITs
- **Formatting failures:** Run `./mvnw spotless:apply` before committing

### Test Issues

- **Integration tests hanging:** Check for resource leaks or improper cleanup
- **Flaky tests:** Ensure proper synchronization using `StatusChecker` or similar patterns
- **Performance test variance:** Results depend on available CPU/memory

## Resources

- **Documentation:** https://javaoperatorsdk.io/
- **GitHub:** https://github.com/operator-framework/java-operator-sdk
- **Slack:** [#java-operator-sdk](https://kubernetes.slack.com/archives/CAW0GV7A5) on Kubernetes Slack
- **Discord:** https://discord.gg/DacEhAy
- **Fabric8 Client:** https://github.com/fabric8io/kubernetes-client

## Performance Considerations

- Use caching appropriately (see `caffeine-bounded-cache-support`)
- Implement proper resource watches and informers
- Consider rate limiting for external API calls
- Use parallel processing where appropriate (`-T1C` for Maven builds)
- Monitor memory usage in performance tests

## Additional Notes for AI Agents

- The codebase uses extensive use of Java generics for type safety
- Context objects provide access to client, informers, and event sources
- The framework handles K8s API retries and conflict resolution automatically
- Prefer using `ResourceOperations` from context over direct client calls
- Status updates are handled separately from spec reconciliation
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AGENTS.md