Usando Componentes no LumisXP

Introdução

Tipicamente em serviços customizados será criado uma tabela no banco de dados para armazenamento de dados. Este artigo irá abordar como tais tabelas podem ser criadas, atualizadas e excluídas através de componentes e em quais arquivos você deve alterar para cada caso. Também será explicitado a diferença fundamental do upgrade x install e a utilização do databasedefinition.xml. Por fim, será explicado uma forma de você utilizar os componentes para realizar deploy de recursos estáticos no apache, um recurso interessante e útil para projetos em angular/react/vue ou que utilizam pwa.

Definição de componentes

Componentes são partes de uma aplicação instaláveis (através de módulos), ou até mesmo de uma aplicação completa, que podem conter:

  • Serviços
  • Temas
  • Contextos de negócio
  • Observadores
  • Arquivos públicos
  • Estrutura

Um componente deve, necessariamente, pertencer a um módulo. Dada uma estrutura de pastas e arquivos pertencentes a um dado módulo, um componente é demarcado por um arquivo de definição de componentes. Toda a árvore a partir da pasta que contém o arquivo pertence a esse componente, a menos as subpastas que também contém arquivos de definição de componentes. Nesse último caso, um outro componente é definido.

Neste artigo, iremos criar um componente que será responsável pela criação, atualização e remoção de tabelas do nosso serviço customizado. Para isso, devemos criar um arquivo chamado componentdefinition.xml na raiz do nosso serviço customizado

<?xml version="1.0" encoding="UTF-8"?>
<lumis-component xmlns="http://www.lumis.com.br/lumisportal/xsd/component" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.lumis.com.br/lumisportal/xsd/component http://www.lumis.com.br/lumisportal/xsd/component">
	<version>1.0.0.0</version>
	<description>Esta é a descrição do nosso serviço customizado</description>
</lumis-component>

Estrutura de arquivos padrão

Para criar uma tabela em um serviço customizado você deve ter basicamente a seguinte estrutura:

unnamed.png

component-install-script.xml

Responsável por realizar a criação de todas as tabelas do serviço. É importante frisar que o LumisXP irá executar as queries definidas neste arquivo somente na instalação do componente. Exemplo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Revision: 16445 $ $Date: 2014-09-18 21:21:12 +0000 (Thu, 18 Sep 2014) $ -->
<component-install xmlns="http://www.lumis.com.br/lumisportal/xsd/component-install-script" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<run-sql>
		<sql>
			CREATE TABLE my_custom_table
			(	
				id					CHAR(32) NOT NULL PRIMARY KEY,
				title 				VARCHAR(255) NOT NULL,
				description			VARCHAR(500)
			) 
		</sql>
	</run-sql>
</component-install>

component-upgrade-script.xml

Responsável por realizar criação de novas tabelas e alterações de tabelas já existentes após o componente já ter sido instalado. O LumisXP irá executar os steps desse arquivo na atualização do componente. Exemplo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Revision: 16582 $ $Date: 2014-11-07 13:18:31 +0000 (Fri, 07 Nov 2014) $ -->
<component-upgrade xmlns="http://www.lumis.com.br/lumisportal/xsd/component-upgrade-script" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<display-message step="1">
		<message>Ok</message>
	</display-message>
	<run-sql step="2">
		<sql>
			ALTER TABLE my_custom_table ADD COLUMN priority int(11) DEFAULT NULL;
		</sql>
	</run-sql>
</component-upgrade>

component-uninstall-script.xml

Responsável por realizar a remoção das tabelas criadas pelo serviço. O LumisXP irá executar os comandos deste arquivo na desinstalação do componente. Exemplo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Revision: 16445 $ $Date: 2014-09-18 21:21:12 +0000 (Thu, 18 Sep 2014) $ -->
<component-uninstall xmlns="http://www.lumis.com.br/lumisportal/xsd/component-uninstall-script" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<run-sql>
		<sql>drop table my_custom_table</sql>
	</run-sql>
</component-uninstall>

Tudo que o componente criar no component-install-script.xml deve ser removido neste arquivo.

Databasedefinition.xml

Uma boa prática no arquivo component-install-script.xml é associá-lo ao arquivo databasedefinition.xml como demonstrado abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Revision: 16445 $ $Date: 2014-09-18 21:21:12 +0000 (Thu, 18 Sep 2014) $ -->
<component-install xmlns="http://www.lumis.com.br/lumisportal/xsd/component-install-script" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<execute-database-file>
		<file>databasedefinition.xml</file>
	</execute-database-file>
</component-install>

