Intelligent warehouse wave creation and optimization service with multi-strategy algorithms, event-driven architecture, and hexagonal design.
The Wave Planning Service orchestrates the creation, optimization, and management of warehouse picking waves within the Paklog platform. This bounded context groups fulfillment orders into efficient waves based on various strategies including carrier cutoffs, zone optimization, and capacity constraints. It publishes domain events to integrate with downstream services like Task Execution, Pick Execution, and Workload Planning.
Wave Planning & Optimization - Manages the lifecycle of warehouse waves from creation through completion with intelligent grouping and optimization algorithms.
- Wave - Root aggregate representing a collection of orders for coordinated picking
- Order - Fulfillment order assigned to a wave
- WaveMetrics - Performance metrics for wave execution
- WaveStatus - Wave status enumeration (DRAFT, PLANNED, RELEASED, IN_PROGRESS, COMPLETED, CANCELLED)
- WaveType - Wave strategy type (TIME_BASED, CARRIER_BASED, ZONE_BASED, CAPACITY_BASED, PRIORITY_BASED)
- CarrierCutoff - Carrier shipping deadline configuration
- WaveCapacity - Wave size constraints
- Location - Warehouse location reference
- OptimizationCriteria - Multi-objective optimization parameters
- WaveCreatedEvent - New wave created
- WaveOptimizedEvent - Wave optimization completed
- WaveReleasedEvent - Wave released for execution
- WaveStartedEvent - Wave picking started
- WaveCompletedEvent - Wave execution completed
- WaveCancelledEvent - Wave cancelled
- WavesMergedEvent - Multiple waves merged
- Wave: Coordinated batch of orders for efficient warehouse picking
- Carrier Cutoff: Deadline for shipping via specific carrier
- Zone Optimization: Grouping orders by warehouse zones to minimize travel
- Wave Capacity: Maximum orders, lines, volume, or weight per wave
- Wave Release: Making wave available to warehouse for execution
- Travel Distance: Total distance pickers must travel to complete wave
- Multi-Objective Optimization: Balancing multiple factors (distance, SLA, workload)
src/main/java/com/paklog/wms/wave/
├── domain/ # Core business logic
│ ├── aggregate/ # Aggregates
│ │ └── Wave.java # Wave aggregate root
│ ├── entity/ # Entities
│ │ ├── Order.java # Order entity
│ │ └── WaveMetrics.java # Metrics entity
│ ├── valueobject/ # Value objects
│ │ ├── CarrierCutoff.java # Carrier deadline
│ │ ├── WaveCapacity.java # Capacity constraints
│ │ ├── Location.java # Location reference
│ │ └── OptimizationCriteria.java # Optimization params
│ ├── service/ # Domain services
│ │ ├── WaveOptimizationService.java # Optimization algorithms
│ │ └── WaveAllocationService.java # Resource allocation
│ ├── repository/ # Repository interfaces (ports)
│ └── event/ # Domain events
├── application/ # Use cases & orchestration
│ ├── service/ # Application services
│ ├── command/ # Commands
│ ├── query/ # Queries
│ └── port/ # Application ports
└── infrastructure/ # External adapters
├── persistence/ # MongoDB repositories
├── messaging/ # Kafka publishers
├── web/ # REST controllers
└── config/ # Configuration
- Hexagonal Architecture - Clean separation of domain and infrastructure
- Domain-Driven Design - Rich domain model with business invariants
- Strategy Pattern - Multiple wave creation strategies
- Factory Pattern - Wave creation based on type
- Event-Driven Architecture - Integration via domain events
- Aggregate Pattern - Consistency boundaries around Wave
- Repository Pattern - Data access abstraction
- SOLID Principles - Maintainable and extensible code
- Multi-Objective Optimization - Weighted scoring for multiple criteria
- Greedy Nearest Neighbor - Travel distance optimization
- Zone-Based Clustering - Minimize zone transitions
- Capacity Bin Packing - Efficient capacity utilization
- Priority Sorting - SLA and customer tier prioritization
- Java 21 - Programming language
- Spring Boot 3.2 - Application framework with GraalVM Native Image support
- Maven - Build and dependency management
- MongoDB - Document database for aggregates
- Spring Data MongoDB - Data access layer
- Apache Kafka - Event streaming platform
- Spring Kafka - Kafka integration
- CloudEvents - Standardized event format
- Spring Web MVC - REST API framework
- Bean Validation - Input validation
- OpenAPI/Swagger - API documentation
- Spring Boot Actuator - Health checks and metrics
- Micrometer - Metrics collection
- Micrometer Tracing - Distributed tracing
- Structured Logging - JSON log format
- JUnit 5 - Unit testing framework
- Testcontainers - Integration testing
- Mockito - Mocking framework
- AssertJ - Fluent assertions
- Docker - Containerization
- Docker Compose - Local development environment
- ✅ Hexagonal Architecture (Ports and Adapters)
- ✅ Domain-Driven Design tactical patterns
- ✅ Event-Driven Architecture
- ✅ Microservices architecture
- ✅ RESTful API design
- ✅ Strategy pattern for wave creation
- ✅ Multi-objective optimization (distance, SLA, workload)
- ✅ Zone-based optimization
- ✅ Capacity constraint satisfaction
- ✅ Carrier cutoff compliance
- ✅ Performance metrics tracking
- ✅ SOLID principles
- ✅ Clean Code practices
- ✅ Comprehensive unit and integration testing
- ✅ Domain-driven design patterns
- ✅ Immutable value objects
- ✅ Rich domain models with business logic
- ✅ CloudEvents specification v1.0
- ✅ Event-driven integration
- ✅ At-least-once delivery semantics
- ✅ Event versioning strategy
- ✅ Idempotent event handling
- ✅ Structured logging (JSON)
- ✅ Distributed tracing
- ✅ Health check endpoints
- ✅ Prometheus metrics
- ✅ Correlation ID propagation
- Java 21+
- Maven 3.8+
- Docker & Docker Compose
-
Clone the repository
git clone https://github.com/paklog/wave-planning-service.git cd wave-planning-service -
Start infrastructure services
docker-compose up -d mongodb kafka
-
Build and run the application
mvn spring-boot:run
-
Verify the service is running
curl http://localhost:8081/actuator/health
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f wave-planning-service
# Stop all services
docker-compose downFor improved startup time (~0.2s vs ~6s) and reduced memory footprint (~150MB vs ~600MB):
# Build native executable (requires GraalVM)
./mvnw -Pnative clean package -DskipTests
# Run native executable
./target/wave-planning-serviceOr build as a Docker image:
# Build native Docker image
docker build -f Dockerfile.native -t wave-planning-service:native .
# Run native container
docker run -p 8080:8080 \
-e MONGODB_URI=mongodb://host.docker.internal:27017/wave_planning \
-e KAFKA_BOOTSTRAP_SERVERS=host.docker.internal:9092 \
wave-planning-service:nativeFor detailed native image build instructions, see NATIVE_BUILD.md.
Once running, access the interactive API documentation:
- Swagger UI: http://localhost:8081/swagger-ui.html
- OpenAPI Spec: http://localhost:8081/v3/api-docs
POST /waves- Create new waveGET /waves/{waveId}- Get wave by IDPOST /waves/create-carrier-based- Create carrier-based wavesPOST /waves/create-zone-based- Create zone-based wavesPOST /waves/create-capacity-based- Create capacity-based wavesPOST /waves/{waveId}/optimize- Optimize wavePOST /waves/{waveId}/release- Release wave for executionGET /waves/{waveId}/progress- Get wave progressPOST /waves/merge- Merge multiple waves
Groups orders by carrier cutoff times to meet shipping deadlines:
// Groups: FedEx (4pm cutoff), UPS (6pm cutoff), USPS (8pm cutoff)
List<Wave> carrierWaves = createCarrierWaves(orders, cutoffs);Groups orders by warehouse zones to minimize picker travel:
// Creates waves with max 3 zones per wave
List<Wave> zoneWaves = createZoneWaves(orders, warehouseId);Creates waves respecting capacity constraints:
// Max 100 orders, 500 lines, 1000 cubic feet per wave
List<Wave> capacityWaves = createCapacityWaves(orders, capacity);Creates waves in fixed time windows:
// 2-hour windows starting at 8am
List<Wave> timeWaves = createTimeBasedWaves(orders, windowSize);- Travel Distance (30% weight) - Minimize picker travel
- SLA Compliance (40% weight) - Prioritize urgent orders
- Workload Balance (30% weight) - Even distribution across pickers
- Average improvement: 20-30% over unoptimized waves
- Processing time: <200ms for 100 orders
- Optimization iterations: Max 100 (configurable)
# Run unit tests
mvn test
# Run integration tests
mvn verify
# Run tests with coverage
mvn clean verify jacoco:report
# View coverage report
open target/site/jacoco/index.htmlKey configuration properties:
spring:
data:
mongodb:
uri: mongodb://localhost:27017/wave_planning
kafka:
bootstrap-servers: localhost:9092
wave-planning:
optimization:
max-iterations: 100
improvement-threshold: 0.01
capacity:
default-max-orders: 100
default-max-lines: 500
default-max-volume: 1000.0
default-max-weight: 5000.0
carrier:
cutoff-buffer-minutes: 30com.paklog.wave.created.v1com.paklog.wave.optimized.v1com.paklog.wave.released.v1com.paklog.wave.started.v1com.paklog.wave.completed.v1com.paklog.wave.cancelled.v1com.paklog.waves.merged.v1
com.paklog.order.created- New orders to plancom.paklog.order.priority.changed- Priority updatescom.paklog.order.cancelled- Order cancellationscom.paklog.pick.session.completed- Wave progress trackingcom.paklog.carrier.cutoff.approaching- Cutoff warnings
DRAFT → PLANNED → RELEASED → IN_PROGRESS → COMPLETED
↓ ↓ ↓
CANCELLED CANCELLED CANCELLED
- Health: http://localhost:8081/actuator/health
- Metrics: http://localhost:8081/actuator/metrics
- Prometheus: http://localhost:8081/actuator/prometheus
- Info: http://localhost:8081/actuator/info
wave.creation.time- Wave creation durationwave.optimization.improvement- Optimization percentagewave.size.orders- Orders per wavewave.completion.rate- Wave success rate
- Follow hexagonal architecture principles
- Implement domain logic in domain layer
- Maintain aggregate consistency boundaries
- Use appropriate wave creation strategy
- Ensure optimization algorithms are tested
- Write comprehensive tests including algorithm tests
- Document optimization strategies
- Follow existing code style and conventions
Copyright © 2024 Paklog. All rights reserved.