Skip to content

Tech Challenge para avaliação da Fase III da Pós Graduação em Arquitetura e Desenvolvimento Java.

License

Notifications You must be signed in to change notification settings

fsales/fiap-tech-chalenge-fase3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub GitHub code size in bytes GitHub language count GitHub top language GitHub issues Create release Publish Image Registry - Branch Develop

@fsales Tech Chalenge

📑 Tech Chalenge

Tech Challenge para avaliação da Fase III da Pós Graduação em Arquitetura e Desenvolvimento Java.

🛠️ Linguagem e ferramentas

logo java

logo mongodb

logo spring logo spring-boot logo spring security

logo git logo github logo github action

logo AWS logo docker logo terraform

logo eclipse logo intellij

logo curl logo Google-chrome logo postman logo swagger

🏫 Dados Acadêmicos

🏬 Instituição

Faculdade FIAP

🧑🏻‍🎓Curso

Pós-Graduação em Arquitetura e Desenvolvimento Java

Aluno


Fábio de Oliveira Sales

Linkedin Badge Gmail Badge

Pré-requisitos

Antes de começar, você precisará ter as seguintes ferramentas instaladas em sua máquina:

  • Java 17
  • Git
  • Docker
  • IDE de desenvolvimento:
    • Eclipse
    • IntelliJ IDEA
    • VSCode
    • Outras
  • Navegador:
    • Google Chrome
    • Outro
  • Postman, CURL ou utilize o Swagger

Como Executar

  1. Abrir o terminal
  • Git Bash
  • CMD
  • Bash
  • Outros
  1. Clonar repositório. git https://github.com/fsales/fiap-tech-chalenge-fase3.git.
git clone  https://github.com/fsales/fiap-tech-chalenge-fase3.git  fiap-tech-chalenge-fase3

Executar imagem Docker do Park Tech

No diretório /fiap-tech-challenge-fase3/docker-compose você encontrará o arquivo docker-compose-parktech.yaml com as definições da aplicação Park Tech.

  1. Park Tech utilizando o Docker.
  • Iniciar o container do Park Tech
docker-compose -f ./docker-compose/docker-compose-parktech.yaml up -d --force-recreate
  • Parar o container do MongoDB
docker-compose -f ./docker-compose/docker-compose-parktech.yaml down -v
  • As configurações do Park Tech está definido no arquivo:

A variável de ambiente PARK_TECH_SPRING_DOCKER_COMPOSE_ENABLE deve ser configurado com o valor false

IDE de desenvolvimento

  1. Acessar o diretório fiap-tech-chalenge-fase3/park-tech.
cd  /fiap-tech-chalenge-fase3/park-tech
  1. Construir o projeto utilizando o maven.
./mvnw clean package
  1. MongoDB utilizando o Docker.

No diretório /fiap-tech-challenge-fase3/docker-compose você encontrará o arquivo docker-compose-mongodb.yaml com as definições do MongoDB e do cliente Mongo Express.

  • Iniciar o container do MongoDB
docker-compose -f ./docker-compose/docker-compose-mongodb.yaml up -d
  • Parar o container do MongoDB
docker-compose -f ./docker-compose/docker-compose-mongodb.yaml down -v

Caso a variável de ambiente PARK_TECH_PROFILE_ENVIRONMENT esteja definida com o valor dev, o plugin do Spring Boot Docker Compose iniciará automaticamente os contêineres que estão definidos no arquivo docker-compose-mongodb.yaml localizado no diretório /fiap-tech-challenge-fase3/docker-compose.

  1. Importar o projeto fiap-tech-chalenge-fase3/park-tech na sua IDE de desenvolvimento.

  2. Configure as variáveis de ambiente na IDE de desenvolvimento.

    • Variáveis:
      • PARK_TECH_MONGODB_DATABASE:

        Nome do Banco de Dados utilizado pela aplicação.

      • PARK_TECH_MONGODB_URI:

        URI de conexão ao seu banco de dados MongoDB.

      • PARK_TECH_PROFILE_ENVIRONMENT:

        Perfis de aplicativos usando a propriedade spring.profiles.active no arquivo application.yml. Isso permite que você defina diferentes configurações e comportamentos para diferentes ambientes (por exemplo, desenvolvimento, produção, teste).

        • Valores possíveis para a variável PARK_TECH_PROFILE_ENVIRONMENT:
          • dev
          • cloud-atlas