O databasedefinition.xml que irá criar a mesma tabela "my_custom_table" pode ser criado da seguinte forma:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- $Revision: 16445 $ $Date: 2014-09-18 21:21:12 +0000 (Thu, 18 Sep 2014) $ -->
<databaseDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.lumis.com.br/lumisportal/xsd/databasedefinition.xsd">
	
	<table name="my_custom_table">
		<fields>
			<field name="id" type="guid" isNotNull="true"/>
			<field name="title" type="string" isNotNull="true"/>
			<field name="description" type="string" size="500"/>
		</fields>
		<constraints>
			<constraint name="my_custom_table_PK" type="primaryKey">
				<fields>
					<field name="id"/>
				</fields>
			</constraint>
		</constraints>
	</table>
	
</databaseDefinition>

Esse arquivo é uma especificação de como a tabela deve ser criada. Ou seja, ao invés de utilizar um comando SQL como feito no component-install-script.xml anteriormente, você irá definir a tabela utilizando um padrão de tags XML que serão interpretadas e processadas pelo LumisXP para realizar a criação de tabelas.

O principal benefício desta utilização é que o LumisXP ao processar este arquivo irá criar as tabelas considerando o banco configurado no lumishibernate.cfg.xml. Portanto a sintaxe definida aqui não está relacionada a nenhum banco de dados e ao ser processada será criada como o padrão do banco utilizado. Por exemplo, teríamos um problema se a tabela criada diretamente no component-install-script.xml criasse uma coluna de um tipo que só existe no MySQL, se precisássemos trocar de banco de dados teríamos que reescrever o create desta tabela.

Dessa forma, seu serviço customizado deve incluir a seguinte estrutura:

unnamed _1_.png

Upgrade x Install

Considere a seguinte situação hipotética: Um desenvolvedor criou um componente com a estrutura de arquivos padrões descritas acima, mas considerando que o component-upgrade-script.xml ainda não possui nenhum step definido. Ele realiza o deploy deste novo componente no ambiente de desenvolvimento e o LumisXP irá executar o component-install-script.xml criando as tabelas.

Em seguida foi identificado um bug que exigiu que fosse criado uma nova coluna "prioridade" no banco de dados. Nesta situação, o desenvolvedor irá adicionar um step no arquivo component-upgrade-script.xml para adicionar tal coluna. Após isso, ele irá realizar o deploy novamente no ambiente de desenvolvimento e o LumisXP irá executar o component-upgrade-script.xml que irá atualizar a tabela incluindo a nova coluna. Neste momento, é importante relatar como o LumisXP sabe que no próximo deploy ele não deve executar tal step. Na tabela lum_decomponent que armazena todos os componentes existe uma coluna chamada lastUpgradeStepExecuted que armazena o último step executado.

Por fim, com a demanda validada, o desenvolvedor realiza o deploy em produção. Neste momento ocorre uma situação interessante, conforme dito anteriormente, o componente será instalado em produção e o arquivo a ser executado será component-install-script.xml. Contudo, o arquivo component-upgrade-script.xml não foi executado. Então nosso banco será criado sem a coluna "prioridade"? A resposta é não, isso porque assume-se que a atualização que você colocou em component-upgrade-script.xml esteja presente no databasedefinition.xml. Sendo assim, a nova coluna prioridade também deveria estar no arquivo de criação das tabelas. Por esta premissa, o LumisXP ao executar o install irá criar o componente salvando-o em tabela com o valor da coluna lastUpgradeStepExecuted preenchido com 2, pois foi considerado que a instalação já ocorreu com a estrutura mais atualizada.

Gerando script a partir do databasedefinition.xml

A partir do databasedefinition.xml é possível visualizar o script que o LumisXP irá gerar. Por exemplo, no eclipse clique com o botão direito neste arquivo Run as / XSL Transformation e clique em Add Files. Selecione lumisportal/setup/bin/lumis/database/<arquivo do banco utilizado>. Isso irá gerar um arquivo com o script de criação considerando o banco escolhido.

Utilizando componentes para realizar deploy de recursos estáticos no apache

Geralmente os arquivos estáticos ficam contidos dentro da pasta tema do projeto. Ao atualizar o módulo deste projeto, o LumisXP irá transferir os estáticos do tema para <diretorio-estático>/lumis-theme/<diretório-tema>. Mas existem algumas situações em que se deseja incluir arquivos na raiz do apache. Por exemplo, se a aplicação for PWA você precisará que o service work possua escopo de todos os recursos que irão ser gerenciados por este. Nesta situação, caso o arquivo esteja na raiz do apache, o escopo deste service work será a pasta atual e todas as suas subpastas, ou seja, o apache inteiro.

Referência: https://pt.stackoverflow.com/questions/291937/escopo-de-service-worker

Para isso podemos utilizar os componentes da seguinte forma:

unnamed _2_.png

Tudo que estiver dentro do diretório componentfiles.www será realizado deploy posteriormente na raiz do apache.

Autor: Rodrigo Santana