PJe2:Documento da Arquitetura de Referência
Conteúdo
|
Introdução
Apresentamos neste documento a arquitetura de referência para o desenvolvimento do software Processo Judicial Eletrônico versão 2.0 (PJe 2.0) e suas evoluções futuras. As seções e subseções do documento explicarão os detalhes pertinentes da arquitetura.
Objetivo do documento
O objetivo principal é especificar a arquitetura de software de referência a ser utilizada como padrão para o desenvolvimento do PJe 2.0 e suas evoluções futuras. Nesta especificação está incluído: a estruturação do projeto do software, a organização das camadas do software, os componentes e arcabouços utilizados no software, a definição das principais tecnologias e ferramentas a serem utilizadas, os padrões de projeto, boas práticas de programação que devem ser utilizadas no desenvolvimento do software, entre outros assuntos relevantes.
Recomendamos que a leitura deste documento seja feita na ordem sequencial em que são apresentados os tópicos do sumário/índice do documento.
A metodologia de desenvolvimento do software definida será tratada em outro documento.
Público Alvo
TODO: esclarecer os perfis principais das pessoas que este documento visa atender.
Termos, abreviações e convenções adotadas
Apresentamos nesta seção uma tabela contendo os termos, abreviações e convenções adotadas no documento da arquitetura de referência do PJe 2.0. A leitura prévia desta seção é fortemente recomendada para compreensão das demais seções.
Termo | Descrição |
Apache Maven | É um software capaz de gerenciar componentes de software e as dependências entres esses componentes, de prover a integração contínua desses componentes, de gerenciar a construção do projeto do software e de documentar e reportar informações inerentes à essa construção. |
API | Acrônimo para a expressão inglesa Application Programming Interface ou interface de programação de aplicativos; essa interface é composta por um conjunto de rotinas, protocolos, padrões de programação e ferramentas que permitem a construção de aplicativos de software. |
Applet | Applet é um software aplicativo que é executado no contexto de outro programa. |
Batch | Termo usado para expressar processamento de dados que ocorre através de um lote (batch) de tarefas enfileiradas, de modo que o software responsável por esse processamento somente processa a próxima tarefa após o término completo da tarefa anterior. |
Browser | Navegador web. Ex.: Firefox, Internet Explorer. |
Build | Termo do inglês que significa 'construir', isto é, é o ato de realizar a compilação de todos os componentes de um ou mais projetos de software envolvidos cujo intuito é deixar pronta a aplicação de software para ser instalada em um ambiente real, por exemplo, em um servidor de aplicações. |
Cache | É um dispositivo de acesso rápido, interno a um sistema, que serve de intermediário entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador concede autorização. |
CRUD | Sigla para Create (Criar), Read (Ler), Update (Atualizar) e Delete (Remover): são operações básicas utilizadas em um software que gerencia bancos de dados. |
CSS | Acrônimo para a expressão inglesa Cascading Style Sheets; é uma linguagem de folhas de estilo utilizada para definir a apresentação de documentos escritos em uma linguagem de marcação, como HTML ou XML. |
DAO | Acrônimo para a expressão inglesa Data Access Object; é um padrão para persistência de dados que permite separar regras de negócio das regras de acesso ao SGBD. |
DBA | Database Administrator ou administrador de bancos de dados. |
Deploy | Instalar/implantar uma aplicação de software em um servidor de aplicações. |
DHTML | Dynamic HTML, ou DHTML, é a união das tecnologias HTML, Javascript e uma linguagem de apresentação. |
DOM | Document Object Model ou Modelo de Objetos de Documentos é uma especificação da W3C, independente de plataforma e linguagem, onde se pode dinamicamente alterar e editar a estrutura, conteúdo e estilo de um documento eletrônico. |
EJB | Enterprise Java Bean. É um componente do tipo servidor da plataforma Java EE que executa no container do servidor de aplicação. |
HTML | Acrônimo para a expressão inglesa HyperText Markup Language (ou linguagem de marcação de hipertexto); essa linguagem de marcação é utilizada para produzir páginas para web. |
HTTP | Acrônimo para a expressão inglesa Hypertext Transfer Protocol (ou protocolo de transferência de hipertexto); é um protocolo de comunicação entre sistemas de informação o qual permite a transferência de dados entre redes de computadores, principalmente na web. |
IDE | Integrated Development Environment ou ambiente integrado para desenvolvimento de software. |
Java | Linguagem de programação orientada a objetos. |
Java EE | Plataforma de desenvolvimento Java voltada para ambientes corporativos/empresariais; também chamada de Java Enterprise Edition (JEE). |
Javascript | Linguagem de programação para navegadores web; é baseada em scripts, orientada a objetos e com sintaxe similar à linguagem de programação C. |
Login | Ato de fornecer credenciais a um determinado sistema, de modo a acessar suas funcionalidades. |
MVC | Model-View-Controller é um padrão de arquitetura de software que visa isolar a lógica (Model) do negócio da apresentação da tela (View) e do controle de navegação (Controller) da tela. |
Query | É a operação de consulta realizada em um SGBD. |
Servidor de aplicação | Software responsável por disponibilizar e gerenciar um ambiente para a instalação e execução de certas aplicações de software, centralizando e dispensando a instalação nos computadores dos usuários clientes dessas aplicações. Ex.: Jboss, Tomcat, entre outros. |
Sessão HTTP | Sessão HTTP provém um modo de armazenar, no servidor de aplicação web, dados importantes relativos a um determinado usuário de uma aplicação. |
RAD | Rapid application development (RAD), também conhecido como desenvolvimento rápido de aplicação; é um modelo de processo de desenvolvimento de software iterativo e incremental que enfatiza um ciclo de desenvolvimento extremamente curto. |
SCRUM | É uma metodologia ágil para planejamento e gestão de projetos de software. |
SGBD | Sistema gerenciador de bancos de dados. Ex.: Oracle, PostgreSQL, entre outros. |
SQL | Structured Query Language ou linguagem de consulta estruturada; é a linguagem de declarativa padrão para bancos de dados relacionais. |
SOA | Service Oriented Architecture ou arquitetura orientada a serviços; é um estilo de arquitetura de software cujo princípio fundamental preconiza que as funcionalidades implementadas pelas aplicações devem ser disponibilizadas na forma de serviços. |
Sprint | Um sprint é a unidade básica de desenvolvimento em conforme a metodologia ágil SCRUM. |
Stored procedure | Procedimento armazenado ou stored procedure é uma coleção de comandos da linguagem SQL para gerenciamento de bancos de dados. |
SUN | Empresa criadora da plataforma Java. |
WAP | Sigla para Wireless Application Protocol ou protocolo para aplicações sem fio. |
Webservice | De acordo com a W3C, webservice é um sistema de software responsável por proporcionar a interação entre duas máquinas através de uma rede de computadores. |
XHTML | Acrônimo para a expressão inglesa eXtensible Hypertext Markup Language; é uma reformulação da linguagem de marcação HTML, baseada em XML. Combina as tags de marcação da linguagem HTML com regras da linguagem XML. |
XML | eXtensible Markup Language é uma linguagem de marcação, recomendada pela W3C, que define um conjunto de regras para a codificação de documentos. |
XSLT | XSL Transformations é uma linguagem de marcação XML usada para transformar documentos XML em outros documentos XML ou em outros formatos. |
W3C | World Wide Web Consortium é um consórcio de empresas de tecnologia que desenvolve padrões para a criação e a interpretação dos conteúdos para web. |
Restrições da arquitetura
TODO: verificar se existem restrições impostas que foram obedecidas e incluí-las nesta seção.
Justificativas arquiteturais
Nesta seção, explicitamos o conjunto de memorandos (técnicos, gerenciais, institucionais) que justificam as decisões arquiteturais da arquitetura de referência do PJe 2.0. Esses memorandos são resumos das discussões e estudos os quais balizam este trabalho.
- Requisitos do projeto PJe 2.0.
- O conjunto completo de premissas e requisitos (funcionais e não funcionais) consta no Plano Geral do Projeto PJe 2.0 ( [TODO: colocar link para o plano, se for desejado]). A saber, explicitamos apenas um resumo desse conjunto:
- Isolamento dos módulos de negócio (ou seja, módulos responsáveis pela lógica de negócio do software PJe) a fim de evitar efeitos colaterais indesejáveis provenientes das modificações no código-fonte.
- Permitir que o desenvolvimento dos módulos de negócio seja realizado isoladamente, inclusive com equipes distribuídas.
- Permitir que a implementação de um módulo de negócio qualquer seja totalmente substituída por nova implementação, sem prejudicar o funcionamento dos demais módulos.
- Isolamento das camadas lógicas do software, para evitar ao máximo o embaralhamento da lógica de negócio do software PJe e a dificuldade de leitura e compreensão do código-fonte
- Permitir que os módulos mais exigentes, quanto ao consumo de recursos de infraestrutura, possam ser "instalados" (deploy) mais de uma vez.
- Experiências prévias.
- Foram consideradas as seguintes experiências:
- Experiência prévia da equipe de arquitetos servidores do Poder Judiciário. Alguns dos arquitetos com experiência no software PJe 1.0.
- Foram analisadas arquiteturas de referência das seguintes instituições: TCU, STF, SERPRO, TJRO e TJPE.
- Estudos diversos foram realizados pela equipe de arquitetos na primeira Sprint do projeto.
- Tecnologias adotadas.
- As tecnologias e/ou ferramentas adotadas para a implementação foram selecionadas a partir da análise dos requisitos do projeto PJe 2.0:
- Java Enterprise Edition Platform specification (JEE): a escolha pela plataforma JEE foi um consenso dada a notória posição de destaque dessa plataforma na construção de aplicações corporativas com grande volume de acesso e necessidade de escalabilidade, de robustez, de segurança, de controle de transação e de processamento em batch, entre outras necessidades. Além disso, a plataforma JEE traz um conjunto expressivo de APIs que aumentam a produtividade da construção do software, encapsulam parte da complexidade inerente às funções que as APIs implementam, promovem a definição de padrões de desenvolvimento, contemplando independência de servidor de aplicações.
- Apache Maven: a escolha pela ferramenta Maven foi norteada pela necessidade de modularização do software e pela adoção da plataforma JEE, como também pelo consenso, na comunidade de desenvolvedores Java, de que a ferramenta Maven é a melhor ferramenta para gerenciamento de builds e dependências na atualidade.
- Git: a escolha pela ferramenta Git (um software de controle de versões de código-fonte) se deu pela complexidade do ambiente de desenvolvimento do software PJe no qual é desejável que várias equipes, em diferentes localidades (Tribunais de Justiça), estejam trabalhando, paralelamente, no desenvolvimento de diferentes módulos do software PJe e, também, na manutenção dos módulos já implementados.
- JBoss Enterprise Application Platform (JBoss EAP): a escolha pelo servidor de aplicações Red Hat JBoss é justificada pela reconhecida posição de destaque, entre a comunidade de desenvolvedores JEE, deste servidor de aplicação que oferece a completa implementação das APIs da plataforma JEE. Além disso, a versão do JBoss denominada EAP (Enterprise Application Platform), em particular, foi a escolhida porque permite a contratação do serviço de suporte da empresa Red Hat. É importante destacar que, o uso do servidor de aplicações JBoss é adotado como o servidor de aplicação padrão do projeto e, para o uso de outro servidor de aplicação diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas.
- PostgreSQL: a escolha do SGBD PostgreSQL deve-se pelo fato deste SGBD ser de uso gratuito e open source (ou seja, é um software cujo código-fonte está aberto para comunidade), implementar o padrão objeto-relacional com a robustez desejada pelo projeto. Além de, ser um SGBD amplamente utilizado pela comunidade de desenvolvedores de diversas linguagens de programação. É importante destacar que, o uso do SGBD PostgreSQL é adotado como o SGBD padrão do projeto e, para o uso de outro SGBD diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas.
Definição da arquitetura de referência
Nesta seção descrevemos a arquitetura de referência definida para o desenvolvimento do software PJe 2.0 e suas evoluções futuras. A sigla batizada para arquitetura de referência é ArqJus. Dentre os assuntos que serão tratados, podemos destacar: a forma como a arquitetura foi estruturada/organizada e as responsabilidades da arquitetura. É importante informarmos que, ArqJus também poderá ser reutilizada para outros projetos cujo domínio do negócio seja diferente do PJe.
ArqJus é formada por 5 "camadas" lógicas relacionadas entre si e, além das camadas, é possível agruparmos logicamente elementos da arquitetura por meio de "módulos". Vejamos o significado desses dois conceitos importantes:
- Camada: representa uma associação abstrata de elementos que atendem a um conjunto bem definido de responsabilidades dentro do contexto do software.
- Módulo: são blocos de implementação (código-fonte, arquivos de configuração, arquivos de propriedades, arquivos de templates (ou modelos) de janelas gráficas, scripts de banco de dados, etc.) responsáveis por um ou mais serviços ofertados pelo software. Um módulo é classificado por um dos seguintes tipos assim definidos:
- Tipo 1: é um módulo que representa abstrações do modelo de negócio inerente ao software, em outras palavras, um módulo do tipo 1 agrupa classes Java que representam conceitos do domínio do negócio. Também o chamaremos de módulo de negócio. Um módulo do tipo 1 não pode conhecer um outro módulo do tipo 1, caso contrário, será violado a independência entre esses módulos. Todo módulo tipo 1 deve ter: uma única interface Java, local e/ou remota e a classe Java que implementa os serviços ofertados por essa interface.
- Tipo 2: é um módulo que representa abstrações da própria ArqJus, em outras palavras, um módulo do tipo 2 agrupa classes Java e um conjunto de arquivos que fazem parte da arquitetura. Exemplo desse conjunto de arquivos: XHTML, CSS, Javascript, HTML, XML, etc. Um módulo do tipo 2 pode conhecer um outro módulo do tipo 2.
Concretamente, cada módulo tornar-se-á um projeto específico gerenciado pelo aplicativo Maven. Dessa forma, garantiremos o isolamento dos módulos do software. Além de ser gerenciado pelo Maven, cada módulo é construído separadamente, com repositório próprio no aplicativo Git e com versionamento exclusivo, permitindo o isolamento do código-fonte e a especialização das equipes de desenvolvimento, contribuindo com o objetivo de facilitar a manutenção do software e minimizar os impactos de efeitos colaterais das diversas manutenções do software.
Explicaremos nas próximas subseções mais detalhes da ArqJus por meio de visões gráficas arquiteturais.
Visão geral das camadas da arquitetura
A primeira visão da ArqJus é exibida na Figura 1 e a denominamos de Visão Geral das Camadas da Arquitetura.
Figura 1. Visão Geral das Camadas da Arquitetura.
TODO: Deve-se explicar 'qual camada conhece qual camada' na Figura 1
Conforme pode ser visto na Figura 1, há 5 camadas lógicas e a definição de cada uma dessas camadas é apresentada seguir:
- Camada de Apresentação: encapsula toda a lógica de interação com usuários, desde a exibição de informações, passando pela captura de dados informados pelos usuários por meio das janelas gráficas do software, até o reconhecimento de ações realizadas nessas janelas gráficas.
- Camada de APIs: encapsula o acesso aos módulos ofertados pelo software. Normalmente, nesta camada terão módulos do tipo 2.
- Camada de Negócio: encapsula toda a lógica do domínio de negócio do software, ou seja, as regras de manipulação dos dados e informações controlados pelo software.
- Camada de Domínio: encapsula as representações dos dados e informações inerentes ao domínio de negócio do software, em outras palavras, esta camada é responsável pela realização do mapeamento objeto-relacional.
- Camada de Serviços: encapsula toda a lógica de acesso ao software, servindo como porta de entrada de requisições dos diversos clientes do software, por exemplo: requisições de usuários por meio de janelas gráficas; requisições de outros softwares por meio de webservices.
TODO: citar as tecnologias adotadas na ArqJus predominantes em cada uma das camadas
Visão modular da arquitetura
A segunda visão da ArqJus é exibida na Figura 2 e a denominamos de Visão Modular da Arquitetura.
Figura 2. Visão Modular da Arquitetura.
Na Figura 2 apresentamos uma visão da ArqJus contemplando os conceitos já explicados: camadas e módulos. Nessa visão também demonstramos um exemplo de uso da arquitetura. Observando a Figura 2 no sentido 'de cima para baixo', explicaremos, a seguir, a estrutura da ArqJus:
- Um módulo tipo 2 que denominamos de Módulo WEB. Esse módulo no aplicativo Maven é denominado pje-web. Nesse módulo inclui-se:
- Uma pasta denominada recursos que contém um conjunto de arquivos. Exemplos desses arquivos: XHTML, CSS, Javascript, imagens, entre outros.
- Um pacote denominado controlador que contém classes Java que realizam o trabalho definido pela Camada de Apresentação do software. Somente as classes desse pacote têm acesso ao conjunto de arquivos da pasta recursos. Também poderemos chamá-las de classes controladoras (ou backbeans). Essas classes também têm acesso às interfaces Java do Módulo Orquestrador. Também podem ter acesso às interfaces Java de módulos do tipo 1 (módulo de negócio) que existirem no software, por exemplo: na Figura 2, a classe Java 'MinhaEntidadeAOperacaoCtrl' acessa o módulo 'Meu negócio A' por meio de sua interface Java.
- Um módulo tipo 2 que denominamos de Módulo Orquestrador. Esse módulo no aplicativo Maven é denominado pje-service. Nesse módulo inclui-se:
- Um pacote denominado api que contém interfaces Java que representam o trabalho definido pela Camada de APIs do software.
- Um pacote denominado impl que contém classes Java que implementam o trabalho definido pela Camada de Serviços do software. Em outras palavras, uma classe Java do pacote impl implementa os serviços ofertados por uma interface Java do pacote api correspondente.
Uma classe do pacote impl não, necessariamente, implementa por completo um determinado serviço o qual ela é responsável. Logo, é possível que essa classe obtenha o resultado de 'partes desse serviço' por meio de um outro módulo da ArqJus. Um exemplo: na Figura 2 temos um ou mais serviços da classe 'MeuServicoSrv' fazendo uso de serviços disponíveis nas interfaces Java 'IMeuNegocioASrv' do módulo 'Meu negócio A' e 'IMeuNegocioBSrv' do módulo 'Meu negócio B'.
- 'Meu Negócio A' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se:
- Uma interface Java denominada 'IMeuNegocioASrv'; essa interface representa o trabalho definido pela Camada de APIs do módulo 'Meu Negócio A'.
- Uma classe Java denominada 'MeuNegocioASrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio A'. Em outras palavras, a classe 'MeuNegocioASrv' implementa os serviços ofertados pela interface Java 'IMeuNegocioASrv'.
- Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio A'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeAManager' e 'MinhaEntidadeCManager' e as suas classes DAO correspondentes.
- 'Meu Negócio B' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se:
- Uma interface Java denominada 'IMeuNegocioBSrv'; essa interface representa o trabalho definido pela Camada de APIs do módulo 'Meu Negócio B'.
- Uma classe Java denominada 'MeuNegocioBSrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio B'. Em outras palavras, a classe 'MeuNegocioBSrv' implementa os serviços ofertados pela interface Java 'IMeuNegocioBSrv'.
- Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio B'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeBManager' e sua classe DAO correspondente.
- Um módulo tipo 2 que denominamos de Módulo Modelo. Esse módulo no aplicativo Maven é denominado pje-modelo. Nesse módulo inclui-se:
- Um pacote denominado modelo que contém classes Java que realizam o trabalho definido pela Camada de Domínio do software. Por exemplo: na Figura 2 temos as classes 'MinhaEntidadeA', 'MinhaEntidadeB' e 'MinhaEntidadeC'. Todos os módulos do software (tanto módulo do tipo quanto do tipo 2) têm acesso às classes do pacote modelo.
É importante destacar que:
- O módulo de negócio 'Meu Negócio A' não conhece o módulo de negócio 'Meu Negócio B', logo, está consistente com a definição de módulo tipo 1.
- Uma classe Java pertencente à Camada de Negócio pode acessar uma outra classe da Camada de Negócio desde que, ambas classes, pertençam ao mesmo módulo de negócio.
- Classes Java da Camada de Negócio podem ser acessadas por classes Java da Camada de Serviços somente dentro de um mesmo módulo de negócio.
Organização dos projetos no Maven
Nesta subseção, apresentamos a organização dos projetos no aplicativo Maven, consolidando os módulos citados no decorrer da explicação da Figura 2 e outros módulos necessários para estruturação da ArqJus.
- pje-pom: projeto que contém as dependências que são comuns entre todos os demais projetos. Não deve conter código-fonte, apenas as configurações dessas dependências. O aplicativo Maven exige a presença do arquivo POM (Project Object Model).
- pje-modelo: projeto que contém todas as entidades de domínio do negócio mapeadas de acordo com o padrão JPA (Java Persistence API).
- pje-comum: projeto que contém todas as classes Java utilitárias do software. Também é classificado como um módulo tipo 2. Exemplos de classes Java desse projeto: classes que implementam os registros de auditoria das operações do software (também chamado de registro de log), classes que implementam o controle de acesso, o tratamento de exceções, entre outras classes responsáveis pela infraestrutura do software.
- pje-service: projeto que contém as classes do Módulo Orquestrador das funcionalidades que envolvam mais de um módulo de negócio.
- pje-web: projeto que contém todo o código-fonte associado à Camada de Apresentação, exemplos: classes controladoras (também conhecidas por back-beans), arquivos HTML, XHTML, CSS e scripts JavaScript.
A nomenclatura de cada projeto específico no aplicativo Maven obedece o padrão pje<modulo>, em 'modulo' deve conter o nome do módulo correspondente.
Os projetos no Maven serão empacotados em arquivos com extensão jar (Java ARchive), com exceção do projeto "pje-web", que será empacotado em um arquivo com extensão war (Web application ARchive).
Para cada módulo do software, independente do tipo do módulo, será preciso criar três arquivos com extensão jar, vejamos:
- pje-modulo-X.Y.Z.jar: este arquivo contém todas as classes Java do módulo e será utilizado no momento da instalação (deploy) do módulo.
- pje-modulo-X.Y.Z-api.jar: este arquivo contém apenas as interfaces Java do respectivo módulo e será utilizado como dependência na implementação dos módulos "pje-web" e "pje-service". Lembrando que, os módulos "pje-web" e "pje-service" somente terão acesso à Camada de APIs do módulo em questão.
- pje-modulo-X.Y.Z-sources.jar: este arquivo contém o código-fonte do módulo e será utilizado para fins de depuração do código-fonte (ou debug).
Visão de Deployment da Arquitetura
Esta subseção tem o objetivo de apresentar os principais componentes envolvidos no processo de deploy do software.
Figura 3. Visão de Deployment do Software.
A Figura 3 apresenta a visão de implantação padrão do software PJe 2, conforme definido pela arquitetura estabelecida. É possível identificar os principais recursos envolvidos no processo de deploy, desde o servidor de aplicação e o servidor de banco de dados, passando pelo build da aplicação, até alguns arquivos de configuração de maior relevância para o funcionamento do PJe 2.
Para habilitar o acesso remoto ao servidor de banco de dados PostgreSQL é necessário realizar ajustes nas configurações definidas nos arquivos “pg_hba.conf” e “postgresql.conf”. Para identificar a localização física destes arquivos, é possível executar os comandos “show hba_file” e “show config_file”, respectivamente, no console do PostgreSQL. Os ajustes necessários podem ser verificados na documentação on-line do SGBD.
Para criar e configurar os datasources do PJe 2 é necessário manipular os arquivos “module.xml”, “jdbc-postgresql.jar”, "jdbcdslog.jar" e “standalone.xml”, conforme descrito posteriormente neste documento. Já o arquivo “persistence.xml” é utilizado para configurar como o provider JPA irá se conectar aos datasources criados.
Uma vez criados os datasources, é possível realizar o deploy padrão do PJe 2 a partir do arquivo “pje-web.war” disponibilizado pelo CNJ. Este arquivo é composto por todos os módulos do software, empacotados em arquivos .jar conforme já mencionado em sessão anterior deste documento.
Padrões, regras e boas práticas
Esta seção tem o objetivo de apresentar os padrões estabelecidos, as regras definidas e algumas boas práticas de programação para construção do software sob a consonância com os requisitos da ArqJus. As explicações serão divididas nas subseções desta seção.
Padrões de nomenclatura e codificação
- Padrões de nomenclatura para classes Java:
- Classes do Módulo Web (também chamaremos de "controladores/controlador(a)" ou de backbeans): <Entidade><operação>Ctrl.java
- Interfaces Java do Módulo Orquestrador (também chamaremos de "orquestradores/orquestrador(a)"): I<Serviço>Srv.java
- Implementações dos orquestradores: <Serviço>Srv.java
- Interfaces Java dos módulos: I<Módulo>Srv.java
- Implementações dos módulos: <Módulo>Srv.java
- Classes de negócio (também chamaremos de "managers/manager"): <Entidade>Manager.java
- Classes de acesso aos dados: <Entidade>DAO.java
- Entidades: <Entidade>.java
- Padrões de nomenclatura para pacotes Java:
- br.jus.cnj.pje.web.controlador: todos os controladores do software devem pertencer a este pacote.
- br.jus.cnj.pje.service.api: todas as interfaces Java dos orquestradores do software devem pertencer a este pacote.
- br.jus.cnj.pje.service.impl: todas as implementações das interfaces Java dos orquestradores devem pertencer a este pacote.
- br.jus.cnj.pje.<negócio>.api: a interface Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.impl: a implementação da interface Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.manager: todas as classes de negócio (managers) do módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.dao: todas as classes de acesso aos dados inerentes ao módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.modelo: todas as classes das entidades mapeadas no padrão JPA devem pertencer a este pacote.
- Padrões de nomenclatura para arquivos XHTML:
- <entidade><operação>.xhtml: entende-se por <entidade> o nome da principal da entidade manipulada pela janela gráfica (ou tela), e por <operação> a principal manipulação que se deseja realizar a partir desta tela (visualizar, excluir, alterar, desativar, cadastrar, etc).
É importante ressaltar que, os padrões apresentados no decorrer da explicação da Figura 2 também foram considerados.
Além dos padrões definidos nesta subseção, recomendamos a adoção do padrão de codificação Java, disponível no endereço http://www.oracle.com/technetwork/java/codeconvtoc-136057.html.
Regras definidas
Sobre o relacionamento entre classes:
É permitido na ArqJus o relacionamento entre as diversas classes do software distribuídas nos módulos e nas camadas lógicas, logo, esse relacionamento deve obedecer as seguintes regras:
- Um orquestrador deve ser criado sempre que houver a necessidade de uma operação no Módulo Controlador que envolva mais de um módulo de negócio.
- As classes dos controladores apenas terão acesso às interfaces Java dos serviços ofertados pelos orquestradores e módulos de negócio.
- Para cada tela (ou arquivo XHTML) deve haver um controlador específico e único.
- Todas as operações que um módulo de negócio disponibilizará devem ser expostas através de sua Camada de API (ou interface Java).
- Os módulos de negócio não podem, em hipótese alguma, acessar funcionalidades e/ou classes de outros módulos de negócio. Somente poderão acessar classes e funcionalidades disponíveis nos projetos pje-modelo e pje-comum.
- As classes managers de um módulo só podem ser acessadas pela classe que implementa a interface Java desse módulo em questão, ou pelos demais managers do mesmo módulo.
- As regras de negócio devem ser implementadas exclusivamente nas classes managers correspondentes.
- O BaseDAO já oferece um conjunto de métodos implementados para as operações de consulta (com ou sem paginação), inclusão, alteração e exclusão das entidades. Caso sejam necessários métodos de acesso/manipulação de dados específicos para uma entidade, deve ser implementada uma, e apenas uma, classe no padrão DAO que estende o BaseDAO.
- Cada classe DAO só deve ser acessada pela sua classe manager correspondente.
- Validações dos atributos que caracterizam uma entidade (por exemplo: não nulo, não vazio, restrição de tamanho, restrição de valores) devem ser realizadas na própria entidade, por meio das anotações disponíveis na API Bean Validation da especificação JEE.
Utilização da Classe Filter
- Objetivo:
Permitir a construção de queries orientadas a objeto, utilizando a Java Persistence Query Language (JPQL), encapsulando detalhes de implementação, gerando padronização de código-fonte, menor complexidade e, consequentemente, menor esforço para manutenção.
- Principais aplicações:
- Adicionar restrições na cláusula WHERE: =, >, <, LIKE, IS NULL, IN além de várias outras;
- Navegar pelo grafo de objetos sem limite de profundidade;
- Determinar FETCH em qualquer propriedade no grafo de objetos;
- Formar cláusulas WHERE complexas, através dos conjuntivos AND e OR;
- Determinar qual tipo de JOIN será utilizado nos relacionamentos;
- Realizar ordenações;
- Paginar consultas.
- Exemplos de uso:
- Restrições na cláusula WHERE
Código:
- Restrições na cláusula WHERE
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("login", "admin"); filter.addBetween("birthDate", new Date(), new Date()); filter.addLikeIgnoreCase("name", "%José"); filter.addGreaterOrEqualThan("id", 10L);
SQL Gerado:
Select //All properties of User from systemuser user0_ where user0_.login=? and ( user0_.birth_date between ? and ? ) and ( upper(user0_.name) like ? ) and user0_.id>=10
- Navegação no grafo de objetos
Código:
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("profiles.screens.module.name", "Controle de Acesso");
SQL Gerado:
Select //All properties of User from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join accessprofile_screen screens3_ on accessprof2_.id=screens3_.accessprofile inner join Screen screen4_ on screens3_.screen=screen4_.id inner join Module module5_ on screen4_.module=module5_.id where module5_.name=?
- Definição do FETCH nas propriedades
Código:
Filter<User> filter = new Filter<User>(User.class); filter.fetch("profiles"); filter.fetch("blockedFunctionalities");
SQL Gerado:
select //All properties of User, AccessProfile(profiles) and //Functionality(blockedFunctionalities) from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join exceptions_systemuser_functionality blockedfun3_ on user0_.id=blockedfun3_.systemuser inner join Functionality functional4_ on blockedfun3_.functionality=functional4_.id where 1=1
Código:
Filter<Client> filter = new Filter<Client>(Client.class); filter.addEquals("address.streetType.name", "Rua",JoinTypes.INNER,true); //addEquals(attribute, value, joinType, fetch)
SQL Gerado:
select //All properties of User, AccessProfile(profiles) and //Functionality(blockedFunctionalities) from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join exceptions_systemuser_functionality blockedfun3_ on user0_.id=blockedfun3_.systemuser inner join Functionality functional4_ on blockedfun3_.functionality=functional4_.id where 1=1
- Construção de cláusulas WHERE complexas
Código:
Filter<User> filter = new Filter<User>(User.class); ComposedRestriction orExtern = Filter.createOr(); orExtern.addRestriction(Filter.createEquals("active", Boolean.TRUE,null,null)); ComposedRestriction and = Filter.createAnd(); and.addRestriction(Filter.createNotEquals("name", "José",null,null)); and.addRestriction(Filter.createEquals("login", "admin",null,null)); ComposedRestriction orIntern = Filter.createOr(); orIntern.addRestriction(Filter.createBetween("birthDate", new Date(), new Date(),null,null)); orIntern.addRestriction(Filter.createEquals("office", "Arquiteto", null,null)); and.addRestriction(orIntern); orExtern.addRestriction(and); filter.addComposedRestriction(orExtern);
SQL Gerado:
select //All properties of User from systemuser user0_ where user0_.active=? or (user0_.name<>? and user0_.login=? and (user0_.birth_date between ? and ? or user0_.office=?) )
- Definição do tipo de JOIN
Código:
Filter<Client> filter = new Filter<Client>(Client.class); filter.addEquals("address.streetType.name", "Rua",JoinTypes.LEFT,false); filter.addLike("contacts.email", "%gmail%");//Default: INNER
SQL Gerado:
Select //All properties of Client from Client client0_ left outer join Address address1_ on client0_.address=address1_.id left outer join StreetType streettype2_ on address1_.streettype=streettype2_.id inner join client_contact contacts3_ on client0_.id=contacts3_.client inner join Contact contact4_ on contacts3_.contact=contact4_.id where streettype2_.name=? and ( contact4_.email like ? )
Código:
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("profiles.name", "Admin",JoinTypes.INNER,false); filter.addEquals("profiles.name", "Admin",JoinTypes.LEFT,false); //generates 2 joins: a with INNER and other with LEFT
SQL Gerado:
Select //All properties of User from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id left outer join systemuser_accessprofile profiles3_ on user0_.id=profiles3_.systemuser left outer join AccessProfile accessprof4_ on profiles3_.accessprofile=accessprof4_.id where accessprof2_.name=? and accessprof4_.name=?
- Ordenações
Código:
Filter<User> filter = new Filter<User>(User.class); filter.addOrderDesc("name"); filter.addOrderAsc("profiles.name", JoinTypes.LEFT,false);
SQL Gerado:
Select //All properties of User from systemuser user0_ left outer join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser left outer join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id where 1=1 order by user0_.name desc, accessprof2_.name asc
- Paginação de consultas
Código:
Filter<User> filter = new Filter<User>(User.class); filter.getPaginator().setPageSize(5); filter.getPaginator().setFirstResult(10);
SQL Gerado:
Select //All properties of User from systemuser user0_ where 1=1 limit ? offset ?
- Considerações finais
Por padrão, qualquer cláusula ou FETCH, que não especifica o tipo de JOIN, utiliza o tipo INNER. Por padrão, qualquer cláusula que não especifica o FETCH da propriedade, o Filter entende que NÃO deve ser feito FETCH nesta propriedade. Há duas formas de informar ao Filter que se deve fazer FETCh numa propriedade:
- A primeira é usando o método fetch(String) o qual recebe uma string com o nome da propriedade ou das propriedades aninhadas. Lembrando que não se deve usar propriedade “primitiva” neste método; caso contrário ocorrerá um erro:
filter.fetch(“usuarios”) → ok filter.fetch(“usuarios.name”) → RuntimeException
- A segunda maneira é especificando o parâmetro (Boolean fetch) nas clausulas:
boolean isFetch = true; ... filter.addEquals(“usuarios.nome”,”José”,JoinTypes.INNER, isFetch); → OK
O Filter entende que deve fazer FETCH JOIN com usuários e depois igualar sua propriedade nome a José. Se uma mesma propriedade faz mais de um JOIN com o mesmo tipo, o SQL resultante só fará um único JOIN:
filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER, false); filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.INNER, false); → só haverá um único join com a tabela usuário
Se uma mesma propriedade faz mais de um JOIN com tipos diferentes, o SQL resultante fará mais de um JOIN:
filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER,false); filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.LEFT, false); → haverá um inner join e um left join com usuários
Por limitações do JPA não é possível com uma mesma propriedade usá-la fazendo FETCH e em seguida sem fazer FETCH. Isso causará erro:
filter.addEquals("profiles.screens.id", 1L, JoinTypes.INNER, TRUE); → aqui faz fetch join em profiles e screens filter.addEquals("profiles.screens.module.id", 1L, JoinTypes.INNER, FALSE); → aqui faz join sem fetch em profiles, screens e module. A ideia dessa consulta seria fazer FETCH apenas em profiles e screens, mas, não em module, mesmo que, seja filtrado por uma propriedade em module.
Boas práticas
[TODO: citar e explicar as boas práticas recomendadas para construção do software.]
Dica: veja o conteúdo sobre boas práticas do PJe1 no link http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Revis.C3.A3o_de_C.C3.B3digo
Problemas conhecidos e preocupações
[TODO: citar e explicar, caso tenham: problemas conhecidos e como resolvê-los, lições aprendidas, preocupações futuras]
Instruções de montagem do ambiente de desenvolvimento
Nesta seção, apresentamos os roteiros/instruções para instalação e configuração do ambiente de desenvolvimento. As explicações serão divididas nas subseções desta seção, e, recomendamos que a leitura seja obedecida na ordem em que serão apresentadas as subseções.
Roteiro para instalação e configuração do Eclipse
1. Realizar o download da ferramenta Eclipse Platform Runtime Binary (latest release, 32 ou 64 bits, dependendo do SO (Sistema Operacional) utilizado) disponível no endereço http://download.eclipse.org/eclipse/downloads/. Após o download, realizar a instalação. Esta versão é a mais básica e simples do Eclipse, logo, será preciso realizar também a instalação do marketplace no Eclipse.
2. Para instalar o marketplace, é necessário abrir o Eclipse e acessar o menu "Help > Install New Software...". Na janela aberta (vide Figura 4), selecionar "All Available Sites" na lista "Work with". Em seguida, digitar "marketplace" no campo texto "type filter text" e, depois, selecionar a opção do marketplace e prosseguir com a instalação.
Figura 4. Instalar marketplace.
3. Após instalar o "marketplace" deve ser realizada a instalação do JBoss Tools no Eclipse. Com o Eclipse aberto, acessar o menu "Help > Eclipse Marketplace...". Na janela aberta (vide Figura 5), na aba "Search", digitar "jboss tools" no campo "Find" e pressionar a tecla Enter. Em seguida, selecionar a versão mais recente do JBoss Tools compatível com a versão do Eclipse utilizada.
Figura 5. Instalar JBoss Tools.
4. Configurar no Eclipse a codificação do projeto para utilizar o padrão "UTF8": acessar o menu "Window > Preferences" e escolher a opção "UTF8" para o campo "Text file encoding".
TODO:
- É importante explicar detalhes da preparação do clone do projeto no Git, entre outros detalhes que forem necessários.
Dica: veja o conteúdo postado em http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Configura.C3.A7.C3.A3o_do_ambiente_de_desenvolvimento
Roteiro para instalação e configuração do PostgreSQL
TODO:
- Explicar roteiro para instalar e configurar PostgreSQL.
Diretrizes de configuração caso use um SGBD diferente do PostgreSQL
TODO:
- Incluir as diretrizes de configuração que precisarão ser feitas caso use um SGBD diferente do PostgreSQL.
Roteiro para instalação e configuração do JBoss EAP
1. Realizar o download do JBoss EAP versão 6.4 disponível no endereço http://www.jboss.org/products/eap/download/. A utilização do JDK (Java Development Kit) é obrigatória na versão 1.6 (JDK6) ou superior. Após o download, realizar a instalação.
2. Realizar o download da versão 4 do driver JDBC do PostgreSQL (JDBC4 Postgresql Driver) disponível no endereço https://jdbc.postgresql.org/download.html. Essa versão 4 é compatível com a versão do JDK6.
3. Realizar o download da versão mais recente da ferramenta jdbcdslog disponível no endereço https://code.google.com/p/jdbcdslog/. Esta ferramenta permite a geração de estatísticas e logs das consultas SQL geradas pela JPA a partir do datasource configurado a seguir.
4. Configurar o driver JDBC do PostgreSQL como módulo do JBoss, obedecendo os passos a seguir:
- Passo 1: Criar a pasta "JBOSS_HOME/modules/system/layers/base/org/postgresql/main".
- Passo 2: Criar o arquivo "module.xml" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão jar do driver JDBC do PostgreSQL. Veja, a seguir, como é o conteúdo do arquivo "module.xml":
<module xmlns="urn:jboss:module:1.1" name="org.postgresql"> <resources> <resource-root path="postgresql-9.3-1101.jdbc4.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
- Passo 3: Copiar o arquivo com extensão jar do driver JDBC do PostgreSQL para a mesma pasta do arquivo "module.xml" criada no passo 1.
5. Configurar a ferramenta jdbcdslog como módulo do JBoss, obedecendo os passos a seguir:
- Passo 1: Criar a pasta "JBOSS_HOME/modules/system/layers/base/com/googlecode/usc/jdbcdslog/main/".
- Passo 2: Criar o arquivo "module.xml" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão jar da ferramenta jdbcdslog. Veja, a seguir, como é o conteúdo do arquivo "module.xml":
<module xmlns="urn:jboss:module:1.1" name="com.googlecode.usc.jdbcdslog"> <resources> <resource-root path="jdbcdslog-1.0.6.2.jar"/> </resources> <dependencies> <module name="org.slf4j"/> <module name="javax.api"/> <module name="javax.transaction.api"/> <module name="org.postgresql" optional="true"/> </dependencies> </module>
- Passo 3: Copiar o arquivo com extensão jar da ferramenta jdbcdslog para a mesma pasta do arquivo "module.xml" criada no passo 1.
- Passo 4: Incluir no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml", dentro da tag
<subsystem xmlns="urn:jboss:domain:logging:1.5">
o código:
<logger category="org.jdbcdslog.StatementLogger"> <level name="DEBUG"/> </logger> <logger category="org.jdbcdslog.ConnectionLogger"> <level name="OFF"/> </logger> <logger category="org.jdbcdslog.ResultSetLogger"> <level name="OFF"/> </logger> <logger category="org.jdbcdslog.SlowQueryLogger"> <level name="OFF"/> </logger>
- Passo 5: Incluir no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml", dentro da tag
<datasources>
o código:
<drivers> <driver name="jdbcdslog" module="com.googlecode.usc.jdbcdslog"> <driver-class>org.jdbcdslog.DriverLoggingProxy</driver-class> <xa-datasource-class>org.jdbcdslog.XADataSourceProxy</xa-datasource-class> </driver> </drivers>
6. Configurar o datasouce da aplicação:
- Incluir dentro da tag
<datasources>
no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml" o código:
<datasource jta="true" jndi-name="java:jboss/datasources/pjeDS" pool-name="pjeDS" enabled="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:jdbcdslog:postgresql://db_server:5432/db_name;targetDriver=org.postgresql.Driver</connection-url> <driver>jdbcdslog</driver> <pool> <min-pool-size>2</min-pool-size> <max-pool-size>20</max-pool-size> <prefill>true</prefill> </pool> <security> <user-name>db_user</user-name> <password>db_password</password> </security> <validation> <check-valid-connection-sql>SELECT 1</check-valid-connection-sql> <validate-on-match>false</validate-on-match> <background-validation>false</background-validation> <use-fast-fail>false</use-fast-fail> </validation> </datasource>
Lembre-se de informar corretamente o nome do servidor do SGBD, o nome do esquema do banco de dados, o usuário e a senha para acesso ao banco de dados.
7. Essas configurações consideram que o JBoss será utilizado no modo "standalone". Caso o modo escolhido seja "domain", é necessário que as modificações no arquivo "standalone.xml" sejam também realizadas no arquivo "domain.xml" do diretório "JBOSS_HOME/domain/configuration/".
Diretrizes de configuração caso use um servidor de aplicação diferente do JBoss EAP
TODO
- Explicar as diretrizes de configuração que precisarão ser feitas caso use um servidor de aplicação diferente do JBoss.
TODO:
- Incluir novas seções para explicar as diretrizes extras de configuração que surgirem.
Referências bibliográficas
1. World Wide Web Consortium (W3C) disponível em http://www.w3.org/, último acesso em 26/05/2015. 2. Maven – Welcome to Apache Maven disponível em https://maven.apache.org/, último acesso em 28/05/2015. 3. Code Conventions disponível em http://www.oracle.com/technetwork/java/codeconvtoc-136057.html, último acesso em 02/06/2015.