diff --git a/.docker-compose-local/application.yaml b/.docker-compose-local/application.yaml index c474bb1..05f4ba0 100644 --- a/.docker-compose-local/application.yaml +++ b/.docker-compose-local/application.yaml @@ -6,8 +6,12 @@ services: build: context: ../ dockerfile: Dockerfile - entrypoint: [ "/flyway/flyway" ] - command: "-url=jdbc:mysql://database -schemas=sampledb -user=root -password=rpassword -connectRetries=60 migrate -locations=filesystem:/flyway/sql" + entrypoint: [ "sh", "-c" ] + command: "/flyway/run-migration.sh" + environment: + DATABASE_URL: jdbc:mysql://database/sampledb + DATABASE_USER: root + DATABASE_PASSWORD: rpassword networks: - database-net diff --git a/Dockerfile b/Dockerfile index 3768680..62d2387 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,14 +7,8 @@ RUN apt-get update && apt-get install -y curl \ && curl -kfsSL https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz -o maven.tar.gz \ && tar -xzf maven.tar.gz -C /opt \ && ln -s /opt/apache-maven-${MAVEN_VERSION}/bin/mvn /usr/bin/mvn \ - && rm -rf maven.tar.gz - -# Install and configure Flyway -ARG FLYWAY_VERSION=7.5.2 -RUN mkdir /flyway \ - && curl https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/${FLYWAY_VERSION}/flyway-commandline-${FLYWAY_VERSION}.tar.gz -o /flyway/flyway-commandline-${FLYWAY_VERSION}.tar.gz \ - && tar -xzf /flyway/flyway-commandline-${FLYWAY_VERSION}.tar.gz --strip-components=1 -C /flyway \ - && rm /flyway/flyway-commandline-${FLYWAY_VERSION}.tar.gz + && rm -rf maven.tar.gz \ + && mkdir /flyway WORKDIR /build @@ -25,9 +19,6 @@ COPY pom.xml . COPY ./acceptance-test ./acceptance-test COPY ./application ./application -# Copy Migration files to flyway folder -COPY resources/flyway/db/migration /flyway/sql - # Run Maven package on the specific application module WORKDIR /build/application RUN mvn clean package -DskipTests @@ -38,7 +29,14 @@ WORKDIR /app # Copy the built application JAR from the build stage COPY --from=build /build/application/target/*.jar application.jar -COPY --from=build /flyway /flyway + +# Copy the Maven installation from the build stage +COPY --from=build /opt/apache-maven* /opt/apache-maven +RUN ln -s /opt/apache-maven/bin/mvn /usr/bin/mvn + +# Copy Migration files to flyway folder +COPY resources/flyway /flyway +RUN chmod +x /flyway/run-migration.sh # Expose the application port EXPOSE 8080 diff --git a/README.md b/README.md index acda9f3..90baa64 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ In this template, we provide a user registration endpoint that triggers an event 📖 Read this in: - 🇧🇷 [Português](README.pt.md) ---- + ## **Architecture** @@ -71,7 +71,7 @@ guaranteeing the separation of concerns and the independence of the core busines _Read more about: [Garantindo a arquitetura de uma aplicação sem complexidade](https://medium.com/luizalabs/garantindo-a-arquitetura-de-uma-aplica%C3%A7%C3%A3o-sem-complexidade-6f675653799c)_ ---- + ### **Acceptance Tests** @@ -94,7 +94,7 @@ during its lifecycle. View module [README](acceptance-test/README.md). _Read more about: [Separando os testes integrados de sua aplicação em um novo conceito](https://medium.com/luizalabs/separando-os-testes-integrados-de-sua-aplica%C3%A7%C3%A3o-em-um-novo-conceito-4f511ebb53a4)_ ---- + ## **Getting Started** @@ -156,7 +156,7 @@ Key Features: This approach enhances deployment reliability and maintains a clean separation of concerns, aligning with the project's architectural principles. -You see the sample how to execute in: [application docker-compose file](.docker-compose-local/application/docker-compose.yml). +You see the sample how to execute in: [application docker-compose file](.docker-compose-local/application.yaml). ### **OpenAPI** This project uses **Springdoc OpenAPI** to automatically document REST endpoints. @@ -185,15 +185,24 @@ After starting the application, access: The local stack also includes infrastructure services to support the application. These services are accessible on `localhost` and provide essential functionalities: +#### Observability Services + +See the stack: [docker-compose-observability.yaml](.docker-compose-local/observability.yaml) + - **Grafana**: Visualization and monitoring dashboard, available at [http://localhost:3000](http://localhost:3000). - **Prometheus**: Metrics collection and monitoring system, available at [http://localhost:9090](http://localhost:9090). - **Jaeger**: Distributed tracing system, available at [http://localhost:16686](http://localhost:16686). + +#### Infrastructure Services + +See the stack: [docker-compose-infrastructure.yaml](.docker-compose-local/infrastructure.yaml) + - **MySQL**: Relational database system, accessible at `localhost:3306`. - **Kafka**: Event streaming platform, available at `localhost:9092`. These services are orchestrated using Docker Compose to ensure seamless setup and operation in a local development environment. ---- + ## **Architectural Decision Records (ADR)** @@ -202,13 +211,13 @@ architectural decisions made throughout the project, providing context, rational To learn more about the ADRs and explore the documented decisions, refer to the [ADR README](./adr/README.md). ---- + ## **Contribute** Pull Requests are welcome. For significant changes, please open an issue first to discuss what you would like to change. Make sure to update tests as appropriate. ---- + _**Architecture Template Project proposed by Guilherme Biff Zarelli**_ - **Blog/Site**: [https://helpdev.com.br](https://helpdev.com.br) diff --git a/README.pt.md b/README.pt.md index 63efb08..63f19a2 100644 --- a/README.pt.md +++ b/README.pt.md @@ -11,7 +11,7 @@ Neste template, fornecemos um **endpoint de cadastro de usuário**, que **dispar 📚 Leia em: - 🇬🇧 [English](README.md) ---- + ## **Architecture** @@ -65,7 +65,7 @@ Esta arquitetura é garantida por meio de testes **ArchUnit**, que validam a con _Read more about: [Garantindo a arquitetura de uma aplicação sem complexidade](https://medium.com/luizalabs/garantindo-a-arquitetura-de-uma-aplica%C3%A7%C3%A3o-sem-complexidade-6f675653799c)_ ---- + ### **Acceptance Tests** @@ -85,7 +85,7 @@ durante seu ciclo de vida. Ver módulo [README](acceptance-test/README.md). _Leia mais sobre: [Separando os testes integrados de sua aplicação em um novo conceito](https://medium.com/luizalabs/separando-os-testes-integrados-de-sua-aplica%C3%A7%C3%A3o-em-um-novo-conceito-4f511ebb53a4)_ ---- + ## **Getting Started** @@ -144,7 +144,7 @@ Principais Características: Essa abordagem melhora a confiabilidade da implantação e mantém uma separação clara de responsabilidades, alinhando-se aos princípios arquitetônicos do projeto. -Você pode ver um exemplo de como executar em: [arquivo docker-compose da aplicação](.docker-compose-local/application/docker-compose.yml). +Você pode ver um exemplo de como executar em: [arquivo docker-compose da aplicação](.docker-compose-local/application.yaml). ### **OpenAPI** Este projeto utiliza o **Springdoc OpenAPI** para documentar automaticamente os endpoints REST. @@ -173,14 +173,23 @@ Após iniciar a aplicação, acesse: A stack local também inclui serviços de infraestrutura para dar suporte ao aplicativo. Esses serviços são acessíveis em `localhost` e fornecem funcionalidades essenciais: +#### Observability Services + +Veja a stack: [docker-compose-observability.yaml](.docker-compose-local/observability.yaml) + - **Grafana**: Visualization and monitoring dashboard, available at [http://localhost:3000](http://localhost:3000). - **Prometheus**: Metrics collection and monitoring system, available at [http://localhost:9090](http://localhost:9090). - **Jaeger**: Distributed tracing system, available at [http://localhost:16686](http://localhost:16686). + +#### Infrastructure Services + +Veja a stack: [docker-compose-infrastructure.yaml](.docker-compose-local/infrastructure.yaml) + - **MySQL**: Relational database system, accessible at `localhost:3306`. - **Kafka**: Event streaming platform, available at `localhost:9092`. Esses serviços são orquestrados usando o Docker Compose para garantir configuração e operação perfeitas em um ambiente de desenvolvimento local. ---- + ## **Architectural Decision Records (ADR)** O projeto inclui uma pasta dedicada para **Registros de Decisões Arquiteturais (ADR)**, localizada no diretório `adr`. Esta pasta documenta as principais @@ -188,12 +197,12 @@ decisões arquiteturais tomadas ao longo do projeto, fornecendo contexto, justif Para saber mais sobre os ADRs e explorar as decisões documentadas, consulte o [README do ADR](./adr/README.md). ---- + ## **Contribua** Pull Requests são bem-vindos. Para mudanças significativas, por favor, abra uma issue primeiro para discutir o que você gostaria de mudar. Certifique-se de atualizar os testes conforme apropriado. ---- + _**Projeto de Template de Arquitetura proposto por Guilherme Biff Zarelli**_ - **Blog/Site**: [https://helpdev.com.br](https://helpdev.com.br) diff --git a/acceptance-test/src/test/java/br/com/helpdev/acceptance/UserEnrichProcessIT.java b/acceptance-test/src/test/java/br/com/helpdev/acceptance/UserEnrichProcessIT.java index b1074de..240c986 100644 --- a/acceptance-test/src/test/java/br/com/helpdev/acceptance/UserEnrichProcessIT.java +++ b/acceptance-test/src/test/java/br/com/helpdev/acceptance/UserEnrichProcessIT.java @@ -15,9 +15,12 @@ import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; import br.com.helpdev.acceptance.containers.DefaultContainerStarter; +@Execution(ExecutionMode.SAME_THREAD) class UserEnrichProcessIT extends DefaultContainerStarter { @Test diff --git a/acceptance-test/src/test/java/br/com/helpdev/acceptance/containers/DefaultContainerStarter.java b/acceptance-test/src/test/java/br/com/helpdev/acceptance/containers/DefaultContainerStarter.java index 510953b..1675d2c 100644 --- a/acceptance-test/src/test/java/br/com/helpdev/acceptance/containers/DefaultContainerStarter.java +++ b/acceptance-test/src/test/java/br/com/helpdev/acceptance/containers/DefaultContainerStarter.java @@ -61,11 +61,12 @@ private static MySQLContainer buildMySqlContainer() { private static GenericContainer buildFlywayContainerFromApp(final Startable... dependsOn) { return new GenericContainer<>(DOCKER_IMAGE_APP) .dependsOn(dependsOn) - .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("/flyway/flyway")) + .withCreateContainerCmdModifier(cmd -> cmd.withEntrypoint("sh", "-c")) .withNetwork(NETWORK) - .withCommand( - "-url=jdbc:mysql://mysqldb:" + MySQLContainer.MYSQL_PORT + "?useSSL=false -schemas=test -user=" + MYSQL_CONTAINER.getUsername() - + " -password=" + MYSQL_CONTAINER.getPassword() + " -connectRetries=60 migrate -locations=filesystem:/flyway/sql") + .withCommand("/flyway/run-migration.sh") + .withEnv("DATABASE_URL", "jdbc:mysql://mysqldb:" + MySQLContainer.MYSQL_PORT + "/test?autoReconnect=true&useSSL=false") + .withEnv("DATABASE_USER", MYSQL_CONTAINER.getUsername()) + .withEnv("DATABASE_PASSWORD", MYSQL_CONTAINER.getPassword()) .waitingFor(Wait.forLogMessage("(?s).*No migration necessary(?s).*|(?s).*Successfully applied(?s).*", 1)) .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("FLYWAY"))); } diff --git a/resources/flyway/pom.xml b/resources/flyway/pom.xml new file mode 100644 index 0000000..9ca6da6 --- /dev/null +++ b/resources/flyway/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + br.com.helpdev + flyway-migration + 1.0.0 + Flyway Migration + + + Sample to run: + ./mvnw flyway:migrate -Dflyway.url=jdbc:mysql://localhost:3306 -Dflyway.user=foo -Dflyway.password=bar -Dflyway.schemas=schema + + + + 8.4.0 + 11.3.1 + + + filesystem:db/migration + jdbc:mysql://localhost:3306 + foo + bar + 60 + + + + + + org.flywaydb + flyway-maven-plugin + ${flyway-maven-plugin.version} + + ${flyway.url} + ${flyway.user} + ${flyway.password} + ${flyway.locations} + ${flyway.connectRetries} + + + + org.flywaydb + flyway-mysql + ${flyway-maven-plugin.version} + + + com.mysql + mysql-connector-j + ${mysql-connector-j.version} + + + + + + \ No newline at end of file diff --git a/resources/flyway/run-migration.sh b/resources/flyway/run-migration.sh new file mode 100644 index 0000000..fac99f7 --- /dev/null +++ b/resources/flyway/run-migration.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +mvn flyway:migrate -f /flyway/pom.xml -Dflyway.url=${DATABASE_URL} -Dflyway.user=${DATABASE_USER} -Dflyway.password=${DATABASE_PASSWORD} -Dflyway.locations=filesystem:/flyway/db/migration \ No newline at end of file