Spring Boot backend service that allocates delivery orders to vehicles using:
- priority-first assignment (
HIGH -> MEDIUM -> LOW) - capacity constraints
- nearest feasible vehicle based on Haversine distance
- REST APIs for order ingestion, vehicle ingestion, and dispatch plan retrieval
- Greedy dispatch optimization algorithm
- Haversine utility with unit tests
- Request validation with structured error responses
- Unit and integration test coverage
- Java 24
- Spring Boot 3.5
- Spring Web
- Spring Data JPA
- MySQL (default runtime database)
- H2 (test/local profile)
- Lombok
- Jakarta Validation
- JUnit 5, Mockito, MockMvc
src/main/java/com/assignment/dispatch
controller- REST controllersservice- service interfacesservice/impl- service implementations and dispatch logicrepository- JPA repositoriesmodel- JPA entities and enumsdto- request/response payloadsutil- utility classes (Haversine)exception- global exception handling
- Java 24
- Maven 3.9+
- MySQL 8+ (for default profile)
Verify tools:
java -version
mvn -versionDefault config file: src/main/resources/application.properties
Important properties:
spring.datasource.url=jdbc:mysql://localhost:3306/dispatch_db?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=rootUpdate username/password if your local MySQL credentials are different.
From the project root directory:
- Start MySQL.
- Run:
mvn spring-boot:runmvn spring-boot:run -Dspring-boot.run.profiles=h2Application base URL:
http://localhost:8080
H2 console (when h2 profile is active):
http://localhost:8080/h2-console
mvn clean test -Dspring.profiles.active=h2POST /api/dispatch/orders
Request:
{
"orders": [
{
"orderId": "ORD001",
"latitude": 12.9716,
"longitude": 77.5946,
"address": "MG Road, Bangalore, Karnataka, India",
"packageWeight": 10,
"priority": "HIGH"
},
{
"orderId": "ORD002",
"latitude": 12.9352,
"longitude": 77.6245,
"address": "Koramangala, Bangalore, Karnataka, India",
"packageWeight": 15,
"priority": "MEDIUM"
}
]
}Success response (201 Created):
{
"message": "Delivery orders accepted.",
"status": "success"
}POST /api/dispatch/vehicles
Request:
{
"vehicles": [
{
"vehicleId": "VEH001",
"capacity": 100,
"currentLatitude": 12.9716,
"currentLongitude": 77.6413,
"currentAddress": "Indiranagar, Bangalore, Karnataka, India"
},
{
"vehicleId": "VEH002",
"capacity": 80,
"currentLatitude": 12.9352,
"currentLongitude": 77.6245,
"currentAddress": "Koramangala, Bangalore, Karnataka, India"
}
]
}Success response (201 Created):
{
"message": "Vehicle details accepted.",
"status": "success"
}GET /api/dispatch/plan
Response:
{
"dispatchPlan": [
{
"vehicleId": "VEH001",
"totalLoad": 25.0,
"totalDistance": "7.91 km",
"assignedOrders": [
{
"orderId": "ORD001",
"latitude": 12.9716,
"longitude": 77.5946,
"address": "MG Road, Bangalore, Karnataka, India",
"packageWeight": 10.0,
"priority": "HIGH"
}
]
}
],
"unassignedOrders": []
}- Fetch all orders and vehicles.
- Sort orders by priority (
HIGH,MEDIUM,LOW). - For each order:
- filter vehicles with enough remaining capacity
- compute distance from vehicle current location to order location
- choose vehicle with minimum distance
- Assign order and update vehicle state:
- remaining capacity
- total distance
- current location (moved to assigned order location)
- If no feasible vehicle is found, store order in
unassignedOrders.
Validation examples:
- missing required fields
- negative/zero weight or capacity
- invalid
priorityvalues - duplicate
orderIdorvehicleIdinside same request
Error response format:
{
"timestamp": "2026-02-10T16:30:00Z",
"status": 400,
"error": "Bad Request",
"message": "Validation failed",
"path": "/api/dispatch/orders",
"details": [
"orders[0].packageWeight: packageWeight must be positive"
]
}Import:
postman/Dispatch-Load-Balancer.postman_collection.json
Collection variable:
baseUrldefault value:http://localhost:8080
Recommended call order:
Create VehiclesCreate OrdersGet Dispatch Plan
- The project uses MySQL by default for runtime.
- Tests are designed to run with the H2 profile for portability.