O usuário e senha do MongoDB foram definidos no /fiap-tech-challenge-fase3/docker-compose/mongo-config/.env-mongodb e podem ser consultados no arquivo .env-mongoexpress.

Arquitetura Hexagonal

A arquitetura hexagonal, proposta por Alistair Cockburn em seu artigo Hexagonal Architecture1, inicialmente chamada de Ports And Adapters, é uma proposta arquitetural em camadas que visa proteger a lógica de negócios do sistema. A inovação dessa abordagem está na compreensão de Cockburn de que não há uma grande diferença entre como a interface do usuário e o banco de dados interagem com o aplicativo; ambos são elementos externos que podem ser substituídos a qualquer momento.

Para mitigar a dependência direta desses fatores externos (como interface de usuário, bancos de dados, integrações e filas), Cockburn introduz o conceito de "portas", que são interfaces aplicando o princípio de inversão de dependência. Estas são interfaces que a lógica de negócio conhece. Além disso, ele propõe os "adaptadores", que são as implementações dessas portas, lidando com as dependências externas.

Essencialmente, a arquitetura hexagonal é um padrão que separa a lógica de negócios do sistema das preocupações técnicas, como a interação com o usuário ou o acesso ao banco de dados. Ela se baseia na ideia de que uma aplicação é composta por "portas" de entrada e saída, que possibilitam a comunicação com o mundo exterior, e "adaptadores", que convertem essas informações em um formato compreensível para a aplicação e vice-versa.

