Objetivo
Esse documento tem como objetivo principal mostrar como funciona o processo de empacotamento de uma versão do Storex Custom.
Para isso vamos precisar falar um pouco sobre o Application Updater, que é utilizado para distribuir e aplicar o pacote de atualização nas lojas e componentes. Vamos falar também sobre o Apache Maven, que é utilizado para fazer o empacotamento da versão a ser distribuída.
Application Updater
O Application Updater é o responsável por realizar as atualizações de versões dos componentes do Storex. Ele sempre é executado localmente no processo de inicialização dos componentes e tem como objetivos verificar se existe alguma versão a ser aplicada e, ao localizar um novo pacote, realizar a atualização da versão.O pacote é um arquivo de extensão PKG, que fica localizado dentro de p2k/bin/downloads. O Application Updater realiza o desempacotamento desse arquivo e em seguida move os arquivos, que estão dentro dele, para seus devidos lugares.
Arquivo PKG Para que o Application Updater reconheça o arquivo PKG como válido, ele precisa conter um arquivo XML chamado update e uma pasta chamada filetypes. Conforme imagem ao lado: Arquivo update.xml O arquivo update.xml contem as informações a respeito do pacote de atualização. Segue um exemplo ao lado: A tag <id> identifica o tipo do componente ao qual o pacote de atualização corresponde. Esse exemplo é de um pacote de atualização para os PDVs das lojas. No caso do pacote do EP, essa mesma tag ficaria <id>LINX-STOREX-EP</id>. A tag <version> possui o número da versão que será aplicada no componente. Pasta filetypes Dentro de filetypes temos as pastas other e properties. A pasta other contem todos os arquivos que serão atualizados dentro de /p2k. A pasta properties contem os arquivos de extensão .properties com as property keys que serão atualizadas. A pasta other contém todos os arquivos que serão copiados para dentro da pasta indicada na tag <rootPath> que existe no arquivo update.xml. Nesse caso, o rootPath é /p2k. Dentro de other/overwrite temos as pastas: bin, lib e temp. Todo o conteúdo da pasta bin será copiado para a pasta /p2k/bin do componente. Ou seja, o que existir será sobrescrito. A mesma coisa vai acontecer para o conteúdo das pastas lib e temp. Na pasta properties existem as pastas delete-key e update-key. Elas armazenam os arquivos .properties que serão atualizados na aplicação. Essa atualização é feita à nível das keys, ou seja, o Application Updater não sobrescreve os arquivos. Primeiro é realizada a remoção de cada uma das property key existentes dentro dos arquivos da pasta delete-key. Em seguida ele atualiza todas as property key existentes nos arquivos que estão dentro da pasta update-key. Atenção: Não recomendamos mais o uso de arquivos properties para manutenção de parâmetros. O caminho recomendado é a utilização do servidor de configurações. Dentro de delete-key encontramos os arquivos que serão utilizados para fazer a exclusão das parametrizações que não serão mais utilizadas. Mais abaixo vamos citar um exemplo. Como exemplo vamos olhar o conteúdo do arquivo motivosCancelamento.properties, que está dentro da pasta delete-key. O processo de atualização vai procurar pelo arquivo motivosCancelamento.properties que existe dentro do caminho /p2k/bin. Vai localizar cada uma das linhas que começam com as keys acima e vai removendo uma a uma do arquivo original. Assumindo que o arquivo motivosCancelamento.properties atual, que está dentro da pasta /p2k/bin, contenha o seguinte conteúdo: Após a execução do processo de atualização o arquivo, que está dentro da pasta /p2k/bin, motivosCancelamento.properties ficará com o seguinte conteúdo: | Conteúdo do update.xml <application> <id>PDV</id> <vendor>LINX</vendor> <description>POS</description> <version>2.18.0.22</version> <rootPath>..</rootPath> <packageInfo> <allowRollback>false</allowRollback> <type>full</type> </packageInfo> </application> Conteúdo de motivosCancelamento.properties ANULACAO_3 DEVOLUCAO_3 CANCELAMENTO_3 motivosCancelamento.properties antes da exclusão das keys DEVOLUCAO_3=Troca por defeito DEVOLUCAO_2=Troca por modelo DEVOLUCAO_1=Troca por Tamanho CANCELAMENTO_3=Cartão não autorizado/sem limite CANCELAMENTO_2=Desistência da compra CANCELAMENTO_1=Erro Operacional ANULACAO_3=Desistência da compra ANULACAO_2=Alteracao Forma de pagamento ANULACAO_1=Erro Operacional motivosCancelamento.properties após a exclusão das keys DEVOLUCAO_2=Troca por modelo DEVOLUCAO_1=Troca por Tamanho CANCELAMENTO_2=Desistência da compra CANCELAMENTO_1=Erro Operacional ANULACAO_2=Alteracao Forma de pagamento ANULACAO_1=Erro Operacional |
Apache Maven
O Storex Custom utiliza o projeto Apache Maven para organizar e automatizar o processo de build e que é utilizado para gerar o pacote final de distribuição. O Maven utiliza o arquivo pom.xml que fica na raiz do projeto, para realizar essa execução.
Entendendo o arquivo pom.xmlO arquivo POM (Project Object Model), presente no diretório-raiz do projeto, contém todas as informações que o Maven necessita para interagir corretamente com o projeto. Ele utiliza o formato XML e relaciona todas as dependências, repositórios e faz o detalhamento da estratégia de build do projeto. Repositório MavenLocal central onde o Maven vai buscar todos os artefatos necessários para o build do projeto. No caso do Storex Custom, os projetos utilizam um repositório remoto. O mesmo encontra-se configurado no pom.xml dos projetos, conforme exemplo ao lado: Adicionando dependênciasNo arquivo POM.xml podemos definir quais são as dependências necessárias ao projeto. Portanto, se quisermos adicionar uma nova biblioteca que será utilizada no projeto, basta irmos no nosso POM.xml e adicionar uma dependência (dependency) dentro das nossas dependecies especificando o groupId, artifactId e a version. Conforme exemplo ao lado: Processo de BuildApós todas as dependências estarem configuradas e serem gerenciadas pelo Maven, podemos iniciar o processo de build. O processo de build segue algumas fases (indicada pela tag <phases>) desde limpar o diretório de destino do projeto (initialize), compilar (compile), executar algumas ações antes de empacotar (prepare-package), até chegar na etapa de empacotar o projeto (package). Todas as fases seguidas no processo de build, possuem seus respectivos plugins e dentro do arquivo pom.xml podemos encontrá-los dentro da tag representada ao lado. Fase initializeO primeiro passo da execução do Build é a limpeza do diretório de compilação, ou seja, do diretório destino para onde os arquivos serão copiados. Isso é executado pelo plugin <artifactId>maven-clean-plugin</artifactId>. Nele está configurado o diretório de destino que deve estar limpo antes de iniciar a fase prepare-package. Fase prepare-packageEssa fase tem o objetivo de realizar quaisquer operações necessárias para preparar um pacote antes do empacotamento propriamente dito. Nessa etapa todas as dependências que estão relacionadas na tag <dependencies> serão copiadas para a pasta lib do diretório de destino do projeto. Além disso, será escrito o conteúdo no arquivo update.xml que fará parte do pacote final. Ao lado, podemos ver os plugins responsáveis por fazer a cópia das dependências e escrever o conteúdo do arquivo update.xml. Fase packageEssa é a etapa onde ocorre a geração do pacote. Nela são seguidas as seguintes etapas:
Ao lado, podemos ver os plugins configurados para realizar a compilação do projeto e gerar o arquivo .jar do componente que será colocado dentro do pacote de final. Ao lado, podemos ver o plugin configurado para fazer a cópia do arquivo jar para dentro da pasta /lib que fica no diretório de build do projeto. Além disso, ele também extrai do .jar do projeto Standard o xml de configuração e salva na pasta. Ao lado, podemos ver o plugin configurado para preparar o arquivo XML com toda a parametrização do componente para ser submetida ao servidor de configurações. Ele faz um merge entre o arquivo XML de configuração do Standard, extraído no passo anterior, com o arquivo de configuração do projeto do cliente.
Depois dessa criação, ele move todos os arquivos que farão parte do pacote, para dentro dos respectivos diretórios. Ao finalizar, ele faz a compactação do diretório raiz do pacote, gerando um arquivo .zip. Em seguida ele muda a extensão do arquivo de .zip para .PKG. Finalizando assim a criação do pacote que será distribuído para as lojas e componentes. | Repositório remoto das dependências <repositories> <repository> <id>maven-group</id> <url>http://a-srvrec013:8081/repository/maven-public</url> </repository> </repositories> Tag dependency <dependencies> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.7</version> </dependency> </dependencies> Tag build onde encontramos os plugins <build> <plugins> <!-- local do POM.xml onde são configurados os plugins que serão executados no processo de build --> </plugins> </build> Plugins executados na fase initialize <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>auto-clean</id> <phase>initialize</phase> <goals> <goal>clean</goal> </goals> </execution> <execution> <id>limpa-diretorio-compilacao</id> <phase>initialize</phase> <goals> <goal>clean</goal> </goals> <configuration> <filesets> <fileset> <directory>${project.dist.dir}/</directory> </fileset> </filesets> </configuration> </execution> </executions> </plugin> Plugins executados na fase prepare-package <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.1.1</version> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <groupId>ru.yaal.maven</groupId> <artifactId>write-text-files-maven-plugin</artifactId> <version>1.1</version> <configuration> <charset>${project.build.sourceEncoding}</charset> <files> <file> <path>${project.build.directory}/${pkg.dir.name}/update.xml</path> <lines> <line><application></line> <line><id>PDV</id></line> <line><vendor>LINX</vendor></line> <line><description>POS</description></line> <line><version>${update.xml.componente.version}</version></line> <line><rootPath>..</rootPath></line> <line><packageInfo></line> <line><allowRollback>false</allowRollback></line> <line><type>full</type></line> <line></packageInfo></line> <line></application></line> </lines> </file> </files> </configuration> <executions> <execution> <id>write-text-files</id> <phase>prepare-package</phase> <goals> <goal>write-text-files</goal> </goals> </execution> </executions> </plugin> Plugins compiler e geração do jar <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <configuration> <archive> <addMavenDescriptor>true</addMavenDescriptor> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> </archive> </configuration> <executions> <execution> <phase>package</phase> </execution> </executions> </plugin> Move o arquivo .jar para diretório de build <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-artifact</id> <phase>package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${project.version}</version> <type>jar</type> <overWrite>true</overWrite> <outputDirectory>${project.build.directory}/lib</outputDirectory> </artifactItem> </artifactItems> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> </configuration> </execution> <execution> <id>unpack</id> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>linx</groupId> <artifactId>${linx-storex-pos-standard.artifactId}</artifactId> <version>${linx-storex-pos-standard.version}</version> <outputDirectory>${basedir}/configuracao/padrao/servidor-configuracao/xml/</outputDirectory> <includes>**/*.xml</includes> </artifactItem> </artifactItems> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>true</overWriteSnapshots> </configuration> </execution> </executions> </plugin> Prepara o arquivo XML com parametrizações <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>xslt-maven-plugin</artifactId> <executions> <execution> <id>merge-faces-config</id> <phase>package</phase> <goals> <goal>transform</goal> </goals> <configuration> <xslFile>${basedir}/configuracao/padrao/servidor-configuracao/xml/mergeConfig.xsl</xslFile> <srcDir>${basedir}/configuracao/padrao/servidor-configuracao/xml/</srcDir> <destDir>${project.dist.dir}/</destDir> <srcIncludes>linx-storex-pos-custom-config.xml</srcIncludes> <fileNameRegex>linx-storex-pos-custom-config</fileNameRegex> <fileNameReplacement>${project.artifactId}-config-${project.version}</fileNameReplacement> </configuration> </execution> </executions> </plugin> Plugin que gera o arquivo final PKG <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>cria-estrutura-pkg</id> <phase>package</phase> <configuration> <target> <!-- Gerando o bootstrap.jar --> <property name="version" value="${project.version}" /> <property name="project.build.directory" value="${project.build.directory}" /> <property name="compilacao.libs" value="${project.build.directory}/lib" /> <property name="compilacao.completo.build" value="${project.build.directory}/classes" /> <property name="storex-pos-custom.artifactId" value="${project.artifactId}" /> <property name="storex-pos-custom.version" value="${project.version}" /> <property name="storex-pos-gui-custom.artifactId" value="${pos-gui-custom.artifactId}" /> <property name="storex-pos-gui-custom.version" value="${pos-gui-custom.version}" /> <property name="storex-pos-standard.artifactId" value="${linx-storex-pos-standard.artifactId}" /> <property name="storex-pos-standard.version" value="${linx-storex-pos-standard.version}" /> <property name="application.bin" value="../bin/" /> <property name="application.config" value="../config/" /> <property name="bootstrap.version" value="${bootstrap.version}" /> <ant antfile="build/build-bootstrap.xml" /> <!-- INICIO DA GERACAO DO PKG --> <!-- OVERWRITE --> <!-- Copiando as libs --> <copy todir="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/lib"> <fileset dir="${project.build.directory}/lib/"> <include name="**"/> <exclude name="${jython.name}-${jython.version}.jar"/> </fileset> </copy> <!-- Renomeando lib do bootstrap --> <move file="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/lib/linx-bootstrap-${bootstrap.version}.jar" tofile="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/lib/linx-bootstrap.jar" /> <!-- Copiando os resources --> <copy todir="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/bin/statemachine"> <fileset dir="${project.resources.dir}/statemachine/" includes="**" /> </copy> <!-- Versão PDV --> <echo file="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/bin/versaoPDV.dat" message="${update.xml.componente.version}" /> <!-- Copiando a estrutura de dominios --> <copy todir="${project.build.directory}/${pkg.dir.name}/${pkg.overwrite.path}/bin/dominios"> <fileset dir="${project.resources.dir}/configuracao/dominios/" includes="**" /> </copy> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> <execution> <id>zipando-pkg</id> <phase>package</phase> <configuration> <target> <!-- Copiando e gerando o PKG --> <zip destfile="${project.build.directory}/${pkg.dir.name}.zip" basedir="${project.build.directory}/${pkg.dir.name}" /> <copy file="${project.build.directory}/${pkg.dir.name}.zip" tofile="${project.dist.dir}/${project.build.finalName}.pkg" /> <delete file="${project.build.directory}/${pkg.dir.name}.zip" /> <!-- FIM DA GERACAO DO PKG --> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> |