UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE UNIDADE ACADÊMICA ESPECIALIZADA EM CIÊNCIAS AGRÁRIAS
CURSO SUPERIOR DE TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS
FÁBIO HENRIQUE FERREIRA DE OLIVEIRA
Automação do processo de implantação e testes de um sistema WEB utilizando Docker
Macaíba, RN 2019
FÁBIO HENRIQUE FERREIRA DE OLIVEIRA
Automação do processo de implantação e testes de um sistema WEB utilizando Docker
Trabalho de conclusão de curso de graduação apresentado à Unidade Acadêmica Especializada em Ciências Agrárias da Universidade Federal do Rio Grande do Norte como requisito parcial para a obtenção do título de Tecnólogo em Análise e Desenvolvimento de Sistemas.
Orientador: Prof. Dr. Taniro Chacon Rodrigues
Macaíba, RN 2019
Universidade Federal do Rio Grande do Norte - UFRN Sistema de Bibliotecas - SISBI
Catalogação de Publicação na Fonte. UFRN - Biblioteca Setorial Prof. Rodolfo Helinski - Escola Agrícola de Jundiaí - EAJ
Elaborado por Elaine Paiva de Assunção Araújo - CRB-15/492 Oliveira, Fábio Henrique Ferreira de.
Automação do processo de implantação e testes de um sistema WEB utilizando Docker / Fábio Henrique Ferreira de Oliveira. - 2019.
62 f.: il.
Monografia (tecnólogo) - Universidade Federal do Rio Grande do Norte, Unidade Acadêmica Especializada em Ciências Agrárias, Curso Superior em Análise e Desenvolvimento de Sistemas.
Macaíba, RN, 2019.
Orientador: Prof. Dr. Taniro Chacon Rodrigues.
1. Integração Contínua - Monografia. 2. Implantação
Automática - Monografia. 3. Testes de software - Monografia. I. Rodrigues, Taniro Chacon. II. Título.
FÁBIO HENRIQUE FERREIRA DE OLIVEIRA
Automação do processo de implantação e testes de um sistema WEB utilizando Docker
Trabalho de conclusão de curso de graduação apresentado à Unidade Acadêmica Especializada em Ciências Agrárias da Universidade Federal do Rio Grande do Norte como requisito parcial para a obtenção do título de Tecnólogo (a) em Análise e Desenvolvimento de Sistemas.
Aprovado em: 14 de junho de 2019.
BANCA EXAMINADORA
__________________________________________ Prof. Dr. Taniro Chacon Rodrigues – EAJ/UFRN – Orientador
__________________________________________
Prof. Dra. Laura Emmanuella dos Santos Santana De Oliveira,EAJ/UFRN
__________________________________________ Prof. Dr. Eduardo Alexandre Ferreira Silva – IMD/UFRN
DEDICATÓRIA
Dedico este trabalho primeiramente a Deus, a minha família, professores e amigos que sempre me apoiaram incondicional durante toda esta jornada chamada TADS.
AGRADECIMENTOS
Talvez essa seja a parte mais difícil. mas vamos lá... Primeiramente agradeço a Deus por ter me dado o dom da vida e me proporciona viver todos os momentos! Agradeço aos meus pais, Erismar Brito e Maria Ferreira, por todo acolhimento, amor e ensinamentos para me tornar o ser humano que sou hoje. Ao meu irmão, Carlos Alberto, por sempre me ajudar/perturbar a nunca ficar parada, sempre buscando um novo conhecimento. Mesmo tendo todas as dificuldades do mundo estamos sempre juntos e espero que isso permaneça ate o meu último suspiro.
Taniro Chacon, você é meu pai acadêmico, o melhor que eu poderia ter, sem DÚVIDA. Sou muito grato a você por tudo que já fez por mim, ter acreditado no meu potencial, me dado apoio nos momentos ruins e sempre me aconselhando em todas as minhas decisões. Muito obrigado por tudo e espero que permanecemos sempre amigos independente de tudo.
Amanda Cândido, muito obrigado por tudo que fizestes por mim, pela paciência durante todo este processo, agradeço a Deus por ter colocado você em minha vida e espero que aproveitemos tudo que esse mundo tem a oferecer! Saiba que sempre estarei aqui! “So pack your bags and come with me”. Amo você, meu grande amor!
Adriano Junior, obrigado por tudo que já fez por mim, agradeço por sempre me ajudar nos momentos difíceis e me motivado a continuar no curso mesmo sendo do jeito que és, saiba que sempre poderá contar comigo. Tamo junto!
Aos meus antigos amigos, João Arthur, Yago Gomes, Ítalo Gabriel, Mathews Dantas, Igor Salgado, Victor Hudson, Igor Ladeira, Dudu, Guidão, João Kleber, Matheus Thierry e Iuki, muito obrigado por sempre estarem juntos e por todas as zoeiras que a vida proporciona.
A minha matilha, Raylan Leite, André Mauricio, Manoel Dias, Ewerton Medeiros e Arthur Guedes por sempre estarem presentes mesmo com toda a distância.
A família TADS, tanto o corpo docente como Laura, Josenalde, Leonardo, Eduardo que foram essenciais para o meu aprendizado. Por todo o apoio e vai dá certo que já foi dito, Tuany Mariah, João Gabriel (Pão duro), AdryelSK, Brunão, Pedro PP, Andrade, Hudson, Lucas Antônio, André Gomes, Larysse Savanna, Lucas Assis, Arthur Medeiros, Iaslan, Laércio, Joel, Nicassio, Heriberto, Amanda Kimberly, Eric Couto, Jailton Câmara, Geraldo Junior, Joffrey Peyrac, Luiz Fernando, a todos vocês agradeço de coração por cada risada, cada aprendizado e cada vivência!
A galerinha do SmartMetropolis muito obrigado a sempre ajudar a ser um inovador na programação e criar o hábito da proatividade, Icaro, Gustavo, Matheus, Silvino, Alex, Juliana Oliveira, Rayane Alves, Natanael, Eiji, Fred e Nélio.
A família ESIG por ter sempre ajudado a me tornar um programador melhor, em especial, Lucas Vasconcelos, Allan Araújo, Amanda Silva e Hiarley Martins, meu sincero OBRIGADO!
E por fim, agradeço a você Fábio Henrique, você completou mais um ciclo e sei que todas as dificuldades foram superadas! Parabéns por isso e seja grato por tudo que já tenha passado na vida! Tenha em mente que todo dia você tem a chance de se tornar uma pessoa melhor, então faça desse mundo um lugar melhor, aproveita a vida, colocar um sorriso nessa cara e nunca desista por nada!
"Sempre confiante e cabeça erguida"
RESUMO
Aumentar a produtividade de determinada tarefa é uma necessidade cotidiana no processo de crescimento de uma organização. No desenvolvimento de
software destaca-se a adoção de processos iterativos e incrementais para
aumento da produtividade, promovendo ideias e princípios do desenvolvimento ágil. A integração continua é uma prática que pode ser adotada para que funcionalidades criadas ou modificadas sejam integradas ao sistema diariamente. O Sistema Integrado de Gestão de Unidades de Alimentação e Nutrição (SIGUAN) foi um software desenvolvido durante a execução de um projeto de extensão na UFRN. No entanto, após sua entrega o sistema não recebeu novas atualizações ou manutenções devido a sua complexidade dessas tarefas e da possibilidade de impacto na parte já em funcionamento. Tendo em vista essa problemática e a necessidade da adoção de metodologias ágeis no desenvolvimento este trabalho tem como objetivo automatizar o processo de implantação do SIGUAN, utilizando tecnologias que facilitam a configuração do ambiente de implantação assegurando através de testes de software uma maior qualidade de software. Para atingir tal objetivo, houve a necessidade de criação do módulo de testes de software utilizando ferramentas como Junit e Mockito e houve a configuração do ambiente de produção e de testes utilizando Docker. Tal processo de implantação automática é feita através da configuração da ferramenta do Jenkins. A avaliação deste trabalho foi realizada através da criação de um novo modulo, cujo nome é Análise de Clientela. Os resultados da avaliação mostraram que a implantação automática do SIGUAN atingiu os objetivos esperados.
Palavras-chave: Integração Contínua, Implantação Automática, Testes de software.
ABSTRACT
Increasing the productivity is a daily necessity in the process of growing an organization. In software development, it is worth highlighting the adoption of iterative and incremental processes to increase productivity, promoting ideas and principles of agile development. Continuous integration is a practice that can be adopted for integrating new functionalities into the system. The Integrated Management System of Food and Nutrition Units (SIGUAN) was software developed during the execution of an extension project at UFRN. However, when in production phase the system has not received any new updates or maintenance due to its complexity and the possibility of impact in the part already in operation. Considering such problem and the need to adopt agile methodologies in software development, this work aims to automate the SIGUAN’s implantation process, using technologies that facilitate the configuration of the deployment environment, ensuring through software testing a higher quality of software. To achieve such goal, it was necessary to create a software testing module using Mockito and configuring both production and testing environment using Docker. The automatic deployment process is achieved by configuring the Jenkins tool. The evaluation of this work was done through the creation of a new module, whose name is Clientele Analysis. The results of the evaluation showed that the automatic implementation of SIGUAN achieved the expected objectives.
LISTA DE FIGURAS
Figura 1: Comparação entre Máquina Virtual e contêineres do Docker. ... 17
Figura 2: Logo do Jenkins ... 19
Figura 3: Exemplo de plugin do Jenkins. ... 20
Figura 4. Complexidade Ciclomática ... 23
Figura 5: Logo do Junit ... 25
Figura 6: Logo do Mockito ... 25
Figura 7: Modelo arquitetural de visões 4+1 ... 26
Figura 8: Processo de envio do código para o GitHub. ... 27
Figura 9: Inserção do .WAR do SIGUAN ao servidor ... 28
Figura 10: Organização do projeto SIGUAN. ... 29
Figura 11: Criação de um job no Jenkins. ... 36
Figura 12: Configuração da comunicação ao repositório do Github. ... 37
Figura 13: Configuração do build do SIGUAN no Jenkins. ... 37
Figura 14: Configuração do deploy do SIGUAN ao servidor de testes. ... 38
Figura 15: Configuração do gatilho de execução do job do ambiente de produção. ... 39
Figura 16: Configuração do build do SIGUAN no Jenkins sem execução dos testes. ... 39
Figura 17: Configuração do deploy do SIGUAN ao servidor de produção.40 Figura 18: Novo processo de inserção do SIGUAN ao servidor. ... 41
Figura 19. Configuração da prática de revisão de código ... 42
Figura 20. Configuração de build automático no Jenkins. ... 43
Figura 21. Configuração de build automático no Github. ... 43
Figura 22: Diagrama de Casos de uso do Módulo de Análise de Clientela 45 Figura 23: Visão do Diagrama de Classe do Módulo de Clientela ... 46
Figura 24. Arquitetura do novo módulo como base no SIGUAN. ... 47
Figura 25. Diagrama de atividades do módulo de Análise de Clientela. .... 48
Figura 26. Diagrama de implantação do SIGUAN. ... 49
Figura 27. Processo de revisão de código. ... 50
Figura 28. Build no Jenkins do ambiente de testes. ... 50
Figura 29. Build no Jenkins do ambiente de produção. ... 50
Figura 30. Criação da análise de comensais ... 51
Figura 31. Cálculo da média calórica. ... 51
Figura 32. Cadastro de Prescrição com a utilização do módulo de Análise de Clientela. ... 52
LISTA DE TRECHOS DE CÓDIGO
Trecho de código 1. Exemplo de uma imagem. ... 18
Trecho de código 2. Exemplo em código de um docker-compose. ... 18
Trecho de código 3. Exemplo de um pseudocódigo. ... 22
Trecho de código 4. Exemplo de um teste Unitário do pacote modelo utilizando Junit. ... 30
Trecho de código 5. Exemplo de Teste de Integração do pacote Service utilizando Junit e Mockito ... 31
Trecho de código 6. Configuração do Dockerfile da imagem do Jenkins. 32 Trecho de código 7. Configuração do Dockerfile da imagem do Tomcat. . 33 Trecho de código 8. Configuração do docker-compose do ambiente de produção. ... 34
Trecho de código 9. Configuração do docker-compose-test do ambiente de teste ... 35
Trecho de código 10. Arquivo manager.xml ... 56
Trecho de código 11. Arquivo tomcat-users.xml ... 12
LISTA DE TABELA
Tabela 1. Exemplo da técnica de caixa preta. ... 23
Tabela 2. Quantitativo de testes criados no SIGUAN ... 29
Tabela 3. Requisitos Funcionais ... 44
Tabela 4. Especificação das classes do diagrama de classe ... 46
SUMÁRIO 1. INTRODUÇÃO ... 12 1.1 JUSTIFICATIVA ... 14 1.2 OBJETIVOS ... 15 1.2.1 OBJETIVO GERAL ... 15 1.2.2 OBJETIVOS ESPECÍFICOS ... 15 2. CONCEITOS BÁSICOS ... 16 2.1 DOCKER ... 16 2.2 JENKINS ... 19 2.3 QUALIDADE DE SOFTWARE ... 20 2.3.1 REVISÃO DE CÓDIGO ... 20 2.3.2 TESTE AUTOMATIZADOS ... 21 2.3.3 TESTE UNITÁRIOS ... 21 2.3.4 TESTE DE INTEGRAÇÃO ... 23 2.4 JUNIT ... 24 2.5 MOCKITO ... 25 3. DESENVOLVIMENTO ... 26
3.1 PROCESSO ANTIGO DE IMPLANTAÇÃO DO SIGUAN ... 27
3.2 NECESSIDADE DE CRIAÇÃO DE UM MÓDULO DE TESTES ... 28
3.3 CONFIGURAÇÃO DO AMBIENTE DE PRODUÇÃO E TESTE UTILIZANDO DOCKER ... 31
3.4 CONFIGURAÇÃO DO JENKINS ... 35
3.5 NOVO FLUXO DE IMPLANTAÇÃO ... 40
4. AVALIAÇÃO ... 44 4.1 PROBLEMA ... 44 4.2 ARQUITETURA ... 45 4.3 RESULTADOS OBTIDOS ... 49 5. CONCLUSÃO ... 53 5.1 TRABALHOS FUTUROS ... 53 REFERÊNCIAS ... 54
1. INTRODUÇÃO
Aumentar a produtividade de determinada tarefa é uma necessidade cotidiana no processo de crescimento de uma organização. Com as possibilidades trazidas pela Tecnologia da Informação, empresas, instituições e organizações públicas e privadas estão adotando cada vez mais o uso de novas tecnologias para aumentar sua produtividade. Nesse contexto, Sistemas de Informação (SI) destacam-se entre as tecnologias mais utilizadas no ambiente das organizações. Tais sistemas têm como objetivo principal coletar, armazenar, processar e distribuir informações para execução de ações e auxílio no processo de tomada de decisão e no controle de uma organização (WAKULICZ, 2016).
O potencial de Sistemas de Informação tem afetado diretamente o mercado com novas ideias, novas tecnologias, novas metodologias e novas culturas para o desenvolvimento de software. Na década de 70 até metade de 90, o processo de desenvolvimento mais utilizado por equipes de desenvolvedores seguia o chamado Modelo Cascata (do inglês Waterfall Model), desenvolvido por Winnston W. Royce (PRESSMAN, 2016, p. 60). Tal processo era caracterizado pelo uso um fluxo de atividades sequencial e sistemática seguido de maneira rígida, sem que o cliente tivesse feedback durante o processo de desenvolvimento, impossibilitando que necessidades imediatas pudessem influenciar o planejamento. Essa característica torna a adoção de tal modelo um problema para o desenvolvimento de sistemas de informação nos dias de hoje, pois caso ocorram mudanças de requisitos, tais mudanças só poderiam ser realizadas após a finalização do software por completo, indo na contramão da demanda por entrega rápida e de qualidade do produto de software.
Além do modelo Cascata como um processo de desenvolvimento de software, existem diversos, como Modelo RAD (Rapid Application Development, ou em português, Desenvolvimento Rápido de Aplicação) (VELASQUEZ, 2009), Modelo de Prototipação (LESSA e LESSA JUNIOR, 2013), Modelo em V (PRESSMAN, 2016, p. 61), entre outros. Dentre os citados, cada um tem suas desvantagens, por exemplo, o modelo RAD requer um custo altíssimo no desenvolvimento devido a um prazo curto de tempo para o desenvolvimento de software, já o modelo de prototipação tem como desvantagem requisitos não
funcionais não serem testados de forma adequada e, por fim, o modelo em V tem problemas similares ao Modelo Cascata, como a baixa flexibilidade de mudanças de requisitos e demora para produzir valor para o cliente.
Tendo em vista a problemática inerente ao processo de desenvolvimento de
software, no ano de 2001 foi proposto o Manifesto Ágil (CURADO et al., 2016).
O desenvolvimento de um software seguindo uma metodologia ágil está ligado a valores e princípios (FADEL, 2010) e promove o uso de um processo de desenvolvimento de maneira iterativa e incremental. O desenvolvimento de
software através de um processo iterativo significa que o software é desenvolvido
já com a ideia de mudar ou evoluir. Sempre que um artefato é construído é preciso realizar uma análise para saber se tal artefato atende os requisitos. Já no desenvolvimento de software através de um processo incremental, partes do
software são construídas incrementalmente, ou seja, a cada incremento, uma
nova funcionalidade é incorporada ao produto.
Partindo do pressuposto de desenvolvimento ágil de software, surge o paradigma de Integração Contínua (CHEN, 2017), uma prática de desenvolvimento de software onde os membros de um time integram seu trabalho frequentemente, ou seja, os desenvolvedores criam ou modificam funcionalidades para serem incorporadas ao produto de software. Cada integração é verificada por uma construção automatizada do sistema (incluindo testes) para detectar erros de integração o mais rápido possível. A adoção dessa abordagem leva a uma potencial redução nos problemas de integração e permite que um time desenvolva software de maneira pragmática e rápida (GOTTESHEIM, 2015).
Apesar da eficácia desses métodos e da rápida popularização, ainda não são práticas padronizadas, como por exemplo um sistema desenvolvido na Escola Agrícola de Jundiaí (EAJ). Nos anos de 2017 e 2018 foi executado um projeto de extensão para o desenvolvimento do Sistema Integrado de Gestão de Unidades de Alimentação e Nutrição (SIGUAN). O objetivo desse sistema era auxiliar o nutricionista no processo de planejamento e execução de cardápios das Unidades de Alimentação e Nutrição (UAN) (SILVA, 2018). Fizeram parte da equipe de desenvolvimento estudantes do curso de Tecnologia em Análise e
Desenvolvimento de Sistemas. Tal projeto foi entregue com suas principais funcionalidades atendidas. No entanto, devido a sua alta complexidade o sistema se tornou difícil de manter ou evoluir, pois atualizações para atender novos requisitos não garantiam que não houvesse impacto no código já implementado. Dessa forma, o sistema parou de receber atualizações.
1.1JUSTIFICATIVA
A versão do SIGUAN entregue não era capaz de realizar Integração Contínua e não havia um processo de testes de software automatizado. Caso houvesse o desenvolvimento de um novo módulo, ele poderia prejudicar a parte já funcional. Outra problemática identificada foi a adoção de um processo manual para implantação de atualizações do sistema. Nesse sentido, para cada atualização do sistema era gerado um novo arquivo de implantação a ser instalado manualmente no servidor, uma tarefa lenta e propensa a erros, ou seja, inadequada dentro de um contexto de desenvolvimento utilizando uma metodologia do desenvolvimento ágil.
Nesse contexto, observou-se a necessidade de implementar uma camada de testes e automatizar a implantação do SIGUAN, visto que este processo tem o potencial de facilitar a integração de novas funcionalidades, garantindo que o sistema que já foi desenvolvido se mantenha sem erros e promovendo um aumento na velocidade do feedback dos clientes que o utilizam.
Além disso, atualmente o SIGUAN está implantado em uma máquina virtual configurada para determinado sistema operacional, com determinadas bibliotecas funcionando sobre determinado hardware. As múltiplas possibilidades de configurações segundo as tecnologias existentes tornam o processo de replicação do ambiente de desenvolvimento uma tarefa custosa e propensa a erros. O novo processo de implantação proposto nesse Trabalho de Conclusão de Curso simplificará a configuração de um servidor devido a utilização de ferramentas que auxiliam na padronização configuração de um novo servidor.
Para avaliar o processo desenvolvido nesse trabalho será apresentado um estudo de caso que demonstra os passos para criação de um novo módulo para
o sistema. Tal módulo já estava previsto como uma extensão do SIGUAN. O objetivo do novo módulo será criar meios para a realização da atividade da Análise de Clientela que tem como objetivo auxiliar o nutricionista na preparação de um novo cardápio a partir das informações calóricas da clientela do Restaurante Universitário.
1.2OBJETIVOS
A seguir são apresentados o objetivo geral e os objetivos específicos deste trabalho.
1.2.1 OBJETIVO GERAL
Para auxiliar no desenvolvimento seguindo os princípios estabelecidos no Manifesto Ágil juntamente com o paradigma da Integração Contínua, este trabalho possui como objetivo proporcionar ao SIGUAN um ambiente adequado para implantações de novos requisitos de maneira rápida e com garantia do mínimo de qualidade através da especificação de um novo fluxo do processo de implantação.
1.2.2 OBJETIVOS ESPECÍFICOS
Como objetivos específicos podem ser citados:
a) Especificação da configuração da implantação do ambiente de testes e de produção através do uso de tecnologias que possam padronizar tais configurações de modo a habilitar seu uso em quantos ambientes foram necessários sem que seja necessário configurar individualmente cada ambiente. b) Especificação do processo de implantação através do uso de tecnologias que organizam todos os passos necessários para criações de pacote de uma aplicação.
c) Especificação do Módulo de Testes Automatizados através do uso de tecnologias que facilitem o aprendizado e o desenvolvimento rápido.
2. CONCEITOS BÁSICOS
Este Capítulo apresenta os conceitos básicos sobre abordagens e tecnologias utilizadas para o desenvolvimento deste Trabalho de Conclusão de Curso. O Capítulo 2 está organizado da seguinte forma: a seção 2.1 apresenta a ferramenta Docker que facilita a criação e administração de ambientes isolados; a seção 2.2 descreve sobre o Jenkins utilizado para desenvolver a prática de Integração Contínua; a seção 2.3 apresenta um pouco sobre a importância dos testes automatizados; as seções 2.3.1 e 2.3.2 apresenta a definição de testes unitários e testes de integração, respectivamente; as seções 2.4 e 2.5 descrevem os frameworks JUnit e Mockito, utilizados para desenvolver os testes automatizados.
2.1 DOCKER
Um problema recorrente na entrega de um software são as diferenças entre versões de ambientes de uma mesma plataforma como Java 7, Java 10 entre outras versões. Para que seja configurado um novo servidor considerando a versão adequada de cada ambiente ou biblioteca é um trabalho custoso principalmente quando se considera a necessidade de replicação do ambiente de implantação de um sistema.
O Docker é uma plataforma open source desenvolvida em linguagem de programação Go (DOCKER, 2019) que apresenta uma coleção interoperável de soluções de software-as-a-service (software como serviço) e
platform-as-a-service (plataforma como serviço) através de virtualização no nível do sistema
operacional. Por isso, a utilização do Docker se torna valiosa devido a facilidade configuração de novos ambientes, garantindo uma rápida disponibilização do
software ao usuário final, proporcionando o desenvolvimento e a entrega de software dentro de pacotes padronizados chamados containers.
Um container é um ambiente isolado onde podem ser definidas características de hardware e software como memória, rede, sistema operacional, aplicações, serviços, entre outros.
A Figura 1 ilustra a arquitetura Docker e destaca sua principal diferença em relação a uma virtualização tradicional.
Figura 1: Comparação entre Máquina Virtual e contêineres do Docker. Fonte: (DOCKER, 2019)
Inicialmente os conceitos de máquina virtual e container Docker são parecidos por necessitar de uma infraestrutura, como um computador ou servidor virtual, e um sistema operacional (SO). No entanto, na máquina virtual existe a camada conhecida como Hypervisor, que é responsável pelo controle de acesso dos sistemas operacionais visitantes aos dispositivos de hardware. As próximas camadas são os SO convidados, juntamente com a camada de binários e bibliotecas e, por fim, a aplicação. Já no container Docker, encontra-se Docker Daemon, um encontra-serviço utilizado para fazer a comunicação entre o SO e
container do Docker. As próximas camadas gerenciadas pelo Docker são
binários e bibliotecas juntamente com a aplicação.
Para a utilização de um container Docker é necessária a configuração de uma imagem de container. Uma imagem é a representação estática do aplicativo ou serviço ou de configurações e dependências. As imagens Docker são totalmente personalizáveis e podem ser espelhadas ou armazenadas no Docker
Hub (DOCKER HUB, 2019), um serviço de registro em nuvem que permite ao
desenvolvedor criar repositórios de imagens Docker. A utilização do Docker Hub facilita o acesso de imagens através da web. O Trecho de código 1 ilustra uma imagem Docker personalizada.
1 #Utiliza a imagem do ubuntu disponibilizada no Docker Hub 2 FROM ubuntu:16.04
3 #Executar a instalação do nginx
4 RUN apt-get update && apt-get install -y make git openjdk-8-jdk
Trecho de código 1. Exemplo de uma imagem.
O Trecho de código 1 apresenta um Dockerfile que faz a configuração da imagem que será utilizada por um container Docker. A linha 2 é referenciado a imagem do Ubuntu 16.04 disponível no Docker Hub e na linha 4 é ilustrado, após sua execução, a instalação o Java 8.
Para a utilização de múltiplas imagens de containers ao mesmo tempo é necessário a utilização do Docker Compose, um arquivo de configuração para execução de todo o ambiente de maneira independente. As configurações são realizadas utilizando a linguagem de marcação YAML (Yet Another Markup
Language, que pode ser traduzido como “Uma outra linguagem de marcação”).
O Trecho de código 2 ilustra um exemplo de configuração através de um arquivo docker-compose. 1 version: '3' 2 services: 3 app: 4 image: yuri/web 5 ports: 6 - 8080:80 7 links: 8 - db 9 db: 10 image: mysql 11 environment: 12 - MYSQL_USER=root 13 - MYSQL_ALLOW_EMPTY_PASSWORD=yes 14 - MYSQL_DATABASE=loja
Trecho de código 2. Exemplo em código de um docker-compose.
O Trecho de código 2 apresenta um arquivo docker-compose para
realizar a configuração do ambiente utilizando duas imagens. A linha 1 é enunciada a versão utilizada do docker-compose, atualmente o próprio Docker recomenda o uso da versão 3. A linha 2 é ilustrado o que será contido no
container, ou seja, onde será feita a declaração de bibliotecas e da aplicação.
Para que a aplicação seja executável, um serviço de app é definido nas linhas 4 até 6, tal serviço está disponível em uma imagem padrão disponível no Docker
configurado com base em outra imagem, também disponível no Docker Hub. Por fim, é configurada, na linha 8, a comunicação entre o serviço app e o serviço db. 2.2 JENKINS
Jenkins (JENKINS, 2019) é uma plataforma de código aberto cujo objetivo é automatizar a parte não humana do processo de desenvolvimento de software, atendendo o paradigma da integração contínua e facilitando os aspectos técnicos da entrega contínua.
Figura 2: Logo do Jenkins Fonte: (JENKINS, 2019)
O Jenkins foi completamente escrito em Java e é facilmente extensível graças à sua arquitetura em estilo plugin e pontos de extensão. Tais pontos são interfaces ou classes abstratas que especificam seu comportamento adicionando novas funções ao Jenkins e os desenvolvedores têm total liberdade de alteração do código. Isso faz com que Jenkins seja altamente personalizável e flexível, capaz de cobrir diversos requisitos graças aos milhares de plugins desenvolvidos pelo seu enorme Open Source Community. Na Figura 3 ilustra um exemplo de um plugin, este plugin é responsável por fazer o deploy dos arquivos de construção do software em um servidor.
Figura 3: Exemplo de plugin do Jenkins. Fonte: (PLUGIN JENKINS, 2019)
2.3 QUALIDADE DE SOFTWARE
Segundo o guia Software Engineering Body of Knowledge (SWEBOK, 2019), conhecido pela sigla SWEBOK, a qualidade de software está totalmente ligado a um software coeso, de fácil manutenção, integridade de dados para que não ocorra comportamentos inesperados e na facilidade de evolução. Para atingir tal objetivo com menor complexidade existem diversas práticas e técnicas, entre elas existem, a revisão de código e testes automatizados e integração contínua, como foi supracitado na Seção 2.2 JENKINS, que servem para aumentar a qualidade de software através da redução da quantidade de falhas que o software pode apresentar.
2.3.1 REVISÃO DE CÓDIGO
A revisão de código é uma prática apresenta diversas vantagens na melhoria da qualidade de software. Tal prática se dá a partir do código escrito por um desenvolvedor, antes de ser aceito no projeto, será revisado por outro desenvolvedor da equipe.
Tal prática pode acontecer de diversas maneiras. Numa delas, conhecida como programação pareada, os desenvolvedores trabalham juntos discutindo cada trecho de código. Outra prática de revisão considera que um desenvolvedor fica responsável pela revisão das alterações, avaliando as modificações solicitadas, contribuindo com comentários e observações e, eventualmente,
aceitando ou rejeitando as alterações. Se aceitas, as alterações são finamente propagadas para o código-fonte.
2.3.2 TESTE AUTOMATIZADOS
A automatização de testes é um tema de grande relevância quando se fala em qualidade de software e, por isso, deve ser considerado em todos os projetos de software. Nos testes automatizados são executados diversos tipos de testes identicamente e inúmeras vezes simulando situações específicas, facilitando a identificação de um possível comportamento inesperado.
Além disso, a utilização de testes automatizados de software permite verificar automaticamente que pequenos incrementos de software não afetem funcionalidades que já funcionavam anteriormente. Esse benefício é particularmente importante em sistemas com longo ciclo de vida no mercado. Com isso, essas novas funcionalidades também terão seus fluxos automatizados, de maneira que a cada nova execução uma quantidade maior de testes será executada.
Outra vantagem decorrente da automação é que os testes podem ser executados numa frequência maior. Dessa forma, é possível obter um rápido feedback de qualquer implementação realizada que impacte alguma funcionalidade que já foi implantada, proporcionando um aumento na velocidade de resolução do comportamento inesperado e na qualidade da entrega realizada. Assim, com a adoção de testes automatizados é possível reduzir o tempo de desenvolvimento e, principalmente, o tempo gasto em ajustes na implementação realizada.
2.3.3 TESTE UNITÁRIOS
O objetivo dos testes unitários, segundo (DURVAL et al, 2007), é validar o comportamento de pequenos elementos em um sistema, elementos esse que, na programação orientada a objetos, geralmente constitui uma classe. Assim sendo, o teste unitário é aquele que testa os métodos de uma classe.
Para criação de testes unitários são utilizadas diversas técnicas, dentre elas, existem testes de caixa preta e testes de caixa branca (DIAS NETO, 2015).
Para a utilização do teste de caixa branca, também conhecido como teste estrutural, o desenvolvedor tem acesso ao código-fonte para analisar a estrutura interna do produto, facilitando assim a projeção do teste para que tenha uma averiguado mais precisa do comportamento da estrutura a ser testada. O Trecho
de código 3 é um exemplo em pseudocódigo.
1 enquanto existir registro faça 2 leia registro
3 se registro.campo1 = 0 então
4 processar registro e armazenar em buffer 5 incrementar contador
6 senão se registro.campo2 = 0 então 7 resetar contador
Senão
8 processar registro e armazenar em arquivo 9 fimse
10 fimse 11 fimenquanto
Trecho de código 3. Exemplo de um pseudocódigo. FONTE: (PIMENTEL, 2016).
O Trecho de código 3 apresenta um pseudocódigo onde é ocorre o processamento de uma determinada tarefa. Na técnica de caixa branca é utilizado uma métrica de software conhecida como Complexidade Ciclomática, cujo objetivo é indicar o número de caminhos que a função pode executar, ou seja, os testes são criados a partir de diversos cenários que um código pode ter ao final de seu fluxo. Na Figura 4 é ilustrado a Complexidade Ciclomática do
Figura 4. Complexidade Ciclomática FONTE: (PIMENTEL, 2016).
Por outro lado, nos testes de caixa preta, também conhecidos como testes funcionais, o desenvolvedor não tem acesso ao código fonte, tendo como base os requisitos funcionais do software, ou seja, os testes são voltados para que cada requisito seja desempenhado sua função específica. A técnica de caixa preta é feita baseada nos requisitos funcionais e requisitos não funcionais do
software, ou seja, os testes criados a partir de ações que uma função pode
desempenhar. Na Tabela 1 ilustra um exemplo utilizando a técnica de caixa preta.
Tabela 1. Exemplo da técnica de caixa preta. Categoria Verificação Descrição
Vazamentos de Informações
Mensagem de erro
Verificar se a aplicação exibe mensagens de erro com informações confidenciais ou que sirvam como dica para um hacker, ex: (usuário não existe, senha incorreta, entre outros).
Dados sensíveis em html
Verificar se não existem dadas sensíveis no HTML como por exemplo, comentários, etc.
Tratamento Inadequado de entrada/saída de dados
Injeção de scripts
Verificar se a aplicação não processa scripts como parte inadequado de das entradas.
Injeção de comandos do sistema operacional
Verificar se aplicação não processa as comandas do sistema operacional injetados pelo usuário.
2.3.4 TESTE DE INTEGRAÇÃO
2007), pela verificação de partes maiores do sistema que dependem de recursos externos, como banco de dados, sistemas de arquivos ou endpoints de rede. Estes testes verificam se os componentes em análise realmente produzem o comportamento esperado.
Um teste de integração comum a muitas aplicações é aquele que valida as ações executadas contra um banco de dados. Considerando que o acesso a recursos externos sempre demanda mais tempo do que um acesso direto à memória (por questões diversas, como latência de rede, leitura de disco, dentre outras).
A integração pode ser incremental ou não-incremental. Na integração não incremental as unidades são testadas individualmente e depois integradas de uma só vez. Isso torna o teste menos eficaz, pois torna-se difícil isolar um erro e, quando esses são corrigidos, novos erros são gerados na estrutura do programa. Já na integração incremental, o programa construído é testado em pequenos segmentos, tornando o teste mais eficiente, pois os erros são mais fáceis de serem isolados e corrigidos e as interfaces têm maior probabilidade de serem testadas corretamente (PRESSMAN, 2016-).
Para a realizar os testes unitários e de integração existem diversos
frameworks que facilitam seu desenvolvimento. Neste trabalho foi utilizado o Junit e Mockito, respectivamente, explicados posteriormente na Seção 2.4 JUNIT
e 2.5 MOCKITO. 2.4 JUNIT
O JUnit (JUNIT, 2019) é um framework Open Source, criado por Erich Gamma e Kent Beck, com foco em desenvolver testes automatizados para códigos Java visando melhoria no software.
Este framework facilita a criação e manutenção do código para a automação de testes com apresentação dos resultados que podem ser classificados como aprovado, falha ou reprovado. Sendo assim, o desenvolvedor poderá usar esta ferramenta para criar diversos cenários para cada tipo de testes.
Figura 5: Logo do Junit Fonte: (JUNIT, 2019)
2.5 MOCKITO
Uma característica chave para um bom teste unitário é o isolamento de dependências externas como acesso à rede, ao sistema de arquivos, a banco de dados, entre outros. Porém, quando há a necessidade de testar um código que faz acesso à camada de persistência ocorre diversos problemas como complexidade de implementação e perderá o isolamento de suas dependências. A solução para o problema citado, é simular o acesso à camada de persistência fazendo a utilização de mocks ou stubs, que são objetos que simulam o comportamento de objetos reais, facilitando e acelerando assim o desenvolvimento da funcionalidade em questão.
Então, o Mockito (MOCKITO, 2019) é um framework Open Source utilizado para a criação de mocks em sistemas Java. Por ter uma API bastante intuitiva, seu uso é bastante simples e a própria página do projeto contém documentação suficiente para auxiliar os desenvolvedores.
Figura 6: Logo do Mockito Fonte: (MOCKITO, 2019)
3. DESENVOLVIMENTO
Este Capítulo descreve a fase de desenvolvimento do novo processo de implantação do SIGUAN. Tal processo se resume na criação de testes de software automatizado e na configuração do ambiente de produção e de testes para a realização da prática de Integração Contínua. O Capítulo 3 está organizado da seguinte forma: a seção 3.1 descreve como era feito o antigo processo de implantação do SIGUAN; a seção 3.2 apresenta como se deu a criação do módulo de testes; a seção 3.3 ilustra as configurações feitas para o ambiente de produção e de testes; a seção 3.4 exemplifica as configurações feitas para implantar automaticamente o SIGUAN; a seção 3.5 ilustra como ficou o novo processo de implantação automático.
Na versão entregue ao final do projeto de extensão, o processo de implantação do SIGUAN se dava a partir da criação de um arquivo de compilação do código fonte que era implantando manualmente no servidor Tomcat para que o sistema ficasse disponível para os usuários. Tal processo é propenso a erros, devido à ausência de testes na compilação do arquivo, e lento para ser efetivado, devido o processo manual.
Figura 7: Modelo arquitetural de visões 4+1 Fonte: (KRUCHTEN, 1995)
O SIGUAN foi desenvolvido com base no modelo arquitetural de Visões 4+1 (KRUCHTEN, 1995), onde a especificação da arquitetura de software está
organizada em torno de cinco visões, a saber: a Visão lógica, responsável pela especificação dos requisitos do sistema; Visão de Implementação, responsável pela descrição de cada módulo do sistema; Visão de Processos, encarregada de descrever como cada funcionalidade se comunica; Visão de Implantação responsável pela instalação da aplicação; e, por fim, Visão de Casos de Uso, o “+1”, descreve os requisitos funcionais e não funcionais em maior nível de abstração e serve de base para as outras visões. Na Figura 7 é ilustrado a como é a organização do modelo 4 + 1.
Sendo assim, o foco deste trabalho é voltado para Visão de Implantação, pois é nessa visão que são necessárias modificações para que o sistema possa adotar um processo de Integração Contínua. Dessa forma, na seção 3.1 apresenta o antigo modelo de implantação utilizado no SIGUAN; a seção 3.2 descreve a necessidade e como foram implementados os testes automatizados; a seção 3.3 é ilustrado como foi implementado o novo fluxo de implantação do SIGUAN.
3.1 PROCESSO ANTIGO DE IMPLANTAÇÃO DO SIGUAN
Na versão inicial do SIGUAN, o sistema era implantado da seguinte maneira: primeiramente o desenvolvedor realizava suas alterações no código-fonte para atender os novos requisitos. Após realizadas tais mudanças, o desenvolvedor enviava o código para um repositório na web para que todos os outros desenvolvedores pudessem compartilhar de tais modificações. A Figura
8 ilustra esse processo de envio do código-fonte para o repositório.
Figura 8: Processo de envio do código para o GitHub.
Em seguida, para que as atualizações chegassem ao cliente, o desenvolvedor deveria compilar código-fonte para gerar um arquivo de implantação contendo todo o código compilado e suas dependências para, só
então, acessar a GUI de implantação do servidor web (Tomcat) e instalar tal mudança no servidor web.
Figura 9: Inserção do .WAR do SIGUAN ao servidor
3.2 NECESSIDADE DE CRIAÇÃO DE UM MÓDULO DE TESTES
No processo apresentado na Seção 3.1 PROCESSO ANTIGO DE IMPLANTAÇÃO DO SIGUAN, o código-fonte compilado a ser implantado no servidor não passava por nenhum processo de verificação ou validação. Tal situação era problemática, pois não havia garantia de que um módulo adicionado fosse minimamente compatível com a implementação já existente.
Dessa forma, surgiu a necessidade de definição de um processo sistemático para verificação e testes antes da realização da implantação. Para atender tal demanda foi especificado um protocolo para revisão do código-fonte e implementado um módulo de testes de software que deverá ser executado sempre que o código for compilado em uma nova versão.
Para o desenvolvimento do módulo de testes foram utilizadas ferramentas como Junit e Mockito para automatizar os testes de software. A Figura 10 ilustra como ficou organizado a estrutura do projeto com o pacote do código-fonte e pacote de testes.
Figura 10: Organização do projeto SIGUAN.
Os testes foram implementados para atender toda lógica de negócio utilizando a técnica de testes de caixa branca. Foram criados testes para todas as classes do modelo, do banco de dados e dos serviços. A Tabela 2 ilustra a quantidade e de que tipo foram os testes criados no SIGUAN. É possível notar na tabela que não foram implementados os testes para todos os caminhos, visto que este trabalho tem como foco a Integração Contínua, o módulo de testes foi implementado de maneira a atender apenas os itens que fazem um CRUD em certos recursos do SIGUAN. Além disso, o código do SIGUAN não foi desenvolvido pensado em testes, dessa forma parte do código exige a realização de refatoração para que seja possível realizar testes de maneira adequada.
Tabela 2. Quantitativo de testes criados no SIGUAN
Pacote Tipo Quantidade
Estimativa do número de testes
necessários
Model Testes Unitários 35 689
Service Testes Unitários
e Integração 104 741
DAO Testes Unitários
e Integração 102 45
O Trecho de código 4 abaixo exemplifica um teste unitário do SIGUAN. Neste exemplo, um teste unitário é realizado no trecho de código onde ocorre a criação de um objeto de TipoCorte, uma classe do SIGUAN. Na linha 9, através do Junit é verificado se a criação desse objeto foi realizada de maneira correta.
1 package com.pa2.model; 2
3 import org.junit.Test;
4 import static org.junit.Assert.*; 5 public class TipoCorteTest { 6 @Test
8 TipoCorte obj = new TipoCorte("Corte", "Descrição", "Observação");
9 assertFalse("Cadastrado do " + obj + " com sucesso",obj.isAtivo());
10 } 11 }
Trecho de código 4. Exemplo de um teste Unitário do pacote modelo utilizando Junit.
O Trecho de código 5 exemplifica um teste de integração do pacote
service do SIGUAN. Nas linhas 18 até 22, ocorre a utilização do framework
Mockito, onde os objetos que fazem a comunicação com o banco de dados são criados para simulação. Posteriormente, na linha 28, ocorre através do Mockito a chamada do real método implementado para que seja inserido no banco de dados. Por fim, na linha 29, através do JUnit, é verificado se o objeto inserido no banco foi realmente criado.
1 package com.pa2.servico; 2 3 import com.pa2.dao.TipoCorteDAO; 4 import com.pa2.model.TipoCorte; 5 import com.pa2.resposta.MensagemException; 6 import org.junit.Test;
7 import static org.junit.Assert.*; 8 import org.junit.Before;
9 import org.junit.Ignore; 10 import org.mockito.Mockito; 11
12 public class ServicoCorteTest { 13
14 TipoCorteDAO tipoCorteDAO; 15 ServicoCorte servicoCorte; 16
17 @Before
18 public void setup() {
19 servicoCorte = Mockito.mock(ServicoCorte.class); 20 tipoCorteDAO = Mockito.mock(TipoCorteDAO.class); 21 servicoCorte.setTipoCorteDAO(tipoCorteDAO); 22 } 23 24 @Test
25 public void salvar() throws MensagemException {
26 TipoCorte tipoCorte = new TipoCorte("Nome do corte", "Descrição", "Observação"); 27 28 Mockito.when(servicoCorte.criarTipoCorte(tipoCorte)).thenCallRealMet hod(); 29 assertNotNull(servicoCorte.criarTipoCorte(tipoCorte)); 30 } 31 /*Continuação do código...*/ 32 }
Trecho de código 5. Exemplo de Teste de Integração do pacote Service utilizando Junit e Mockito
Um detalhe importante presente no Trecho de código 5 é a utilização de uma chamada do método real. A chamada do método real para o banco de dados causa um impacto negativo, pois coloca no banco, dados utilizados para testes. Visando isolar esse problema foi criado um container específico para testes que segue exatamente as mesmas configurações do container de produção. Mais detalhes dessa configuração são apresentados na seção 3.3 CONFIGURAÇÃO DO AMBIENTE DE PRODUÇÃO E TESTE UTILIZANDO DOCKER.
3.3 CONFIGURAÇÃO DO AMBIENTE DE PRODUÇÃO E TESTE UTILIZANDO DOCKER
Na versão do SIGUAN entregue ao final do projeto de extensão contava com um processo de implantação manual. Além disso, toda as configurações do servidor eram feitas de maneira não sistemática, isto é, para configurar dois servidores aptos a receber o SIGUAN todo o processo de instalação e configuração de software era reproduzido do zero tornando a replicação do servidor um processo custoso e propenso a erros. Em vias de suprimir as questões apontadas, essa seção apresenta um novo processo de implantação, realizado a partir da configuração de containers e da configuração do processo de implantação automática.
Para que a implantação seja feita de forma pragmática, é necessário que os testes implementados na seção 3.2 NECESSIDADE DE CRIAÇÃO DE UM MÓDULO DE TESTES sejam feitos de acordo com o ambiente de produção. Visto que alguns testes de software afetavam o banco de dados com a criação de uma massa de dados, houve a necessidade da criação de um ambiente de testes idêntico ao ambiente de produção.
Tais ambientes foram configurados através da conveniência da ferramenta do Docker, onde múltiplos ambientes independentes podem ser idênticos devido as imagens, conforme explicada na seção 2.1 DOCKER.
Sendo assim, o container Docker foi divido em dois ambientes, produção e testes. Estes dois ambientes serão configurados utilizando Java 8, Tomcat 8.5,
MySQL 5.7, e no ambiente de testes, além destas configurações, terá a
todo o processo de implantação do SIGUAN no servidor. A seguir são abordados os detalhes dessas configurações.
Primeiramente foi necessário especificar uma imagem customizada da ferramenta do Jenkins, pois algumas configurações eram necessárias para que ocorresse o processo de implantação automática. Tais configurações são relatadas nos Trecho de código 6, referindo a configuração da ferramenta do Jenkins.
1 #Utilização da imagem do Jenkins fornecida no Docker hub
2 FROM jenkins/jenkins:2.172
3 #Utilização do usuário administrador do sistema 4 USER root
5 #Instalação do java 8
6 RUN apt-get update && apt-get install -y make git openjdk-8-jdk
7 #Criação de pasta que receberá o backup do Jenkins
8 RUN mkdir /srv/backup && chown jenkins:jenkins /srv/backup
9 #Utilização do usuário configurado pela imagem do Jenkins 10 USER Jenkins
11 #Remoção das telas de configurações quando inicia o Jenkins 12 RUN echo 2.172 >
/usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state
13 RUN echo 2.172 >
/usr/share/jenkins/ref/jenkins.install.InstallUtil.lastExecVersion
14 #Copia os plugins que serão instalados assim que a imagem for implantada
15 COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
16 #Instala os plugins que foram copiados 17 RUN /usr/local/bin/install-plugins.sh <
/usr/share/jenkins/ref/plugins.txt
18 #Configurando a varíavel de ambiente do java 19 ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
20 #Copia o backup antigo para dentro do Jenkins
21 COPY --chown=jenkins:jenkins config_jenkins /var/jenkins_home Trecho de código 6. Configuração do Dockerfile da imagem do Jenkins.
O Trecho de código 6 apresenta um Dockerfile que configura a imagem do Jenkins que será utilizada no processo de implantação automática. Na linha 2 é declarada a importação de uma imagem com configurações iniciais do
Jenkins. Nas linhas 6 e 7 estão detalhados os passos necessários para a
instalação do Java 8 e criação de uma pasta que servirá como backup da imagem, respectivamente. Nas linhas 12 e 13, ocorre a remoção das páginas iniciais de configurações do Jenkins, desnecessários ao projeto. As linhas 15 e 17 ilustram o processo de instalação de alguns plugins necessários (como foi explicado na seção 2.2 JENKINS). Na linha 19, a variável de ambiente Java é configurada para habilitar o uso do Java 8. Por fim, na linha 21, o Docker verifica
a existência de uma pasta com as configurações de backup, caso exista ele realiza a cópia de tais configurações para dentro imagem.
Posteriormente, observando a estrutura necessária para executar a aplicação do SIGUAN, houve a necessidade de especificar uma imagem customizada do servidor Tomcat. O Trecho de código 7 relata as especificações para atender o servidor Tomcat configurado.
1 #Utilização da imagem do tomcat fornecida no Docker hub 2 FROM tomcat:8.5.39
3 #Define o diretório de trabalho 4 WORKDIR ${CATALINA_HOME}
5 #Copia os arquivos para dentro da imagem
6 COPY manager.xml conf/Catalina/localhost/manager.xml 7 COPY tomcat-users.xml conf/tomcat-users.xml
8 COPY context.xml conf/context.xml 9 COPY server.xml conf/server.xml 10 COPY web.xml conf/web.xml
Trecho de código 7. Configuração do Dockerfile da imagem do Tomcat.
O Trecho de código 7 apresenta um Dockerrfile de configuração do
Tomcat, na linha 2 a imagem do Tomcat disponibilizada no Docker Hub é
importada. Na linha 4 é definido que o diretório de trabalho do servidor é o diretório do padrão do Tomcat. Nas linhas seguintes são executados comandos para realizar cópias dos arquivos de configuração do Tomcat. O detalhamento desses arquivos está disponível na seção de Apêndice B.
Para imagem do MySQL foi especificado nenhum Dockerfile, pois não houve necessidade de realizar configurações personalizadas já que a imagem do MySQL disponível no Docker Hub apresenta todas as configurações necessárias ao SIGUAN.
Para que o ambiente de produção e o ambiente de testes sejam executados utilizando as imagens que foram especificadas no Trecho de código 6 e Trecho de código 7 é necessária a utilização do docker-compose conforme explicado na seção 2.1 DOCKER. Sendo assim, foram especificados dois arquivos docker-compose, um para ambiente de produção (Trecho de código
8) e outro para ambiente de testes (Trecho de código 9).
2 version: "3" 3 services:
4 #imagem personalizada do tomcat 5 tomcat: 6 image: fbio15/tomcat:0.1 7 ports: 8 - "8280:8080" 9 links: 10 - db
11 #imagem padrão do mysql 12 db: 13 image: mysql:5.7 14 command: --lower_case_table_names=1 15 environment: 16 MYSQL_ROOT_PASSWORD: tomcat 17 MYSQL_DATABASE: siguan 18 MYSQL_USER: tomcat 19 MYSQL_PASSWORD: tomcat 20 volumes: 21 - ./var/lib/dbteste
Trecho de código 8. Configuração do docker-compose do ambiente de produção.
O Trecho de código 8 apresenta a configuração do ambiente de produção do SIGUAN. A linha 2 declara a versão utilizada do docker-compose. A partir da linha 3 são descritos os serviços que estarão contidos dentro do
container. Este container utiliza para configuração de seus serviços duas
imagens, elas são: a imagem do Tomcat, configurada no Trecho de código 7, e a imagem do MySQL, padrão do Docker Hub. Da linha 5 até a 10 é feita a configuração do serviço da imagem do Tomcat. Da linha 12 até 21 é feita a configuração do serviço da imagem do MySQL, como por exemplo a configuração do uso de letras minúsculas para as tabelas como apresentado na linha 14. Para que a comunicação entre o Tomcat e o MySQL aconteça, é necessário que ocorra uma configuração dentro do container, como ilustrado na linha 9 e 10.
1 #ambiente-teste 2 version: "3" 3 services:
4 #imagem personalizada do Jenkins 5 jenkins:
6 image: fbio15/jenkinstcc:0.1 7 ports:
9 - "50000:50000"
10 #imagem personalizada do tomcat 11 tomcat: 12 image: fbio15/tomcat:0.1 13 ports: 14 - "8380:8080" 15 links: 16 - db
17 #imagem padrão do mysql 18 db: 19 image: mysql:5.7 20 command: --lower_case_table_names=1 21 environment: 22 MYSQL_ROOT_PASSWORD: tomcat 23 MYSQL_DATABASE: siguan 24 MYSQL_USER: tomcat 25 MYSQL_PASSWORD: tomcat 26 volumes: 27 - ./var/lib/dbprod
Trecho de código 9. Configuração do docker-compose-test do ambiente de teste
O Trecho de código 9 apresenta a configuração do ambiente de testes do SIGUAN. Este container utiliza para configuração de seus serviços três imagens disponibilizadas no Docker Hub, elas são: a imagem do Jenkins, configurada no Trecho de código 6; a imagem do Tomcat, configurada no Trecho de código 7, e a imagem do MySQL, padrão do Docker Hub.
Da linha 5 até a 9 é feita a configuração do serviço da imagem do Jenkins. Da linha 11 até a 16 é feita configuração do serviço do Tomcat. E, por fim, da linha 18 até a 26 é feita a configuração do serviço do MySQL. Dentre as configurações feitas em sobre a versão do docker-compose e a comunicação entre a imagem do Tomcat e MySQL, seguem o mesmo exemplo do Trecho de
código 8.
Sendo assim, para que sejas executados tais arquivos do Trecho de
código 8 e do Trecho de código 9 é necessário a instalação do Docker. Após
sua instalação é necessário executar o comando “docker-compose up” no diretório do arquivo do Trecho de código 8 e do Trecho de código 9, e assim o Docker inicializará os ambientes de produção e de teste.
3.4 CONFIGURAÇÃO DO JENKINS
necessário a configuração da ferramenta do Jenkins instalada dentro do ambiente de testes. Tal ferramenta é acessada através do Docker, como configurada no Trecho de código 9.
Os jobs podem ser tratados como compiladores do código-fonte, neles podem ser executados testes, atualização de arquivos nos repositórios ou até mesmo disponibilização uma nova versão em um servidor web. Sendo assim, é necessário a configuração de dois Jobs, uma para ambiente de produção e outro para ambiente de testes. Para que tal configuração seja iniciada é necessário criar um job. A Figura 11 apresenta um exemplo de criação de um job para o ambiente de testes.
Figura 11: Criação de um job no Jenkins.
No job criado para o ambiente de testes é necessário realizar a configuração da integração com a plataforma Github para ter o acesso ao código-fonte no repositório. Para tal configuração é necessário a URL do repositório juntamente como as credenciais do Github. A Figura 12 ilustra como é feita tal comunicação ao Github.
Figura 12: Configuração da comunicação ao repositório do Github.
Logo em seguida, é necessário configurar a compilação do sistema. Através da seção Build (Dentro do Jenkins), é possível configurar como será executado a compilação do sistema. Para atender o propósito do ambiente de testes conforme citado na seção 3.2 NECESSIDADE DE CRIAÇÃO DE UM MÓDULO DE TESTES, foi feita a configuração atendendo todo execução do sistema juntamente com os testes de software criados, e ao final seja gerado o arquivo compilado com todo o código-fonte A Figura 13 ilustra como foi feita a configuração da construção do arquivo com código-fonte compilado.
Em seguida, para que o arquivo gerado, após a execução do build do job, seja colocado no servidor Tomcat, é necessário configurar o deploy automático. Tal servidor será utilizado apenas para a execução de testes automatizados conforme explicado na seção 3.3 CONFIGURAÇÃO DO AMBIENTE DE PRODUÇÃO E TESTE UTILIZANDO DOCKER. Para que seja executado o deploy, é necessário identificar o arquivo que deseja ser inserido no servidor, a URL e as credenciais de acesso do servidor de testes. A Figura 14 apresenta a configuração feita no Jenkins que servirá para o deploy do SIGUAN no servidor de testes.
Figura 14: Configuração do deploy do SIGUAN ao servidor de testes.
Após a configuração do job do ambiente de testes é necessária a criação de um job para o ambiente de produção. O ambiente de produção será utilizado para que os usuários tenham acesso a aplicação do SIGUAN. Inicialmente, esse
job segue o mesmo passo de comunicação com o repositório na web (Github)
conforme a Figura 12.
Posteriormente, deve-se configurar um gatilho para que o job do ambiente de produção seja executado após a finalização do job do ambiente de testes.
Esse gatilho só será disparado caso job de teste seja finalizado com sucesso. A
Figura 15 ilustra como foi realizada a configuração desse gatilho.
Figura 15: Configuração do gatilho de execução do job do ambiente de produção.
Caso a execução do job do ambiente de testes seja concluída corretamente, automaticamente será executada o job do ambiente de produção, mas sem a execução dos testes de software, visto que tais testes afetam a massa do banco de dados de produção. Sendo assim, para que os testes de
software não sejam executados, foi configurado para que a execução do build
seja ignorado os testes, e ao final seja gerado o arquivo compilado com todo o código-fonte. A Figura 16 demonstra como será compilado o projeto pulando a execução dos testes de software.
Por fim, para que seja implantado ao servidor de produção é necessário configurar o deploy para que as modificações sejam entregues ao cliente. Para que seja executado o deploy, é necessário identificar o arquivo que deseja ser inserido no servidor, a URL e as credenciais de acesso do servidor de produção. A Figura 17 apresenta a configuração do deploy no servidor de produção.
Figura 17: Configuração do deploy do SIGUAN ao servidor de produção.
3.5 NOVO FLUXO DE IMPLANTAÇÃO
Com criação do Módulo de Testes e a configuração do ambiente de produção e de testes juntamente com a configuração do Jenkins, foi proposto um novo processo de implantação. Tal processo tem como finalidade aumentar da velocidade de feedback do usuário, devido ao uso de um processo automatizado. A Figura 18 ilustra o novo processo de implantação.
Figura 18: Novo processo de inserção do SIGUAN ao servidor.
Visto que todo este trabalho tem foco na implantação de um sistema pragmático, com intuito de facilitar a manutenção e evolução do código, foi adotada a prática de revisão de código como explicado no item 2.3.1 REVISÃO DE CÓDIGO. Para isso, foi feito a configuração (Figura 19) no repositório para que um código enviado só seja aceito após a realização da revisão. A princípio, fica em aberto a técnica de revisão a ser adotada pelos desenvolvedores.
Figura 19. Configuração da prática de revisão de código
Sendo assim, neste novo processo, primeiramente, o desenvolvedor após realizar alterações no código-fonte e enviar para o repositório na web, terá o seu código revisado por outro desenvolvedor. Após a conclusão da revisão, se aceita no repositório de produção, a plataforma configurada do Jenkins, que está sendo gerenciada pelo Docker, será capaz de detectar que houve uma modificação no repositório e executará todo o processo de implantação ao servidor web (Tomcat). A Figura 20 ilustra como foi configurado no Jenkins o processo para builds automáticos e a Figura 21 ilustra como foi configurado no Github este
processo. Após a finalização do job no Jenkins, o sistema estará disponível para o cliente ter acesso as novas funcionalidades criadas.
Figura 20. Configuração de build automático no Jenkins.
4. AVALIAÇÃO
Este Capítulo descreve o desenvolvimento de um novo incremento para SIGUAN, ou seja, um novo módulo, chamado de Análise de Clientela. O objetivo desse módulo é auxiliar o nutricionista na preparação de um novo cardápio a partir da captação de informações sobre necessidade calórica da clientela do Restaurante Universitário. Assim como o SIGUAN este módulo foi desenvolvido utilizando com base no modelo arquitetural de Visões 4+1. Tal avaliação ocorre devido a necessidade de comprovar que o novo fluxo de processo de implantação explicado na Seção 3.5 NOVO FLUXO DE IMPLANTAÇÃO, é adequado e suficiente para atingir o objetivo principal desse trabalho.
O Capítulo 4 está organizado da seguinte forma: a seção 4.1 apresenta os requisitos para atender o novo módulo; a seção 4.2 ilustra como foi implementada tal modulo seguindo o modelo arquitetural 4+1; a seção 4.3 apresenta o processo de implantação do SIGUAN na ferramenta do Jenkins e demonstra o novo módulo do SIGUAN.
4.1 PROBLEMA
A necessidade de criar tal módulo veio da problemática de que, para o nutricionista, é necessário ter uma base da média calórica necessária para a clientela que será atendida em um determinado dia. Dessa forma, para facilitar tal previsão, é necessário adicionar ao sistema um módulo para cadastro das informações relevantes da clientela para que a média calórica da refeição possa ser estimada durante a preparação dos cardápios. A Tabela 3 apresenta tais requisitos funcionais do novo módulo.
Tabela 3. Requisitos Funcionais
Código Descrição
RF001 Cadastro, exclusão, atualização e consulta de análise de clientela.
RF002 Cadastro, exclusão, atualização e consulta de clientela.
RF003 Consulta de uma análise de clientela durante o processo de cadastro de prescrição.
4.2 ARQUITETURA
Como citado anteriormente, o SIGUAN desenvolvido com base no modelo arquitetural 4+1. Os detalhes da arquitetura do SIGUAN podem ser encontrados no trabalho de (SILVA, 2018). Assim, serão apresentados nessa seção apenas a parte específica necessária para o desenvolvimento do novo módulo.
4.2.1 VISÃO DE CASOS DE USO
A visão de casos de uso ilustra como estão organizados os requisitos funcionais do Módulo de Análise de clientela. Tais requisitos foram obtidos através de reuniões com os usuários do sistema. A Figura 22 apresenta o diagrama de casos de uso que ilustra as principais funcionalidades oferecidas por esse novo módulo e o modo como os atores interagem com as mesmas.
Figura 22: Diagrama de Casos de uso do Módulo de Análise de Clientela
O detalhamento dos casos de uso está disponível na seção de Apêndice
4.2.1.2 VISÃO LÓGICA
A Visão Lógica apresenta a especificação do modelo de regras de negócios que implementam os requisitos funcionas do sistema. Esta visão foi representada através do diagrama de classes com intuito de especificar todos os dados e relacionamentos necessários. A Figura 23 mostra o diagrama de classes do módulo de Análise de Clientela.
Figura 23: Visão do Diagrama de Classe do Módulo de Clientela
A Tabela 4 apresenta as descrições das classes especificando o que cada uma representa.
Tabela 4. Especificação das classes do diagrama de classe
Classe Descrição
Prescrição
Classe que representa uma prescrição, onde é especificado a quantidade necessária dos insumos para preparar as refeições de um dia específico. Possui atributos que indicam o cardápio aplicado, a data, o responsável e a lista de itens que serão retirados do estoque especificando suas respectivas quantidades
Análise Clientela
Classe que utilizasse uma equação que será escolhida pelo ator Nutricionista onde será calculada a partir de uma análise de clientela a média de todos os atributos que um comensal poderá apresentar.
Comensal
Classe que representa as variáveis desejáveis que um ser humano que visite a UAN apresente.
4.2.1.3 VISÃO DE IMPLEMENTAÇÃO
A visão de implementação se baseia no ponto de visto do desenvolvedor no aspecto de como o sistema será implementado. Tal visão não foi alterada, seguindo a mesmo do trabalho de (SILVA, 2018). A Figura 24 apresenta a organização desta visão.
Figura 24. Arquitetura do novo módulo como base no SIGUAN. FONTE: (SILVA, 2018).