Exemplo da Organização do Projeto
├── src
  └── main
    └── java
      └── br
        └── com
          └── fsales
            └── parktech
              ├── adapters
              │  ├── in
              │  │  └── controller
              │  │    ├── condutor
              │  │    │  ├── CondutorController.java
              │  │    │  ├── mapper
              │  │    │  │  └── CondutorMapper.java
              │  │    │  ├── request
              │  │    │  │  ├── CondutorRequest.java
              │  │    │  │  ├── DadosAtualizarCondutorRequest.java
              │  │    │  │  └── ListarCondutorRequest.java
              │  │    │  └── response
              │  │    │    └── CondutorResponse.java
              │  │    ├── exception
              │  │    │  ├── ParkTechControlerExceptionHandler.java
              │  │    │  └── response
              │  │    │    ├── ValidationErrorResponse.java
              │  │    │    └── ViolationResponse.java
              │  │    ├── ParktechResource.java
              │  │    └── veiculo
              │  │      ├── mapper
              │  │      │  └── VeiculoMapper.java
              │  │      ├── request
              │  │      │  ├── DadosAtualizarVeiculoRequest.java
              │  │      │  ├── VeiculoFiltroConsultaPaginadaRequest.java
              │  │      │  └── VeiculoRequest.java
              │  │      ├── response
              │  │      │  └── VeiculoResponse.java
              │  │      └── VeiculoController.java
              │  └── out
              │    ├── client
              │    │  ├── ConsultarEnderecoPorCepClient.java
              │    │  └── response
              │    │    └── EnderecoResponse.java
              │    ├── condutor
              │    │  ├── DeleteCondutorAdapter.java
              │    │  ├── FindCondutorAdapter.java
              │    │  ├── FindCondutorByIdAdapter.java
              │    │  ├── InsertCondutorAdapter.java
              │    │  └── UpdateCondutorAdapter.java
              │    ├── endereco
              │    │  └── ConsultarEnderecoPorCepAdapter.java
              │    ├── repository
              │    │  ├── CondutorRepository.java
              │    │  ├── CondutorRepositoryCustom.java
              │    │  ├── entity
              │    │  │  ├── CondutorEntity.java
              │    │  │  ├── ContatoEntity.java
              │    │  │  ├── EnderecoEntity.java
              │    │  │  ├── PessoaEntity.java
              │    │  │  ├── PessoaFisicaEntity.java
              │    │  │  └── VeiculoEntity.java
              │    │  ├── impl
              │    │  │  ├── CondutorRepositoryCustomImpl.java
              │    │  │  └── VeiculoRepositoryCustomImpl.java
              │    │  ├── mapper
              │    │  │  ├── CondutorEntityMapper.java
              │    │  │  ├── EnderecoResponseMapper.java
              │    │  │  └── VeiculoEntityMapper.java
              │    │  ├── PageRepositoryCustom.java
              │    │  ├── VeiculoRepository.java
              │    │  └── VeiculoRepositoryCustom.java
              │    └── veiculo
              │      ├── DeleteVeiculoAdapter.java
              │      ├── FindVeiculoAdapter.java
              │      ├── FindVeiculoByIdAdapter.java
              │      ├── InsertVeiculoAdapter.java
              │      └── UpdateVeiculoAdapter.java
              ├── application
              │  ├── core
              │  │  ├── domain
              │  │  │  ├── Condutor.java
              │  │  │  ├── Contato.java
              │  │  │  ├── Endereco.java
              │  │  │  ├── enumeration
              │  │  │  │  └── EstadoEnum.java
              │  │  │  ├── funcionalinterface
              │  │  │  │  └── Mapper.java
              │  │  │  ├── paginacao
              │  │  │  │  └── Page.java
              │  │  │  ├── Pessoa.java
              │  │  │  ├── PessoaFisica.java
              │  │  │  ├── Veiculo.java
              │  │  │  └── VeiculoFiltroConsultaPaginada.java
              │  │  └── usecase
              │  │    ├── condutor
              │  │    │  ├── DeleteCondutorUseCase.java
              │  │    │  ├── FindCondutorByIdUseCase.java
              │  │    │  ├── FindCondutorUseCase.java
              │  │    │  ├── InsertCondutorUseCase.java
              │  │    │  └── UpdateCondutorUseCase.java
              │  │    └── veiculo
              │  │      ├── DeleteVeiculoUseCase.java
              │  │      ├── FindVeiculoByIdUseCase.java
              │  │      ├── FindVeiculoUseCase.java
              │  │      ├── InsertVeiculoUseCase.java
              │  │      └── UpdateVeiculoUseCase.java
              │  └── ports
              │    ├── in
              │    │  ├── condutor
              │    │  │  ├── DeleteCondutorInputPort.java
              │    │  │  ├── FindCondutorByIdInputPort.java
              │    │  │  ├── FindCondutorInputPort.java
              │    │  │  ├── InsertCondutorInputPort.java
              │    │  │  └── UpdateCondutorInputPort.java
              │    │  └── veiculo
              │    │    ├── DeleteVeiculoInputPort.java
              │    │    ├── FindVeiculoByIdInputPort.java
              │    │    ├── FindVeiculoInputPort.java
              │    │    ├── InsertVeiculoInputPort.java
              │    │    └── UpdateVeiculoInputPort.java
              │    └── out
              │      ├── condutor
              │      │  ├── ConsultarEnderecoPorCepOutputPort.java
              │      │  ├── DeleteCondutorOutputPort.java
              │      │  ├── FindCondutorByIdOutputPort.java
              │      │  ├── FindCondutorOutputPort.java
              │      │  ├── InsertCondutorOutputPort.java
              │      │  └── UpdateCondutorOutputPort.java
              │      └── veiculo
              │        ├── DeleteVeiculoOutputPort.java
              │        ├── FindVeiculoByIdOutputPort.java
              │        ├── FindVeiculoOutputPort.java
              │        ├── InsertVeiculoOutputPort.java
              │        └── UpdateVeiculoOutputPort.java
              ├── config
              │  ├── condutor
              │  │  ├── DeleteCondutorConfig.java
              │  │  ├── FindCondutorByIdConfig.java
              │  │  ├── FindCondutorConfig.java
              │  │  ├── InsertCondutorConfig.java
              │  │  └── UpdateCondutorConfig.java
              │  ├── feign
              │  │  └── FeignConfiguration.java
              │  ├── GroupedOpenApiConfig.java
              │  └── veiculo
              │    ├── DeleteVeiculoConfig.java
              │    ├── FindVeiculoByIdConfig.java
              │    ├── FindVeiculoConfig.java
              │    ├── InsertVeiculoConfig.java
              │    └── UpdateVeiculoConfig.java
              ├── infrastructure
              │  ├── configuration
              │  │  ├── OpenAPIConfiguration.java
              │  │  └── SwaggerConfigProperties.java
              │  └── properties
              │    └── ParktechProperties.java
              └── ParkTechApplication.java
Adapters

