Generar el proyecto
En este primer paso generaras el proyecto Task Manager a partir del arquetipo y verificaras que compila y arranca correctamente.
Generar el proyecto
Ejecuta el siguiente comando, proporcionando los parametros del dominio Task Manager:
mvn archetype:generate \
-DarchetypeGroupId=io.zutun.templates \
-DarchetypeArtifactId=template-spring-microservice-multitenant \
-DarchetypeVersion=<version> \
-DgroupId=io.zutun.tutorial \
-DartifactId=task-manager \
-Dpackage=io.zutun.tutorial \
-DapplicationName=TaskManagerService \
-DapplicationDesc=Task\ Manager\ Service \
-DapiBasePath=/tasks \
-DopenApiTag=Tasks \
-DaggregateRoot=Task \
-DdomainName=task \
-DtableName=tasks
Maven generara el directorio task-manager/ con la siguiente estructura:
task-manager/
├── pom.xml
├── wizard.sh
├── .env
├── Dockerfile
├── lombok.config
├── CLAUDE.md
├── AGENTS.md
└── src/
├── main/
│ ├── java/io/zutun/tutorial/
│ │ ├── TaskManagerServiceApplication.java
│ │ ├── task/
│ │ │ ├── domain/
│ │ │ │ └── Task.java # Aggregate root
│ │ │ ├── port/
│ │ │ │ ├── in/ # Input ports (vacios)
│ │ │ │ └── out/
│ │ │ │ ├── TaskPersistencePort.java # Output port (write)
│ │ │ │ └── TaskRetrievalPort.java # Output port (read)
│ │ │ ├── service/ # Servicios (vacio)
│ │ │ ├── adapter/
│ │ │ │ ├── in/
│ │ │ │ │ ├── web/ # Controllers (vacio)
│ │ │ │ │ └── listener/
│ │ │ │ │ └── TaskEventHandler.java # Event listener
│ │ │ │ └── out/
│ │ │ │ └── persistence/
│ │ │ │ ├── TaskPersistenceAdapter.java
│ │ │ │ └── TaskRepository.java # JPA repository
│ │ │ └── exception/
│ │ │ └── TaskError.java # Error codes
│ │ ├── events/task/
│ │ │ └── TaskCreatedEvent.java # Domain event
│ │ └── commons/ # Infraestructura compartida
│ └── resources/
│ ├── application.yaml
│ ├── application-local.yaml
│ └── db/changelog/ # Migraciones Liquibase
│ ├── db.changelog-master.yaml
│ ├── v0.0.1__domain_events_and_shedlock_tables.yaml
│ ├── v0.0.2__create_aggregate_tables.yaml
│ └── v0.0.3_create_command_tables.yaml
└── test/
├── java/io/zutun/tutorial/
│ └── it/
│ ├── ApiSteps.java # BDD steps (API)
│ └── ApiClient.java # Cliente HTTP
└── resources/
└── api/
└── 000_application_health.feature # Health check
Que incluye el proyecto generado
El arquetipo genera la estructura base del microservicio con:
-
Un aggregate root
Taskque extiendeAbstractAuditabley publica unTaskCreatedEvental ser creado. -
Dos output ports separados:
TaskPersistencePort(escritura) yTaskRetrievalPort(lectura). -
Un adaptador de persistencia
TaskPersistenceAdaptercon su repositorio JPA. -
Un listener de eventos
TaskEventHandlerpara procesar eventos de dominio. -
Migraciones Liquibase que crean la tabla
taskscon columnas de auditoria, las tablasoutbox_events/inbox_eventspara el patron outbox y la tablashedlockpara bloqueos distribuidos. -
Configuracion multi-tenant con tres tenants preconfigurados en el perfil
local:public,tenant1ytenant2, cada uno con su propio esquema de base de datos. -
Tests BDD end-to-end con un escenario de health check como punto de partida.
Los paquetes port/in, service y adapter/in/web se generan vacios — los iras completando a lo largo del tutorial.
Inicializar y ejecutar
Ingresa al directorio generado e inicializa el entorno local:
cd task-manager
./wizard.sh init-all
Esto ejecuta dos acciones:
-
init-idea— genera las run configurations de IntelliJ IDEA. -
init-h2— crea la base de datos H2 local y ejecuta las migraciones Liquibase para cada tenant.
Arranca el servicio:
./wizard.sh run
Verificar
Una vez iniciado, verifica que el servicio responde:
curl http://localhost:8080/actuator/health
La documentacion OpenAPI estara disponible en http://localhost:8080/swagger-ui.html.
Siguiente paso
Con el proyecto generado y funcionando, en el siguiente paso vas a crear tu primer caso de uso.