Categorias
Arquitetura Engenharia de Software Java

usa Jenkins e não encontrou o que precisa? Faça o seu plugin!

Não consigo imaginar hoje um projeto em Java com qualidade que não tenha o Jenkins para garantir a integração continua com robustez e determinação.

jenkinsLogo1

Recentemente participei de primeiro encontro de Jenkins do Brasil, e além da presença do Bruno Kinoshita que falou de como criar um plugin para o Jenkins e do Tony Lâmpada sobre o Liquibase (a palestra dele toda feita em giz de cera foi uma das melhores que já vi, ele mesmo comentou que demorou quase um mês para desenhar tudo) , contamos com a participação ilustre de nada mais nada menos que o criador do Jenkins, o Kohsuke Kawaguchi.

O Kohsuke é um cara que foge ao padrão dos “japas tradicionais”… pra começar ele é gigante, tem dois metros de altura… ele viu minha camiseta de 25 anos do Metal Gear para MSX e comentou: “ah, eu não tinha um desses, mas morava do lado de uma loja cheia de jogos para MSX“.

Mas foi quando começou a palestra dele que a plateia ficou na dúvida… quem está falando agora, é o Kohsuke ou o Pavarotti ?

kohsuke-ou-pavarotti

Aqui tem a lista completa dos vídeos das palestras do Jenkins Meetup São Paulo.

Depois da palestra do Bruno eu tentei criar um plugin e consegui sem muita complicação.
A ideia é testar o tempo de conexão ao banco de dados (Oracle,MySQL, SQL Server), que pode ser exibida, por exemplo, antes de um build ou um de rodar os testes.

Para você criar o seu plugin, siga o tutorial que é bem tranquilo, mas vou usar o meu como exemplo.

Eu comecei usando o site do gerado de plugin… acessei, escolhi o nome database-connection-speed e cliquei em Generate. Depois de poucos segundos foi gerado um zip com o projeto de exemplo de plugin inteiro, basta eu descompactar dentro do workspace do Eclipse.

O segundo passo foi rodar o plugin… aí com o Maven facilitou bastante, não preciso instalar nada na minha máquina, o que eu preciso fazer é ir no diretório do projeto e rodar: mvn clean install hpi:run , ele baixará todas as dependências necessárias para rodar o Jenkins local.

Todo plugin que você usa tem as configurações globais e as específicas de cada job, certo?

No seu plugin, o Jenkins utiliza o framework Jelly para trabalhar com essas informações.

No meu exemplo, essa tela de configuração geral:

dcs-config-gerais

É representada por esse XML:

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
  <f:section title="Database Connection Speed Test">
    <f:entry title="detalhes" field="detalhes"
      description="Exibir acesso ao banco de dados com detalhes">
      <f:checkbox />
    </f:entry>
  </f:section>
</j:jelly>

E essas configurações de cada job:

dcs-config-do-job

São representadas por esse XML:

 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
  <f:entry name="dbType" title="Tipo de banco de dados" field="dbType">
    <select name="dbType">
        <option value="mysql">MySQL</option>
        <option value="oracle">Oracle</option>
        <option value="sqlserver">SQL Server</option>
    </select>
</f:entry>
  <f:entry title="url" field="url">
    <f:textbox />
  </f:entry>
  <f:entry title="usuario" field="usuario">
    <f:textbox />
  </f:entry>
  <f:entry title="senha" field="senha">
    <f:password />
  </f:entry>
</j:jelly>

Então, só falta ler esses valores e mostrar o resultado.
Tudo isso é feito na classe abaixo, os valores entram pelo construtor e no método perform você implementa o que o seu plugin realmente faz:

    ...

@DataBoundConstructor
public ConnectionTestBuilder(String dbType,String url,String usuario,String senha) {
    this.dbType = dbType;
    this.url = url;
    this.usuario = usuario;
    this.senha = senha;
}

...

@Override
public boolean perform(AbstractBuild build,Launcher launcher,BuildListener listener) {

    try {
        TestConnection.inicia(url,usuario,senha,dbType,getDescriptor().getDetalhes(),listener);
        listener.getLogger().println(" Tempo: " + TestConnection.diff() + " milisegundos  ");
        TestConnection.finaliza();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return true;
}

Disso temos o resultado sem detalhes:

dcs-job-sem-detalhes

E com detalhes:

dcs-job-com-detalhes

Todo o código do plugin está disponível no github.

Uma observação: como a licença do driver da Oracle não é livre, ela não pode ficar em nenhum repositório na Internet, você precisa baixar o driver (ojdbc6.jar) e depois instalar em seu repositório local com o comando:

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.3 -Dpackaging=jar -Dfile=ojdbc6.jar -DgeneratePom=true

 

Fernando Boaglio, para a comunidade =)