Adaptadores na arquitetura hexagonal são componentes que traduzem dados e chamadas entre a aplicação e sistemas externos. Por exemplo, um adaptador pode converter dados do formato interno da aplicação para um formato compreendido por um banco de dados externo, permitindo que a lógica de negócios permaneça independente da implementação específica do banco de dados.

Esses adaptadores são a implementação das dependências externas, como a interface do usuário/entrada e a infraestrutura/saída.

  • adapter/inbound: Nesta parte, encontram-se todos os controladores responsáveis pela entrada de dados na aplicação.

  • adapter/outbound: Aqui estão todas as integrações externas, como repositórios e integrações de API, que cuidam da saída de dados da aplicação.

Domain

O "domain" (domínio) na arquitetura hexagonal representa a parte central da aplicação, onde são implementadas as regras de negócios fundamentais. Nesta camada, a lógica específica da aplicação é encapsulada de forma independente de qualquer tecnologia ou detalhes de implementação externos, como interfaces de usuário ou bancos de dados.

Neste contexto, as classes no domínio não possuem dependências externas, incluindo dependências de estrutura. A estrutura do domínio pode ser organizada da seguinte forma:

  • domain/domain: Aqui estão todas as entidades e objetos do domínio, sem nenhuma dependência externa.

  • domain/ports/inbound: Nesta parte, são definidas as interfaces que representam os casos de uso da aplicação.

  • domain/ports/outbound: Esta seção contém as interfaces que representam os serviços externos utilizados pela aplicação. Importante notar que aqui não há nenhuma nomenclatura ligada a tecnologias específicas.

  • domain/usecase: Nesta área, ocorre a implementação concreta dos casos de uso da aplicação.

Consideração

O desenvolvimento deste projeto está fundamentado na Arquitetura Hexagonal2, onde a principal preocupação reside em aplicar corretamente os conceitos de portas e adaptadores, estando integralmente alinhado com o princípio de inversão de dependências. É crucial observar que os casos de uso, interfaces (portas) e domínios não devem apresentar dependências externas, incluindo aquelas relacionadas ao framework utilizado. A proposta é assegurar que a lógica de negócios esteja completamente isolada desses fatores externos, garantindo assim sua integridade e independência.

CI/CD

CI/CD é a abreviação de Continuous Integration/Continuous Delivery, traduzindo para o português: integração e entrega contínuas. Trata-se de uma prática de desenvolvimento de software que visa tornar a integração de código mais eficiente por meio de builds e testes automatizados. 3

Github Action

GitHub Actions é uma plataforma de integração contínua e entrega contínua (CI/CD) que permite automatizar sua compilação, testes e pipeline de implantação. É possível criar fluxos de trabalho que compilarão e testarão cada solicitação de pull em seu repositório ou implantarão solicitações de pull mescladas em produção. 2

Pipeline CI/CD

  1. Publicação da Imagem no Docker Hub - Branch Develop 4.
  • No início do desenvolvimento, é criada uma branch feature/w.x.y.z a partir da branch develop.
  • Ao finalizar o desenvolvimento, é aberto um Pull Request da branch feature/w.x.y.z para develop.
  • Quando esse PR for mesclado, o fluxo de trabalho git-flow-publish-image-develop.yaml do GitHub Actions será acionado, gerando a imagem Docker e publicando-a no Docker Hub.
  1. Criação da Release - Branch Main 4.
  • Quando a validação das funcionalidades for realizada, é criada uma branch release/w.x.y.z a partir da branch develop.
  • Após mesclar esse PR, o fluxo de trabalho create-release.yaml do GitHub Actions será acionado, gerando a imagem Docker e publicando-a no Docker Hub, além de criar automaticamente uma tag de versão w.x.y.z.
  1. Endereço do Docker Hub:

Secrets

Secrets são variáveis que você cria em uma organização, repositório ou ambiente de repositório. Os Secrets que você cria estão disponíveis para utilização nos fluxos de trabalho em GitHub Actions. GitHub Actions só poderá ler um Secret se você incluí-lo explicitamente em um fluxo de trabalho.

  1. Lista dos secrets que devem ser configurados no repositório:
  • Repositório Github:
    • GIT_TOKEN
    • GIT_EMAIL
  • DockerHub:*
    • DOCKERHUB_USERNAME
    • DOCKERHUB_TOKEN
  • Park-Tech:
    • PARK_TECH_PROFILE_ENVIRONMENT
    • PARK_TECH_MONGODB_URI
    • PARK_TECH_MONGODB_DATABASE
    • PARK_TECH_BASIC_AUTH_NAME
    • PARK_TECH_BASIC_AUTH_PASSWORD
    • URI_DATABASE
  • AWS
    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
  1. Publicação da versão

