Arquitetura
Este documento é o veículo de comunicação que informa aos desenvolvedores quais partes do sistema devem construir, bem como de qual maneira estas partes se comportam e interagem entre si. Ao determinar a estrutura de camadas e componentes do projeto, torna-se mais fácil o planejamento e a administração por parte dos gerentes. Fornece, para quem irá manter e modificar a arquitetura, a primeira visão elementar do sistema, e um entendimento das motivações que levaram às decisões técnicas mais importantes.
Além disso, foca em aspectos específicos do projeto, concentrando-se na sua estrutura, nos elementos essenciais, nos cenários chaves e aspectos que possuem impacto duradouro nos atributos de qualidade do sistema tais como: desempenho, confiabilidade, adaptabilidade e custo. Define também o conjunto de mecanismos, padrões e estilos que irão guiar o restante do projeto, assegurando a sua integridade.
O caderno de arquitetura traz ainda benefícios na fase de construção das unidades de implementação, dos testes unitários, integração de componentes, gerência de configuração e documentação. A organização da arquitetura pode também ajudar o gerente de projeto a decidir quanto à organização do time ou como montar a equipe.
Especificamente, este caderno apresenta a arquitetura para a versão 1.6 do sistema de processo eletrônico de que trata o TCOT CNJ n.º 73/2009 (acesso ao DJE), no qual se firmou o compromisso de elaborar e manter um sistema de acompanhamento e tramitação de processo judicial eletrônico posteriormente denominado sistema Processo Judicial Eletrônico – PJe.
Público-Alvo
O presente documento se destina aos envolvidos diretamente no desenvolvimento do sistema PJe, seja no próprio Conselho Nacional de Justiça, seja nas equipes de desenvolvimento formadas por órgãos ou tribunais participantes do projeto.
Estrutura do documento
Este documento utiliza o Modelo de Visão 4+1 de Philippe Kruchten, permitindo que se identifique as diferentes necessidades na arquitetura proposta [KRU99].
A visão de casos de uso descreve as funcionalidades do sistema a partir dos requisitos que tenham repercussão nas decisões de arquitetura, ou quando esses casos de uso ilustram um ponto específico, delicado da arquitetura. Esta seção ilustrará como o software realmente trabalha, provendo algumas realizações de casos de uso, por meio de diagramas de interação ou cenários, explicando como os vários elementos do modelo do projeto contribuem para atender a essa funcionalidade.
A seção dedicada à visão lógica descreve como os elementos do modelo de projeto, que são importantes para a arquitetura, são decompostos em subsistemas e pacotes e, para cada pacote significativo, seu detalhamento em termos das classes que o compõe. Algumas classes criadas pelo modelo de projetos são também documentadas, descrevendo as suas responsabilidades, operações e atributos.
A visão de processos descreve os aspectos de concorrência e sincronização da aplicação.
A visão de implantação descreve os nodos (hardware) onde o software será distribuído e executado. É uma visão do modelo de disponibilização.
A visão de implementação descreve a organização estática do software no ambiente de desenvolvimento, sua decomposição em camadas e subsistemas e inclui outros componentes significativos para a arquitetura.
Convenções deste documento
Para melhor apreensão deste manual, serão adotadas algumas convenções de conceitos e exibição de informações.
Conceitos, termos e abreviações
Esta seção apresenta o conceito ou a abreviação de alguns termos importantes que serão mencionados no documento, todos relacionados ao processo de gerência de configuração de software.
TODO
Requisitos não funcionais
Interoperabilidade
Interoperabilidade diz respeito à facilidade de comunicação com outros sistemas. O modelo de interoperabilidade proposto para o PJe privilegia uma arquitetura orientada a serviços visando sobretudo o rápido desenvolvimento com a diminuição dos custos e a integração com parceiros externos.
Nesse contexto, sempre que possível, deve-se utilizar serviços web, sem entretanto negligenciar os problemas ligados à segurança, desempenho e consumo de recursos ligados a este tipo de tecnologia.
O sistema terá, inicialmente, interface com os seguintes sistemas externos:
Sistema | Órgão/Ente | Finalidade |
Cadastro Nacional de Advogados | Conselho Federal da Ordem dos Advogados do Brasil | Troca de informações a respeito da existência e regularidade de inscrição de pessoa como advogado |
Cadastro de Contribuintes do Ministério da Fazenda | Secretaria da Receita Federal do Brasil | Validação e obtenção de informações a respeito de dados de pessoas físicas e jurídicas |
Além desses sistemas, o PJe deverá, em momento posterior, passar a utilizar serviços providos pelos seguintes sistemas:
Sistema | Órgão/Ente | Finalidade |
Registro de Imóveis | Associação Nacional de Registradores | Permitir a concretização de ordens de indisponibilidade e de pesquisas por bens imóveis |
BacenJud/CSS | Banco Central do Brasil | Permitir a concretização de ordens de indisponibilidade de ativos financeiros e de pesquisas a seu respeito, assim como de pesquisas a respeito de relacionamentos financeiros entre pessoas |
Sistema bancário | CEF, Banco do Brasil e outros bancos responsáveis por contas de depósitos judiciais e/ou recolhimento de custas | Troca de informações a respeito da realização de depósitos e pagamentos judiciais |
Cadastro de Magistrados | Conselho Nacional de Justiça | Validação e obtenção de informações a respeito de magistrados |
Replicação Nacional | Conselho Nacional de Justiça | Envio de dados para consolidação estatísticas pelo CNJ. |
Renajud | Ministério das Cidades | Permitir a concretização de ordens de indisponibilidade de veículos automotores, assim como pesquisas a esse respeito |
SNBA | Conselho Nacional de Justiça | Permitir o envio e recuperação de informações de bens postos sob a responsabilidade do Poder Judiciário |
Os pontos de interface comporão um projeto maven separado do projeto principal e deve ser internalizados no sistema como biblioteca. A configuração de endereços de acesso desses serviços deve poder ser feita por meio de parâmetros do sistema, recuperável por meio de interface específica para tanto.
Integração com sistemas do próprio Judiciário
Além da integração com sistemas de terceiros, é imprescindível que o PJe também seja capaz de se comunicar com outros sistemas do próprio Poder Judiciário para efetivar atividades que dependam dessas informações ou para permitir que as atividades realizadas por esses sistemas que dependam das informações do PJe possam ser realizadas. Para concretizar a primeira dessas demandas, o PJe preverá um conjunto de interfaces, que serão implementadas individualmente por cada tribunal interessado e reunidas no projeto como bibliotecas, de modo que, estando disponível o componente implementador da interface, seja possível ao PJe concretizar suas regras de negócio. Em um primeiro momento, essas interfaces incluirão operações relativas a:
- prevenção relativa a processos de sistemas legados
- publicação em diário oficial
- envio e recebimento de informação sobre cartas (correios)
- confirmação de recolhimento de custas processuais
Caso um tribunal pretenda realizar alguma atividade adicional no sistema, deverá criar seus componentes em projetos separados e implementar suas demandas em objetos de Services que acessem as managers existentes no PJe, sem prejuízo de tratar informações não existentes no PJe em fonte de informação separada. Exemplo disso seria um tribunal que efetiva um controle orçamentário e financeiro mais rígido demandando contabilização de determinados atos processuais nessa atividade, caso em que deverá criar um projeto separado cujos componentes serão responsáveis por monitorar e armazenar em banco de dados separado essas informações. Além dessas interfaces, ao lançar uma versão minor (x.x.X), o PJe deve aderir integralmente ao Modelo Nacional de Interoperabilidade na versão estável imediatamente anterior.
Segurança
Os requisitos de segurança seguem especificações do MoReq-Jus e, no que couber, do e-PING, conforme previsto na Resolução 90 do Conselho Nacional de Justiça. Os dados e informações do PJe devem ser protegidos contra ameaças de forma a reduzir riscos e garantir a integridade, confidencialidade, disponibilidade e autenticidade, observando-se a Política de Segurança da Informação e Comunicações do Conselho Nacional de Justiça, sem prejuízo do intercâmbio de informações com outros sistemas. A segurança é um processo que deve estar inserido em todas as etapas do ciclo de desenvolvimento do PJe. É recomendável utilizar a abordagem proposta pela OWASP e WASC para direcionar o processo de desenvolvimento seguro, testes de segurança e detecção de vulnerabilidades do sistema. Devem ser seguidas as recomendações proposta pelo e-PING, notadamente as seguintes:
- documentos cujo nível de sigilo impeça o conhecimento da informação por pessoas que não fazem parte do processo judicial ou que dele não participam direta ou indiretamente devem ser criptografados
- as informações somente devem poder ser obtidas por aqueles que têm nível de acesso suficiente para as conhecer
- requisitos de segurança da informação, dos serviços e de infraestrutura devem ser identificados e tratados de acordo com a classificação da informação, níveis de serviço definidos e resultado da análise de riscos
- todos os sistemas ou módulos diretamente envolvidos com o PJe devem manter registros históricos (logs) para permitir auditoria e prova material futura, buscando-se a sincronia de tempo entre os sistemas que realizam esses registros
- serviços de segurança de XML devem estar em conformidade com as especificações do W3C
- tráfego de dados protegido por meio de criptografia
- uso de certificação digital de acordo com as regras da ICP-Brasil para a emissão de assinaturas digitais de documentos e do próprio código-fonte
- manutenção e execução de plano de gerência de configuração que assegure que a documentação do sistema, de seus controles de segurança e de sua topologia permaneça atualizada e protegida segundo o grau de sigilo pertinente
- inserção de carimbo de tempo nos moldes definidos pelo ICP-Brasil, quando disponível, nos objetos assinados eletronicamente
- utilização do algoritmo de hash MD5 ou mais forte para a concretização das assinaturas digitais
- utilização do algoritmo RSA para transporte de chave criptográfica de conteúdo ou sessão
- adoção dos requisitos da Resolução 65/2009, do Comitê-Gestor do ICP-Brasil para os módulos criptográficos
- utilização de WS-Security 1.1 para troca de mensagens SOAP
Requisitos gerais de segurança
- utilizar algoritmos criptográficos recomendados pelo e-PING
- registrar eventos relacionados a número de tentativas de autenticação, bloqueios de contas e erros de aplicação
- evitar a disponibilização de informações que detalhem a infraestrutura ou a arquitetura do sistema nas exceções ou mensagens de erro exibidas
- possuir a capacidade interna de registrar logs para os eventos que são importantes para atender requisitos de confidencialidade, disponibilidade e integridade
- validar os dados fornecidos pelo usuário antes de seu consumo na atividade negocial fim
- as validações e verificações de segurança devem ser feitas em ambiente computacional diretamente controlado pelos administradores do sistema, ou seja, essas validações não podem ser delegadas para aplicativos controláveis pelo cliente
- a definição dos papéis no sistema deverá obedecer ao princípio do menor privilégio
- quando da acumulação de papéis em um único perfil, o nível de acesso às informações resultante deve ser o maior entre eles
- verificar a integridade dos componentes principais do sistema antes de sua inicialização
Requisitos de autenticidade
- impedir que os mecanismos de autenticação de usuário permitam engenharia reversa ou sejam manipulados para permitir o acesso não autorizado
- os recursos do sistema somente deverão ficar à disposição de usuários legítimos
- autenticação em servidor deverá ser feita através de canal criptografado
- única rotina de verificação, preferencialmente com um sistema exclusivo de segurança, garantindo assim um mecanismo menos intrusivo para esse requisito
- exigir autenticação prévia de sistemas externos sempre que um componente de comunicação for acessado
- informar tempo restante para a expiração da sessão
- expirar a sessão após certo tempo de inatividade
- armazenamento de chaves de criptografia críticas
- permitir que o usuário acesse o sistema em várias sessões simultâneas em navegadores diversos, exibindo alerta a respeito desse fato
- registrar falhas de login, indicando o número de tentativas realizadas, token de sessão (se houver), endereço IP e hora;
- apresentar, após o login do usuário, a data e a hora da última autenticação bem sucedida e se houve falhas desde então;
- os certificados digitais devem ser verificados utilizando a LCR (lista de certificados revogados).
Requisitos de confidencialidade
- os dados enviados para outros sistemas devem ser protegidos contra quebra de confidencialidade no trânsito
- o armazenamento de chaves criptográficas no código do sistema deve ser evitado, de forma a dificultar ao máximo sua identificação e recuperação
- as variáveis de sessão ou “cookies” não devem armazenar informações sensíveis
Requisitos de disponibilidade
- as funções externas chamadas pelo sistema devem ter seu retorno verificado, evitando que parâmetros errados sejam propagados entre as funções do sistema
Requisitos de integridade
- registrar a criação e a remoção de usuários, bem como a atribuição e a remoção de direitos do usuário
- transações críticas devem prover mecanismos que identifiquem inequivocamente sua autoria
- existência de trilha de auditoria
- as trilhas de auditorias devem ser protegidas contra alteração e remoção por parte de todos os usuários
- deve ser possível verificar as trilhas de auditorias de forma manual ou automatizada
- registrar acessos em dados sensíveis mantidos pela aplicação.
Usabilidade
Segundo a ISO 9126, a usabilidade, sob o ponto de vista da qualidade de uso, “é a capacidade do produto de software permitir a usuários específicos atingir metas específicas com eficácia, produtividade, segurança e satisfação em um contexto de uso específico”. Nos tópicos a seguir são enumerados os atributos de usabilidade considerados fundamentais para o PJe.
Inteligibilidade
Esta característica diz respeito aos atributos do PJe que evidenciam o esforço do usuário para reconhecer o conceito lógico e sua aplicabilidade. Os componentes de interface gráfica devem estar bem agrupados, com os ícones dos botões representativos e mnemônicos. Os nomes das janelas e os componentes visuais devem manter coerência com a finalidade a que se destinam. Além disso, a ergonomia deve ser adequada e os recursos oferecidos facilmente identificáveis de uma forma quase sempre intuitiva. As mensagens do sistema devem estar em português e em linguagem não técnica, trazendo, em caso de erro, além da mensagem, o respectivo número do erro gerado pelo próprio sistema para facilitar a sua identificação.
Apreensibilidade
Esta característica diz respeito aos atributos do PJe que demonstram o esforço do usuário para aprender a usar a aplicação. Neste sentido, considera-se relevante a existência, pelo menos, dos seguintes recursos:
- arquivos de ajuda, preferencialmente sensíveis ao contexto e com hipertexto;
- tutoriais;
- manual do usuário;
- dicas nos campos.
Operacionalidade
Refere-se ao esforço do usuário para operar e controlar o sistema. A otimização de entrada de dados através de valores-padrão, seleção de dados pré-definidos, disponibilidade de teclas de atalho, disponibilidade de funções para o usuário cancelar, desfazer ou refazer uma tarefa ou ação, são recursos que contribuem para a facilidade de operação do sistema.
O PJe deve oferecer os seguintes recursos:
- incluir valores padrões, quando aplicáveis;
- incluir recurso de preenchimento de outros campos quando valores padronizados podem ser obtidos de um campo determinado, tal como com os dados de endereço que podem ser parcialmente obtidos a partir do CEP;
- exibir as informações estruturadas hierarquicamente em formato de árvore ou outra forma de exibição que permita a apreensão dessa estrutura pelo usuário.
Além dessas características, que devem ser aplicadas para a visualização padrão produzida, devem ser feitos estudos para a preparação de camada de visão específica que atenda aos requisitos da Recomendação CNJ n.º 27/2009.
Eficiência
Eficiência se refere à quantidade de esforço e recursos necessários para se chegar a um determinado objetivo.
Nesse sentido diversos aspectos podem influenciar na eficiência do PJe. Os desvios que o usuário faz durante a interação e a quantidade de erros cometidos pode servir para avaliar o nível de eficiência do sistema.
Deve-se, pelo menos:
- reduzir, sempre que possível, a quantidade de cliques necessários para a realização de uma operação
- realizar operações que podem ser automatizadas sem a necessidade de intervenção do usuário
Manutenibilidade
Testabilidade
No contexto deste documento, testabilidade diz respeito à facilidade de o software ser testado, ou seja, de ser validada a sua corretude. Quanto maior a testabilidade, mais fácil é acrescentar testes em vários níveis, desde testes de unidade até testes de sistema.
No desenvolvimento do PJe, dever-se-á desenvolver os diferentes módulos atentando para o seguinte:
- na camada de modelo, testes unitários para verificação de funcionalidades implantadas em classes utilitárias e em métodos que sigam o padrão DDD(Domain-Driven Design-Eric Evans);
- na camada de negócio, testes em todos os objetos managers e services, para todos os seus métodos, de modo a permitir verificar o comportamento do sistema em situação de quase produção;
- na camada de visão, dever-se-á, quando possível, testar as classes action de modo a simular o comportamento do usuário em sua interação com o sistema.
Para elaboração dos testes unitários simples, dever-se-á utilizar a biblioteca JUnit, com o correspondente plugin da Eclipse IDE.
O CNJ e os tribunais com convênio de fábrica de software do PJE devem manter uma equipe específica para testes de negócio da aplicação. Também devem, quando possível, criar scripts automatizados para teste das funcionalidades do sistema, utilizando as ferramentas e padrões definidos pelo CNJ.
Arquitetura proposta
Visão de casos de uso
Com o objetivo de uniformizar e concentrar o tratamento de questões negociais mais relevantes, à exceção dos CRUDs simples, as implementações deverão acessar interfaces de serviço do sistema para concretizar seus objetivos negociais. Essas classes são as descritas a seguir:
Nome | Descrição |
AudienciaService | Interface que encerra os métodos para gravação, recuperação e modificação de informações relacionadas a audiências. Alguns métodos dessa interface podem ser expostos como serviços web. |
AtoComunicacaoService | Interface que encerra métodos destinados a criar e recuperar informações relativas a atos de comunicação expedidos em processos judiciais, assim como quanto a prazos aplicáveis a essas intimações. |
AutuacaoService | Interface que encerra métodos destinados a verificar a integridade negocial de uma autuação de processo novo, incidental ou recursal. |
DistribuicaoService | Interface que encerra métodos destinados a viabilizar a distribuição de processos entre os órgãos julgadores competentes para seu processo e julgamento. |
DocumentoProcessualService | Interface que encerra métodos destinados a viabilizar a criação, modificação, validação e recuperação de documentos processuais. |
IdentidadeService | Interface que encerra métodos destinados a autenticar e autorizar usuários a terem acesso a processos e/ou funcionalidades do sistema. |
PrevencaoService | Interface que encerra métodos destinados a identificar a existência de possível prevenção entre processos judiciais. |
SessaoJulgamentoService | Interface que encerra métodos destinados à gravação, recuperação e modificação de informações relacionadas a sessões de julgamento. Alguns métodos dessa interface podem ser expostos como serviços web. |
TramitacaoProcessualService | Interface que encerra métodos destinados à tramitação de processos judiciais já existentes. |
Além dessas interfaces e das implementações correspondentes, com o intuito de facilitar os desenvolvedores nas tarefas mais básicas, tais como as de realizar um CRUD, foi desenvolvido uma espécie de framework com diversas classes-base. A figura a seguir apresenta um diagrama de sequência de uma chamada ordinária no sistema, ilustrando o fluxo entre as várias camadas.
Entre a camada de action e a camada de manager, quando não se tratar de um mero CRUD, deve-se utilizar um dos componentes service de que tratam as interfaces já descritas.
As linhas de vida acima expostas, à exceção do usuário, têm as seguintes funções e tecnologias:
a) xhtml: camada de visão, implementada na tecnologia JSF com a implementação Facelets + Richfaces, envolvida por uma camada JBoss Seam com vistas a evitar erros relativos à inicialização de variáveis, destinadas a permitir a apreensão do usuário de informação do sistema ou o fornecimento, por ele, de algo a ser processado internamente;
b) derivada de BaseAction: camada de visão, implementada em componente Seam (Java) com escopo de evento, devendo uma action ser implementada para cada conjunto de telas destinado a atender um determinado caso de uso;
c) derivada de BaseManager (ou Service): camada de negócio, implementada em componente Seam (Java) com escopo de evento, devendo uma manager ser implementada para cada entidade concreta do sistema e uma service (que pode agrupar managers) ser implementada para o fornecimento de serviços que reclamem o tratamento de entidades não diretamente relacionadas entre si;
d) derivada de BaseDAO: camada de negócio, implementada em componente Seam (Java) com escopo de evento, devendo uma DAO ser implementada para cada entidade concreta do sistema;
e) EntityManager: camada objeto-relacional, a ser utilizada sem qualquer alteração do código-fonte da implementação JPA adotada, sem prejuízo de serem incluídas medidas gerenciais inerentes a esse modelo JPA, como, por exemplo, mecanismos de auditoria automática;
f) banco de dados: camada de persistência sobre a qual o desenvolvedor não deve produzir qualquer modificação direta.
Os casos de uso em que o ator principal é outro sistema – por exemplo, como no caso de serviços Web ofertados pelo PJe publicamente ou mediante autenticação específica – seguem a mesma sequência, tendo como fronteira externa a camada de serviços, devendo um componente Seam ser criado para cada serviço a ser ofertado, ainda que ele envolva mais de uma operação.
Visão lógica
Do ponto de vista lógico, o PJe está dividido em pelo menos 3 projetos maven: pje-interfaces, pje-storage e pje. As implementações de interfaces de serviços não internos do PJe deverão ser concretizadas em projetos próprios a serem incluídos como dependências nos perfis de compilação e construção respectivos.
Internamente, cada um desses projetos segue a estrutura de pastas padrão de projetos maven. Internamente, as classes estão estruturadas em pacotes que têm o prefixo br.jus.cnj.pje, complementados com os seguintes subpacotes:
Pacotes | ||
Projeto(s) | Pacote | Descrição |
pje-interfaces | extensao | Contém as interfaces de pontos de extensão do PJe que devem ser implementadas em serviços externos ao PJe |
extensao.servico | Contém as interfaces de serviços que devem ser implementados fora do PJe. | |
interfaces | Contém as interfaces que viabilizam troca de informações pertinentes a objetos de interesse do PJe independentemente de sua implementação. | |
interfaces.servico | Contém as interfaces de serviços que são implementados no próprio PJe e que, em razão disso, podem ser invocadas por uma implementação de ponto de extensão externo quando dentro do contexto de execução do PJe. | |
pje | business | Contém as classes utilizadas indistintamente nas camadas DAO e Manager do PJe. |
business.dao | Contém as classes de acesso a dados do sistema. | |
business.manager | Contém as classes de gerenciamento de negócio das entidades do sistema | |
entidades.* | Contém as entidades JPA do sistema. | |
service | Contém as implementações de serviços do PJe. | |
view | Contém as implementações de actions do sistema, especificamente aquelas não vinculadas a telas de fluxo. | |
view.fluxo | Contém as implementações de acions do sistema que estão vinculadas a actions de fluxo. | |
util | Contém classes e componentes utilitários para o sistema, assim como classes definidoras de constantes que podem nele ser utilizadas. | |
pje-storage | storage | Contém os componentes que implementam o mecanismo de persistência de documentos do sistema. |
A seguir, são expostos o conteúdo e objetivos de cada um dos projetos maven componentes do sistema.
pje-interfaces
Projeto que contém a definição de versões, plugins e profiles a serem utilizados pelos demais projetos.
pje-storage
O projeto pje-storage é um projeto maven que resulta em um artefato de biblioteca (JAR) que provê ao sistema uma implementação de serviço de gravação de documentos em base de dados. Esse projeto pode ser substituído pelos tribunais por implementação diversa da funcionalidade, por exemplo, para que a gravação se dê em sistema de arquivos ou em CAS.
pje
O projeto pje é um projeto maven que resulta em um artefato WEB archive (WAR) que provê todas as camadas do projeto.
Visão de implantação
O sistema deve ser implantado em configuração única para cada uma das instâncias de aplicação. A troca de processos entre instalações deve ser feita pelo mecanismo de interoperabilidade.
Visão de implementação
O PJe está organizado em 3 camadas horizontais: visão, controle, serviço e persistência e duas camadas verticais: comuns e transversal.
Camada comuns
Esta camada é uma camada vertical do sistema, permeando todas as demais camadas horizontais e que contém, como o próprio nome sugere, os pacotes que são comuns para todo o PJe.
O pacote modelo contém as classes que fazem o mapeamento Objeto-Relacional usando JPA 1.0.
Para essas classes cabe destacar:
a) o mapeamento deverá ser feito usando classes anotadas segundo as especificações JSR 269 nos métodos (properties);
b) os IDs das entidades devem ser criados preferencialmente com o tipo java.lang.Long e, além disso, com o uso de gerador de identidade específico existente no sistema;
c) as entidades não devem ser criadas como objetos Seam nem incluir injeções de objetos tais;
d) cada entidade deve ter sua própria chave primária;
e) relacionamentos ManyToMany devem ser mapeados em entidades autônomas, exceto se isso for impossível em razão do uso de algum framework previamente definido;
f) deve ser evitada a criação de campos de tipo String sem limite de caracteres;
g) se necessários campos de tipo String sem limite de caracteres, eles devem ser anotados como campos @Lob e com recuperação preguiçosa (FetchType.LAZY);
h) a estratégia “g” deve ser adotada também quando o campo do tipo String tiver tamanho superior a 1024 bytes;
i) os campos de listas (derivados de java.util.Collection) devem ser criados com a implementação padrão definida e inicializados com uma lista vazia, e sua recuperação deve ser preguiçosa.
A implementação do padrão DDD deve atentar para a necessidade de se utilizar informações contidas na própria entidade ou em seus atributos diretos.
Exceções
Um dos itens que indicam qualidade de um sistema é a impressão de mensagens aos usuários de forma coesa e precisa. Para isso, é importante que se defina bem a política de lançamento e tratamento de exceções, já que estas, em camadas superiores da arquitetura, tem ligação direta com as mensagens aos usuários.
Em Java, há dois tipos de exceções: as denominadas Checked Exceptions (verificadas) e as Not Checked Exceptions (não verificadas). Essa primeira define exceções que obrigatoriamente precisam ser tratadas ou relançadas explicitamente pelo programador. As exceções do tipo não verificadas não obrigam a captura da exceção lançada na camada atual ou nas superiores.
Normalmente definem-se as exceções verificadas (herdando de Exception) para exceções de regras de negócio, tais como inexistência de usuário. Usar exceções deste tipo para regras de negócio obrigam o programador a 1) tentar recuperar o sistema da falha, ou 2) mostrar uma mensagem ao usuário mais coerente com o ocorrido.
O que ocorre na prática é que normalmente o programador não consegue recuperar o sistema a partir de uma exceção de negócio. Por exemplo, após ser lançada uma exceção do tipo SaldoInsuficienteException a única coisa que o código de serviço pode fazer é relançar a exceção para que uma mensagem ao usuário seja mostrada: “Seu saldo é insuficiente para realizar esse saque.”.
Levando isso em consideração, no PJe a hierarquia de exceções foi definida de forma que as exceções de sistema sejam não verificadas, desburocratizando assim o trabalho do desenvolvedor que normalmente era de apenas relançar a exceção. Além disso, o fato de todas as exceções de sistema serem não verificadas reduz o problema de mudança da interface de um método para acrescentar ou tirar exceções de sua assinatura.
PJeException representa a classe que define o que tem em comum às exceções do PJe, que é o código único da exceção e a chave da exceção.
Código único da exceção representa um código gerado usado para facilitar os desenvolvedores a achar a causa do problema. Esse código é logado junto com a stacktrace da exceção e é também impresso na tela do usuário ao lado da mensagem do erro. Desta forma, o desenvolvedor/servidor de apoio pode procurar no log o erro específico após o usuário informar o código do erro em sua tela.
A chave da exceção representa o tipo da exceção.
Há dois tipos de exceção no PJe, a PjeDAOException e a PjeBusinessException. A PJeDAOException é utilizada em todos os erros da camada de persistência que não possam ser recuperados, sendo o erro “traduzido” para um erro do PJe. Essa exceção causa rollback nas transações e, por isso, não pode ser tratada e deve ser propagada para todas as camadas superiores, para que o framework lide com as transações adequadamente. A PjeBusinessException deve ser lançada em todos os erros havidos na validação de regras de negócio do sistema.
Em qualquer caso, para que a camada de visão exiba adequamente a mensagem de erro, as exceções contém um parâmetro “chave” e parâmetros de texto. Essa chave é uma string no formato: excecao.[nome_servico].nome_erro. Por exemplo: excecao.autuacao.advogadojacadastrado. Essa chave é usada tanto para diferenciar as exceções de negócio quanto para mostrar a mensagem específica para o usuário via um message-bundle na interface. O arquivo de mensagens terá como chave todas as chaves das exceções, bem como a mensagem respectiva (ex.: excecao.autuacao.advogadojacadastrado=O advogado de OAB {0} já está cadastrado no processo {1}. ).
Nos serviços web externalizados (WebServices), as exceções devem ser lançadas como PjeBusinessExceptions e tratadas nos serviços antes do retorno para o cliente.
Camada persistência
Nesta camada estão as classes que tratam o acesso a dados das entidades. Cada entidade potencialmente terá seu próprio DAO.
Nas classes DAOs há referência ao EntityManager de JPA para lidar com o banco de dados. Para os métodos básicos de CRUD foram implementados métodos na classe BaseDAO. Nesta camada também foram definidos métodos para paginação real em banco.
O método remove() tem uma semântica diferente daquilo que normalmente é feito. De acordo com o MoReq-Jus nenhum registro deve ser removido da base de dados, apenas inativado. Desta forma, o remove() do BaseDAO não remove do banco fisicamente, apenas altera o campo ativo da entidade para false. Assim, tal registro não é mostrado no PJe, dando a impressão ao usuário que ele não existe.
Camada serviço
Esta camada representa o coração do PJe. Representa, em grande parte a camada “controller” do modelo MVC. O escopo dos componentes que estão nesta camada deve ser EVENT.
É responsável por manter todas as regras de negócio através das classes Managers e Services.
As classes Managers são destinadas a orquestrar serviços de escopo restrito a uma entidade de domínio. Pensando em uma abordagem DDD as entidades deverão encapsular métodos que representam as regras de negócio de sua alçada e os componentes de negócio ou managers irão apenas recepcionar eventos e, casualmente, tratar pré-condições para então acionar os serviços de dados. As regras de domínio deverão ser delegadas para as Entidades responsáveis.
Uma classe do tipo Manager gerencia o acesso aos dados de uma determinada entidade. Na Manager haverá métodos CRUD, bem como métodos de validação da entidade que ela representa. Cada entidade do sistema deve ter seu próprio manager, e um manager só acessa diretamente o DAO de sua entidade (i.e: AdvogadoManager referencia AdvogadoDAO).
Toda Manager deve estender de BaseManager, e esta contém todos os métodos de CRUD para uma entidade específica.
As classes Services são úteis para orquestrar uma lógica de negócio que permeia diversas agregações de entidades. As classes Services não devem implementar cálculos, mas somente fluxos e delegações, incluindo condições, laços e algoritmos. Cada serviço deve estar associado a um ‘tema’ comum e bem definido, valendo-se de classes managers para se desincumbir de suas tarefas. Um serviço, por referenciar um tema, não deve ter o nome de uma entidade. Além disso, um serviço nunca acessa a subcamada DAO diretamente. Serviços também podem se comunicar com outros serviços. Exemplos de Serviços: DistribuicaoService e AutuacaoService.
Nesta camada também estão localizados os agentes para serviços. Estes artefatos de software devem servir de ponte para provedores e consumidores de serviços, incluindo aí serviços externos para outros sistemas ou entidades.
A integração com o jBPM deve ser feita também nesta camada através dos componentes de workflow.
Camada visão
Nesta camada estão os componentes de interface com o usuário, merecendo especial atenção por parte dos desenvolvedores, já que esta é a porta de entrada do sistema.
Algumas das tecnologias utilizadas nesta camada são JSF com Richfaces e Facelets e JBoss Seam para o orquestração.
Recomendações importantes para a escrita de arquivos xhtml:
- usar tags HTML quando não houver necessidade de manutenção do componente na árvore de elementos do JSF, que ocupa espaço na memória do servidor e costuma ser um gargalo em sistemas baseados nesta tecnologia;
- usar Ajax sempre que possível para dar maior dinamismo às telas dos usuários;
- as exceções do tipo PJeBusinessException devem ser tratadas e repassadas ao usuário a mensagem do Message Bundle referente à chave da exceção. Outras exceções devem ser enviadas a uma tela específica de erro;
Recomendações importantes para a camada de visão:
- os frames desta camada, escritos em arquivos xhtml (facelets), devem acessar apenas as Actions (JBoss Seam), as entidades manipuladas e os componentes Seam necessários para a visão (FacesMessages etc.);
- as Actions são componentes POJO que, por padrão, terão o escopo de evento;
- as classes Actions recebem os eventos de GUI da aplicação e, por sua vez, devem acessar apenas a camada de negócio (Service ou Manager), de modo que o acesso direto à camada DAO não é permitido para que não haja inconsistência no tratamento dos dados;
- as Actions são responsáveis por tratar e validar os dados de entrada da tela e por efetivar a lógica de tela;
- validações de entidade devem ser feitas pelo uso de Hibernate Validator e quando se tratar de uma validação negocial genérica, nas managers.
Toda Action deve estender a classe BaseAction, que contém métodos, principalmente, para lidar com CRUDs de entidades.
O PJe deve ter classes em que serão registradas constantes para identificação de permissões e eventos lançados pelo sistema. Tais eventos servem para informar observadores (padrão Observer) que alguma ação foi realizada ou algum estado foi alterado.
As injeções das dependências devem ser feitas utilizando-se anotações do Seam. Os objetos injetados devem ser referenciados através de suas respectivas abstrações, evitando-se o uso de classes concretas.
Referências
[KRU99]-Philippe Kruchten. The Rational Unified Process: an introduction. Addison Wesley, 1999, ISBN 0-201-60459-0
Mock Objects, http://pt.wikipedia.org/wiki/Mock_Object, acessada em 16/06/2011
Mockito, http://code.google.com/p/mockito/, acessada em 16/06/2011
EasyMock, http://easymock.org/, acessada em 16/06/2011
JUnit, http://junit.org/, acessada em 16/06/2011
Testes de Integração, http://pt.wikipedia.org/wiki/Teste_de_integra%C3%A7%C3%A3o, acessada em 16/06/2011
E-Ping, http://www.governoeletronico.gov.br/biblioteca/arquivos/documento-da-e-ping-versao-2011/view, acessada em 15/06/2011
MoReq-Jus, http://www.jf.jus.br/cjf/tecnologia-da-informacao/gestao-documental/moreq-jus-1, acessada em 15/06/2011
OWASP, https://www.owasp.org, acessada em 15/06/2011
WASC, http://www.webappsec.org, acessada em 15/06/2011
DDD, http://en.wikipedia.org/wiki/Domain-driven_design, acessada em 15/06/2011
Proposta de transição de arquitetura
A fim de facilitar o desenvolvimento no PJe atual usando o modelo de arquitetura definido neste documento e visando uma migração menos traumática para esta arquitetura num futuro próximo, vê-se necessário o uso de uma arquitetura intermediária que possa ser usada nas novas implementações do PJe.
A arquitetura intermediária será atingida por duas abordagens.
A primeira será usada quando a implementação de uma funcionalidade é totalmente nova, não usando classes, normalmente do modelo, do que já está implementado na arquitetura atual, ou usando o mínimo de componentes já existentes. Nesse caso, pode-se dizer que a arquitetura usada será totalmente nova. A segunda é usada quando se deseja migrar uma implementação feita na arquitetura anterior para a arquitetura proposta.
Para a primeira abordagem, usa-se a nova arquitetura de ponta a ponta, fazendo a página xhtml acessar diretamente o Action através das ELs. A partir do Action vão sendo criados os componentes necessários para todas as camadas propostas até chegar no componente de acesso a dados.
Para a segunda a abordagem, sugere-se a decomposição das classes Home usadas atualmente em novas classes que irão compor a nova arquitetura, mantendo a classe Home apenas como delegate para o novo Action, que passará a acessar os novos componentes na sequência proposta pela nova arquitetura. Nessa abordagem, a página xhtml também se mantém inalterada, já que continuará chamando a mesma classe Home em suas expressões de EL.
Passos dessas atividades:
- abrir a página sob refatoração;
- examinar as expressões EL;
- abrir as classes Home acessadas;
- delegar para o novo Action o comportamento da operação acessada nas homes, criando os componentes necessários para a navegação entre as camadas.
A atividade de inclusão da nova arquitetura será realizada, em primeiro lugar, realizando uma junção dos três projetos atuais em um único projeto no formato e com a organização do maven. Em segundo lugar, as estratégias acima serão realizadas por meio da segmentação das classes nos pacotes correspondentes às respectivas camadas. Tudo o que for feito na versão descanso na nova arquitetura deverá ser replicado na versão esmeralda considerando suas entidades.