Engenharia Reversa para Recuperação de Modelos de Sistemas Desenvolvidos em PL/SQL - PDF
Download "Engenharia Reversa para Recuperação de Modelos de Sistemas Desenvolvidos em PL/SQL"
Leonardo Caires César
1 Engenharia Reversa para Recuperação de Modelos de Sistemas Desenvolvidos em PL/SQL Rodnei Couto 1, Luana Lachtermacher 1, Soeli Fiorini 1, Akeo Tanabe 1, Gustavo Carvalho 1, Arndt von Staa 1, Ricardo Choren 2 1 Departamento de Informática PUC-Rio Rua Marquês de São Vicente Rio de Janeiro RJ Brasil 2 Seção de Engenharia de Computação IME/RJ Pça General Tibúrcio Rio de Janeiro RJ Brasil Abstract. Recovering a legacy system structure helps its maintenance. With the system structure it is possible to understand the system and to make an impact analysis about a change request. This paper shows an approach to recover the structural models of legacy systems, which were developed using PL/SQL. The structure recovery is based on search patterns that extract the dependencies between structural elements. This paper also presents a tool that supports the proposed approach. Resumo. A recuperação da documentação sobre a estrutura de um sistema legado visa apoiar sua manutenção. Com esta estrutura é possível entender o sistema e fazer uma análise de impacto de um pedido de mudança. Este artigo mostra uma abordagem para a recuperação de modelos de sistemas legados em PL/SQL. A recuperação se baseia em padrões de busca que extraem as dependências entre elementos estruturais. Este artigo também apresenta uma ferramenta de apoio à abordagem proposta. 1. Introdução Um sistema de software está sempre evoluindo para se adequar a modificações em práticas de negócio organizacionais. Após diversas modificações, o software e a sua documentação vão se tornando mais difíceis de entender. Quanto mais difícil é entender um sistema, mais os desenvolvedores se focam na modificação do software, diminuindo a confiabilidade da documentação existente e dificultando a tarefa de manutenção. Para fazer uma manutenção em um software, é importante que o desenvolvedor realize uma análise de impacto da mudança [Sommerville 2007]. Uma análise de impacto utiliza uma representação da estrutura do sistema para verificar se outras partes do software devem ser modificadas por conta de uma manutenção, buscando minimizar os efeitos colaterais de uma mudança [Wilde and Huitt 1992; Queille et al. 1994]. Porém, a documentação de um sistema legado (incluindo a documentação sobre sua estrutura) tende a perder a confiabilidade ao longo do tempo. Para contornar este problema, pode-se recuperar a estrutura do sistema utilizando engenharia reversa, que se 1
2 preocupa em recuperar a representação arquitetural do sistema a partir do código fonte, permitindo seu entendimento e modernização [Chikofsky and Cross 1990]. O processo de recuperação do modelo da estrutura de um sistema legado pode ser automatizado com uma combinação de ferramentas de análise de código. Porém, a análise de código fonte normalmente não abrange a análise de código que implementa regras de negócio diretamente em sistemas gerenciadores de banco de dados, como código escrito em PL/SQL. Este artigo tem como objetivo apresentar uma abordagem para a recuperação de modelos de sistemas legados em PL/SQL. A Seção 2 apresenta a abordagem, baseada em padrões para extrair informações do código. A Seção 3 mostra uma ferramenta que dá suporte à abordagem proposta. A Seção 4 descreve um exemplo de uso desta ferramenta. A Seção 5 apresenta um exemplo de como a proposta pode auxiliar o desenvolvedor na tarefa de análise de impacto. A Seção 6 apresenta alguns trabalhos relacionados e, finalmente, a Seção 7 apresenta as conclusões. 2. Recuperando a Estrutura de Software O processo de recuperação do modelo da estrutura de software proposto possui as seguintes etapas: (i) encontrar padrões para a extração de informações; (ii) gerar uma ferramenta para extrair do código fonte os padrões criados, e; (iii) gerar os modelos. Um padrão deve buscar uma característica no código e deve ter um objetivo específico no processo de recuperação da estrutura. Neste trabalho, a geração de padrões buscou encontrar os relacionamentos estruturais do sistema, se baseando em um exame da sintaxe da linguagem PL/SQL e nos comandos SQL padrão. No entanto, é importante salientar que o uso de convenções (padrões) de programação é importante para extração de conhecimento a partir de código-fonte. O código produzido utilizando convenções deve ser a marca da equipe, pois serve para que todos os desenvolvedores possam entender completamente o código produzido por qualquer um da equipe. Os padrões propostos por este trabalho, além de verificar a sintaxe PL/SQL e os comandos SQL, se vale de um conjunto de convenções de programação. Assim, foram criados quatro padrões: Padrão 1: padrão para mostrar o relacionamento entre procedimentos (procedures de PL/SQL). Para reconhecer tais relacionamentos é preciso descobrir todos os pacotes e procedimentos existentes no código PL/SQL. Assim, é necessário: (i) eliminar os comentários, expressos com /*... */ ou com --, e; (ii) buscar dados através dos seguintes padrões: PACKAGE/package, procedure e function. Após a identificação dos pacotes e dos procedimentos, as seguintes expressões (convenções de programação) são usadas para recuperar os relacionamentos entre procedimentos: _pkg.<nome_outro_proc>: representa um relacionamento entre um procedimento e o procedimento referenciado em _pkg.<nome_outro_proc>; pacote.procedure: cada palavra do código que atendesse a este padrão foi selecionada e procurada na listagem produzida em (iii). Se a palavra for encontrada na listagem, então um relacionamento entre o procedimento onde o padrão foi recuperado e o procedimento da listagem é adicionado. 2
3 Padrão 2: padrão para mostrar o relacionamento entre procedimentos e tabelas. O padrão definido para extrair estes relacionamentos verifica os comandos que contém as expressões update, delete, select, join, insert e from. Padrão 3: padrão para mostrar o relacionamento entre as tabelas através de chaves estrangeiras. O padrão para extrair estes relacionamentos verifica os comandos que iniciam com alter table e que contém as expressões foreign key e references. Padrão 4: padrão para mostrar as entradas e as saídas dos procedimentos. Este padrão busca por: (i) sentenças PACKAGE/package; (ii) comandos iniciados com as palavras-chaves procedure ou function, e; (iii) comandos contendo as expressões in ou out. Depois da definição dos padrões, uma série de programas AWK [Aho et al. 1988] foi desenvolvida para extraí-los do código fonte. O AWK foi utilizado, pois conta com recursos para encontrar padrões (pattern matching) e para manipulação de expressões regulares. Tais recursos foram determinantes para o sucesso da mineração de relacionamentos descritos nos padrões. Com base no código (transformado em um arquivo de texto) e nos padrões estabelecidos, os programas AWK fazem a engenharia reversa, gerando os arquivos com os dados necessários para se recuperar o modelo da estrutura do sistema. Estes arquivos são organizados para que a ferramenta Dependencies Viewer (Seção 3) possa apresentar graficamente o modelo. 3. A Ferramenta Dependencies Viewer A ferramenta Dependencies Viewer (figura 1) foi desenvolvida para mostrar o modelo da estrutura do software (parte PL/SQL) a partir dos arquivos gerados pelos programas AWK. A ferramenta permite: (i) visualizar os procedimentos e seus relacionamentos (entre si e entre eles e as tabelas), partindo-se de um procedimento específico; (ii) visualizar as tabelas e seus relacionamentos, partindo-se de uma tabela específica, e; (iii) gerar uma imagem com a estrutura para o usuário imprimir. Figura 1. Tela para gerar diagramas de procedimentos. 3
4 A ferramenta oferece quatro opções de visualização do modelo da estrutura a partir da seleção de um procedimento (exemplo da figura 1) ou tabela escolhida pelo usuário: origem; destino; ver tabelas, e; todos os níveis. Marcando a opção Origem a busca dos relacionamentos será a partir do procedimento informado, mostrando um diagrama com as chamadas desta aos outros procedimentos. Marcando a opção Destino significa que o procedimento informado é destino e um diagrama mostrará todos os procedimentos que fazem chamadas a ele. Se a opção Ver Tabelas for selecionada serão apresentadas as tabelas relacionadas ao procedimento. Marcando a opção Todos os níveis, um diagrama, que apresenta o grafo em profundidade, é gerado, mostrando os relacionamentos diretos e indiretos do procedimento. Uma combinação destas opções pode ser realizada, dependendo do nível de detalhe que se busca. Estas opções também são válidas para diagramas de tabelas. A ferramenta possui um modelo bastante simplificado, que transforma a árvore de chamadas de procedimentos e de tabelas em um grafo. Isto facilita na hora de percorrê-lo e de selecionar os nós que devem ser exibidos. O uso de grafos é importante, pois permite a geração de sub-grafos a partir de uma raiz (procedimento) qualquer, selecionada pelo usuário. No exemplo do grafo da figura 2, um usuário pode gerar diversos sub-grafos. Figura 2. Exemplo de um grafo de modelo de estrutura Se o usuário desejar ver os relacionamentos existentes do nó C, ele pode optar por marcar Origem, o que mostrará o sub-grafo C D E. Caso seja escolhida a opção Destino, são selecionados os vértices A B C. Se as duas opções forem marcadas, será exibido o sub-grafo A B C D E. Note que o nó F nunca será adicionado no grafo de C, pois ele não pertence à árvore de chamadas deste nó. As regras apresentadas acima servem tanto para procedimentos como para tabelas, pois os dois são vistos do mesmo modo pela ferramenta. Embora a ferramenta consiga extrair a estrutura de forma simples, algumas dificuldades foram encontradas. Na extração do relacionamento entre procedimentos (padrão 1), dois procedimentos podem ter o mesmo nome e estar no mesmo pacote, sendo diferenciadas pela quantidade e pelos tipos de parâmetros. Neste caso, a ferramenta gera vários relacionamentos para um mesmo procedimento (em vez de gerar dois procedimentos diferentes com o mesmo nome). Outra dificuldade encontrada se refere à extração dos relacionamentos entre procedimentos e tabelas (padrão 2). Em PL/SQL, uma tabela pode estar definida como um tipo, que pode ser utilizado no código apenas como um nome de uma variável. Neste caso, a ferramenta não consegue reconhecer a tabela, perdendo seus relacionamentos. 4
5 4. Prova de Conceito Para mostrar a aplicabilidade da abordagem, a ferramenta foi utilizada para extrair o modelo da estrutura de um sistema legado escrita em PL/SQL, que possui cerca de 150 KLOC e mais de 340 procedimentos. Abaixo, é mostrada a extração de relacionamentos entre procedimentos e entre procedimentos e tabelas e a geração do grafo. O código 1 mostra um trecho do código do procedimento update_scenarium que possui um relacionamento com uma tabela cenário. procedure UPDATE_SCENARIUM (...) is... begin Código 1. Trecho I do procedimento update_scenarium select ce.cena_nr_numero_cenario, ce.cena_dt_criacao into scena_cd_id, creation_date from cenario ce where ce.cena_nr_numero_cenario = to_number(scenarium_id.identifier);... end; O trecho marcado acima mostra o código que indica um relacionamento entre o procedimento e a tabela. A ferramenta encontra o código a partir do padrão 2 e gera o trecho mostrado na figura 3 no arquivo da estrutura. Figura 3. Trecho gerado pela aplicação do padrão 2 O código 2 mostra um trecho do código do procedimento update_scenarium que possui um relacionamento com outros procedimentos. procedure UPDATE_SCENARIUM (...) is... begin... Código 2. Trecho II do procedimento update_scenarium if open_stock.count > 0 then update_open_stock(open_stock); end if; if delivery.count > 0 then update_delivery(delivery); end if;... if fcc_processing.count > 0 then end; O trecho marcado no código 2 mostra o código que indica um relacionamento entre update_scenarium e update_open_stock e update_delivery. Estes trechos são 5
6 encontrados pela ferramenta a partir do padrão 1. O arquivo gerado (parcial) após o processamento do código está mostrado na figura 4 (se o procedimento é chamado várias vezes, há repetição; no entanto, isto é filtrado posteriormente). Figura 4. Trecho gerado pela aplicação do padrão 1 Atualmente um arquivo.jar pode ser criado para fazer todo o processo de geração dos arquivos extraídos do código de forma automática permitindo atualização rápida dos modelos de acordo com a evolução de versões do software. Depois de aplicar todos os padrões, a ferramenta gera o seguinte grafo de relacionamentos para o procedimento update_scenarium (figura 5). Figura 5. Modelo recuperado da estrutura do procedimento update_scenarium 5. Análise de Impacto A ferramenta Dependencies Viewer auxilia o desenvolvedor a fazer uma análise de impacto de um pedido de mudança. A figura 6 mostra um cenário de uso da ferramenta. Imagine que um desenvolvedor, atendendo a um pedido de mudança, saiba que será necessário modificar um procedimento (neste exemplo, chamada de get_scenarium). O desenvolvedor usa a ferramenta para saber se existem outros procedimentos que chamam o procedimento em questão, encontrando o procedimento open_scenarium (figura 6.1). Neste ponto, o desenvolvedor pode recuperar os procedimentos diretamente relacionados ao procedimento open_scenarium (figura 6.2). Caso seja necessário, o desenvolvedor pode verificar se existem outras chamadas em maiores níveis de profundidade opção Todos os níveis para open_scenarium (figura 6.3). Esta verificação apresenta diversos relacionamentos. O retângulo cinza representa o procedimento utilizado para a busca (na parte superior está o nome do pacote e na parte inferior o nome do procedimento). Além da análise dos relacionamentos entre procedimentos, é possível analisar as tabelas associadas a cada procedimento impactado. Estes diagramas mostram um mapa da implementação. Em alguns casos, pode haver muitos caminhos e, quando se tem pouco conhecimento sobre o software, o esforço para a análise é bem maior. Informações associadas a cada procedimento/tabela (semelhante a um Javadoc) ajudam no entendimento das funções de cada um destes elementos. 6
7 Figura 6. Navegando nos diagramas para realizar a análise de impacto. 6. Trabalhos Relacionados Para a linguagem Java e a notação UML, existe um conjunto de ferramentas similares, como o Together [Borland 2009], e o Rational Software Architect [IBM 2009a]. Para a exibição do comportamento e chamadas da aplicação, normalmente o diagrama exibido é o diagrama de seqüência. Todas estas ferramentas possuem a opção de geração de diagramas a partir da análise estática de um código Java. No entanto, estas ferramentas não provêem suporte para outras linguagens. O mais próximo disto é a funcionalidade de importação de um XMI. Para produtos específicos para desenvolvimento focado em banco de dados, existe a ferramenta Rational Data Architect [IBM 2009b], que provê diversas funcionalidades de geração de diagramas a partir da estrutura do SGBD. Todas, porém, são focadas na organização das tabelas. Para desenvolvimento e manutenção de procedimentos, a única funcionalidade é o destaque com cor das palavras chaves. Outras ferramentas, específicas para determinados bancos, fornecem um suporte melhor. O SqlDeveloper [Oracle 2009] provê um editor que completa palavras e marca com cores as palavras chaves do procedimento. Assim, ele exibe quais os procedimentos chamados e as tabelas utilizadas textualmente a partir do procedimento que está sendo editado 7
8 naquele momento. Porém, apenas o primeiro nível é exibido, e não toda a árvore de chamadas, além de não existir a possibilidade de exibição e geração de um diagrama. 7. Conclusão A manutenção de um sistema legado pode ser facilitada quando se aplica algumas práticas de engenharia reversa. Uma delas é a recuperação do modelo de sua estrutura. Para recuperar o modelo da estrutura de um software legado, desenvolvido em PL/SQL, este trabalho propõe o uso de padrões para o reconhecimento de procedimentos, tabelas e seus relacionamentos no código fonte. Para dar suporte ao uso automatizado destes padrões, foi desenvolvida a ferramenta Dependencies Viewer que permite a recuperação do modelo da estrutura de um sistema legado para contribuir na tarefa de análise de impacto de uma mudança. Como trabalhos futuros, é preciso avaliar os padrões e a ferramenta em outros estudos de caso, com o intuito de aperfeiçoar a detecção dos padrões no código fonte. Além disso, seria interessante incrementar a ferramenta para permitir a visualização de outras informações como os parâmetros de entrada e saída dos procedimentos. Novos padrões podem ser desenvolvidos e tais padrões deverão ser incorporados à ferramenta. Neste sentido, já está em desenvolvimento um padrão para mostrar os comentários dos procedimentos. Este padrão extrai os comentários do código, buscando os caracteres de início e fim de comentário dentro do PL/SQL ( /* e */ ). Logo, o Dependencies Viewer poderá auxiliar o desenvolvedor, apresentado a documentação de um procedimento selecionado para ajudar na tarefa de análise de impacto de mudança. Referências Aho, A. V., Kernighan B. W. and Weinberger, P. J. (1988). The AWK Programming Language, Addison Wesley. Borland (2009). Borland Together. Disponível em: products/together/. Acessado em: 30 Mar Chikofsky, E. J. and Cross, J. H. (1990). Reverse engineering and design recovery: a taxonomy. IEEE Software 7(1), p IBM (2009a). Rational Software Architect. Disponível em: software/awdtools/architect/swarchitect/. Acessado em: 30 Mar IBM (2009b). Rational Data Architect. Disponível em: software/awdtools/modelbundle/. Acessado em: 30 Mar Oracle (2009). Oracle SQL Developer. Disponível em: technology/products/database/sql_developer/. Acessado em: 30 Mar Queille, J., Voidrot, J., Wilde, N. and Munro, M. (1994). The impact analysis task in software maintenance: a model and a case study. In: Proceedings of the International Conference on Software Maintenance, p Sommerville, I. (2007). Engenharia de Software, Pearson Education, 8th edition. Wilde, N. and Huitt, R. (1992). Maintenance support for object oriented programs. In: Proceedings of the International Conference on Software Maintenance, p
5 Avaliação experimental 5.1. Cenário
73 5 Avaliação experimental 5.1. Cenário No capítulo 1, seção 1.2, foi apresentado o cenário deste estudo de caso que motivou esta dissertação. Fazendo uma recapitulação, tudo se iniciou numa parceria