Escolhemos o Amazon Elastic Container Service (ECS) como plataforma para hospedar nossa aplicação na nuvem da AWS. Para garantir uma implantação eficaz e segura, optamos por utilizar o Terraform, uma ferramenta que nos permite provisionar toda a infraestrutura necessária e publicar o contêiner no ECS. O processo de execução do Terraform é cuidadosamente gerenciado pelo fluxo de trabalho aws-terraform-deploy-manual.yaml no GitHub Actions, sendo ativado manualmente para garantir um controle preciso sobre a implantação. Além disso, se necessário, podemos reverter o processo de implantação acionando o fluxo de trabalho aws-terraform-undeploy-manual.yaml.

Park Tech - Sistema de Gestão de Estacinamentos

O sistema Park Tech é responsável por gerenciar o tempo de estacionamento dos veículos, calcular os valores devidos e armazenar essas informações para fins de fiscalização.

Integração com Serviços

  • ViaCEP

    O ViaCEP é um serviço para consulta gratuita de código postais de endereçamento do Brasil.

🔨 Funcionalidades do projeto

  • API de condutores: Os condutores podem se registrar no sistema, associando seus dados pessoais, como nome, endereço e informações de contato.
  • API de veiculos: Os condutores podem registrar no sistema vários veículos.
  • API de estacionamentos: tem como objetivo permite iniciar o período de estacionamento, oferecendo opções de tempo fixo ou por hora.

Endpoints

Descrição dos endpoints disponíveis na aplicação Park Tech.

Requisição HTTP

Para fazer as requisições HTTP pode ser utilizado:

  1. CURL

  2. Swagger

  3. Postman

    1. Collections
    2. Environment

API

Desafio encontrado durante o desenvolvimento

Durante o desenvolvimento do projeto, não enfrentei dificuldades significativas com o Framework Spring. Por essa razão, pude concentrar-me em desenvolver funcionalidades básicas e aprimorar minhas habilidades em atividades para as quais não tinha experiência anteriormente. Introduzi no projeto as seguintes melhorias:

  1. Utilização do banco de dados MongoDB: Optei por utilizar o MongoDB como parte do nosso sistema de gerenciamento de banco de dados, explorando uma abordagem diferente e valiosa para armazenar dados.

  2. Implementação de uma Infraestrutura na Nuvem AWS utilizando o Terraform: Aproveitei a oportunidade para utilizar a nuvem pública, específicamente a AWS, e empregar o Terraform para provisionar e disponibilizar nossa infraestrutura na nuvem, proporcionando escalabilidade e flexibilidade ao projeto.

  3. Criação de um Pipeline de CI/CD utilizando o GitHub Actions: Estabeleci um Pipeline de Integração Contínua e Entrega Contínua (CI/CD) utilizando o GitHub Actions. Esse pipeline automatizado realiza diversas etapas essenciais, como o build do projeto, a geração da imagem Docker e sua publicação no Docker Hub, a criação de tags e releases no GitHub, além de provisionar recursos com o Terraform e publicá-los na nuvem da AWS, proporcionando uma implantação contínua e confiável.

  4. Implementação dos Conceitos Básicos da Arquitetura Hexagonal: Iniciei o estudo para aplicar os conceitos da arquitetura hexagonal, melhorando a estrutura do projeto para torná-lo mais simples de entender e modificar.

Nesta fase do projeto, percebo um grande avanço em meu conhecimento e saio extremamente satisfeito com os resultados alcançados. Estou confiante de que essas melhorias enriqueceram significativamente minha experiência e habilidades no desenvolvimento de software.

Referência

Footnotes

  1. Alistair in the "Hexagone" 1/3.

  2. GitHub Actions. 2

  3. CI/CD.

  4. Git Flow - Alura 2

About

Tech Challenge para avaliação da Fase III da Pós Graduação em Arquitetura e Desenvolvimento Java.

Resources

License

Stars

Watchers

Forks

Packages

No packages published