Skip to content

Latest commit

 

History

History
157 lines (119 loc) · 5.88 KB

File metadata and controls

157 lines (119 loc) · 5.88 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Camunda 8 Developer Training repository containing hands-on exercises for learning Zeebe process orchestration, BPMN testing, distributed transaction patterns, and custom connector development. The project is a multi-module Maven build with exercises available in both Java and Kotlin.

Build System & Commands

Root level:

  • mvn clean install - Build all modules
  • mvn test - Run all tests across modules

Individual exercises:

  • Navigate to specific exercise directory (e.g., cd exercises/exercise-1-testing-java)
  • mvn test - Run tests for that exercise
  • mvn spring-boot:run - Run Spring Boot application (for exercises 2 and 3)

Infrastructure:

  • cd stack && docker-compose up -d - Start Camunda 8 stack (Zeebe, Operate, Tasklist, Connectors, PostgreSQL, Elasticsearch)
  • docker-compose down - Stop infrastructure
  • Access Camunda UI at http://localhost:8080 (credentials: demo/demo)

API Testing:

  • Bruno API collection available in bruno/ directory for testing process endpoints

Technology Stack

  • Java 21 & Kotlin
  • Spring Boot 3.4.1
  • Camunda 8 (Zeebe 8.8.2)
  • PostgreSQL 17.5 for persistence
  • H2 for test database
  • Mockito for mocking in tests
  • Maven for build management

Architecture Pattern: Hexagonal/Ports & Adapters

The codebase follows hexagonal architecture principles:

src/main/java/io/miragon/example/
├── adapter/           # Infrastructure layer
│   ├── in/           # Inbound adapters (REST controllers, message receivers)
│   ├── out/          # Outbound adapters (database, external APIs)
│   └── process/      # Process adapters (Zeebe workers, process message handling)
├── application/      # Application services (use cases)
└── domain/           # Core domain models and business logic

Key concepts:

  • Domain layer: Pure business logic, no framework dependencies
  • Application layer: Orchestrates domain objects and coordinates workflows
  • Adapter layer: Framework-specific implementations (Spring, Zeebe, JPA)
  • Inbound adapters: REST APIs, Zeebe workers that receive jobs
  • Outbound adapters: Database persistence, process engine clients, external services

Camunda 8 Process Testing

Exercises 1 (Java/Kotlin) focus on BPMN process testing using @CamundaSpringProcessTest:

Key testing patterns:

  • Use processTestContext.increaseTime(Duration) to trigger timer events
  • Message correlation: processPort.sendPaymentReceived(correlationKey)
  • Process assertions: assertThatProcessInstance(byKey(instanceKey)).isCompleted()
  • Element completion checks: hasCompletedElement(elementId, count)
  • Mock workers with Mockito to verify business logic invocation

Test scenarios covered:

  • Happy path flows
  • Error/cancellation paths
  • Timer-triggered events (reminders, timeouts)
  • Message correlation patterns
  • End-to-end integration tests

Distributed Patterns (Exercise 2)

Outbox Pattern:

  • Ensures reliable message delivery to Zeebe by storing messages in database first
  • ProcessMessageEntity with status (PENDING → SENT)
  • Background scheduler (ProcessEngineOutboxScheduler) processes outbox every 200ms
  • Uses pessimistic locking (@Lock(LockModeType.PESSIMISTIC_WRITE)) to prevent race conditions
  • Database write + outbox write = same transaction = guaranteed delivery

Idempotency Pattern:

  • Prevents duplicate operations from job retries
  • ProcessedOperationEntity tracks completed operations with composite key (subscriptionId + elementId)
  • Check-Execute-Record pattern in workers:
    1. Check if operation already processed
    2. Execute business logic
    3. Record operation as completed (in same transaction)

Custom Connector Development (Exercise 3)

Exercise 3 teaches building custom Camunda outbound connectors:

Key principles:

  • Keep BPMN clean by encapsulating technical complexity in connectors
  • Use domain-focused activities in process models (e.g., "Notify Customer" instead of "Send Email via SendGrid")
  • Connectors should be reusable and environment-agnostic
  • Implement hexagonal architecture in connectors to decouple external APIs from business logic
  • Separate input/output adapters for vendor-specific implementations

BPMN Resources

Process definitions are located in src/main/resources/bpmn/:

  • newsletter.bpmn - Newsletter subscription process (completed reference)
  • bike-subscription.bpmn - Bike subscription process (exercise to implement)

Database Access

PostgreSQL runs on localhost:5432 (credentials: admin/admin):

-- Monitor outbox pattern
SELECT * FROM process_message ORDER BY created_at DESC;

-- Monitor idempotency tracking
SELECT * FROM processed_operations ORDER BY processed_at DESC;

Common Patterns

Zeebe Worker Implementation:

@JobWorker(type = "check-bike-availability")
public void checkAvailability(ActivatedJob job) {
    // Extract variables
    var subscriptionId = job.getVariableAsType("subscriptionId", String.class);

    // Business logic
    var isAvailable = useCase.checkAvailability(subscriptionId);

    // Complete job with result
    client.newCompleteCommand(job)
        .variables(Map.of("available", isAvailable))
        .send();
}

Process Port Pattern: Process interaction abstraction separates BPMN engine details from application layer. Implement ProcessPort interface in adapter layer.

Testing Strategy

  • Unit tests for domain logic (pure Java/Kotlin)
  • Integration tests for adapters with mocked dependencies
  • Process tests using camunda-process-test-spring with in-memory engine
  • Use @SpringBootTest with H2 database for full integration tests
  • Mock external dependencies (email services, APIs) in tests

Version Information

  • Camunda Platform: 8.8.9
  • Zeebe: 8.8.2
  • Elasticsearch: 8.17.0
  • Camunda Connectors: 8.8.5