Retornando valores entre jobs

Neste pequeno tutorial vou demonstrar como retornar valores de jobs “filhos” utilizando o componente tRunJob sem “fluxo de dados”, ou seja, sem utilizar o schema deste componente.

A passagem de parâmetros entre jobs no Talend é feita através de variáveis de contexto. Geralmente os parâmetros do job pai são transferidos para o job filho e quando este precisa retornar algo, são dados cujos metadados são definidos no schema do componente tRunJob. Na forma como foi implementado, o Talend possibilita transferir parâmetros do job pai para o filho através de variáveis de contexto, mas não o contrário. Também não é possível transferir parâmetros entre jobs através do globalMap, pois cada job possui sua própria área de globalMap.

Porém, algumas vezes você pode desejar retornar valores de um job filho que não estão necessariamente em um fluxo de dados. Como fazer isso?

Vamos criar dois jobs de exemplo para demonstrar como retornar valores de subjobs:

Em ambos os jobs, defina uma variável de contexto com tipo Object, vamos chamá-la aqui de SUBJOB_CONTEXT.

pass_param_subjob (1)

Vamos começar pelo job filho. Adicione um componente tJava ao mesmo, e na guia Advanced adicione as seguintes linhas para importar as bibliotecas necessárias:

import java.util.Map;
import java.util.HashMap;

pass_param_subjob (2)

Ainda no componente tJava, na guia Basic, adicione as seguintes linhas:

//Imprime o parâmetro recebido do job pai
System.out.println("param=" + ((Map<String, String>)context.SUBJOB_CONTEXT).get("param"));

//Define uma nova variável, denominada "retVal" e atribui o valor "Ok" à mesma
((Map<String, String>)context.SUBJOB_CONTEXT).put("retVal", "Ok");

pass_param_subjob (3)

O job filho está concluído. Salve.

Agora no job pai, acrescente um componente tJava, importe as mesmas bibliotecas Map e HashMap, conforme no job filho e na guia Basic acrescente as seguintes linhas:

//Instancia um HashMap na variável de contexto definida
context.SUBJOB_CONTEXT = new HashMap<String, String>();

//E então atribui "valor" à uma chave denominada "param" (poderia ter qualquer nome, funciona exatamente como o globalMap)
((Map<String, String>)context.SUBJOB_CONTEXT).put("param", "valor");

pass_param_subjob (6)

Agora arraste o job filho do repositório para o job pai e no campo “Context Param” lembre-se de acrescentar à variável SUBJOB_CONTEXT e atribuir o valor context.SUBJOB_CONTEXT à mesma. Neste exemplo você pode optar também por marcar a opção “Transmit whole context”.

pass_param_subjob (8)

Agora acrescente outro tJava e na guia Basic cole a seguinte linha:

//Imprime o retorno do job filho
 System.out.println("retVal=" + ((Map<String, String>)context.SUBJOB_CONTEXT).get("retVal"));

pass_param_subjob (7)

Ligue os três componentes através da trigger OnSubJobOk.

pass_param_subjob (4)

Execute:

pass_param_subjob (5)

Agora você já viu como é possível retornar valores de jobs filhos utilizando poucas linhas de código. Embora esse seja um exemplo muito simples, é apenas uma porta para várias possibilidades.

Até a próxima!

Fonte: http://bekwam.blogspot.com.br/2011/05/passing-parameters-and-variables-to.html

Anúncios

Arquivos mdb (MS Access) sem ODBC

Trabalhar com arquivos MDB do Microsoft Access no Windows pode ser um tanto fácil via ODBC, mas o mesmo não é verdade em outros sistemas operacionais. Garantir a portabilidade do projeto ao se trabalhar com esse tipo de tecnologia é um desafio que vamos explorar nesse artigo.

A maioria do conteúdo que se encontra pela web tenta trabalhar com arquivos .mdb criando uma ponte JDBC-ODBC e embora você possa encontrar bons drivers ODBC, o único gratuito que encontrei para Linux foi o libmdbodbc (via repositório apt: apt-get install libmdbodbc mdbtools), porém o mesmo não suporta result set, impedindo o seu uso com o Talend/Java. Apesar disso, em conjunto com o pacote mdbtools essa é uma boa ferramenta para explorar arquivos mdb, permitindo executar queries, listar tabelas… tudo fora do Talend, claro.

Há também a possibilidade de obter drivers puramente JDBC, como o desenvolvido pela HXTT, porém esta não é uma solução gratuita. Você pode fazer o download de um trial por 30 dias, mas o result set das queries tem um limite de 1000 registros.

Assim sendo, utilizaremos um método não JDBC, tampouco ODBC, através da biblioteca Jackcess. Esta biblioteca contém uma série de funcionalidades que nos permite trabalhar com este tipo de tecnologia. Demonstrarei agora como utilizar algumas destas funcionalidades e ler o conteúdo de tabelas em arquivos access.

Primeiramente você deve ir até o site do projeto Jackcsess e realizar o download da biblioteca. Feito isso vamos carregar esta biblioteca em nosso job. Para isso utilizamos o componente tLibraryLoad, conforme na imagem abaixo:

Demonstração do componente tLibraryLoad

Observe que para carregar uma biblioteca que não está na listagem do componente, basca clicar no botão à direita da combo box e apontar para o arquivo com extensão .jar desejado. Além disso, observe também que temos três componentes tLibraryLoad neste job, isto se deve ao fato da biblioteca Jackcess possuir duas dependências: as bibliotecas commons-logging.jar e commons-lang-2.6.jar, ambas já existentes na listagem de bibliotecas do Talend.

Agora que já carregamos as bibliotecas necessárias, partiremos para a leitura dos dados do arquivo. Suponha que desejamos carregar estes dados em um Mysql. Utilizaremos então dois componentes: tJavaFlex e tMysqlOutput.

O componente tJavaFlex possui uma funcionalidade mesclada dos componentes tJava e tJavaRow. Através dele você pode trabalhar o código em três partes diferentes: Begin, Main e End. Mas antes que possamos compreender isto vamos definir o schema da tabela que pretendemos ler. Se você está em um ambiente Windows pode simplesmente abrir o Microsoft Access para obter os metadados da tabela, mas caso esteja em um ambiente Linux e tenha instalada a ferramenta mdbtools, pode executar o comando:

mdb-schema arquivo.mdb

Este comando irá listar os metadados de todas as tabelas existentes neste arquivo, e então você poderá utilizar o resultado deste comando para definir o schema do componente tJavaFlex.

Feito isso, vamos ao código que irá ler uma das tabelas e mapear o conteúdo obtido com as colunas definidas em nosso schema. Primeiramente, vamos importar as classes utilizadas, nós já carregamos as bibliotecas com os componentes tLibraryLoad, mas temos que dizer ao Java quais classes especificamente pretendemos utilizar destas bibliotecas. Para isso vá até o componente tJavaFlex e na aba Advanced:

Classes a serem importadas

Tendo importado as classes acima, vá até a aba Basic do componente tJavaFlex:

Esta aba será dividida basicamente em três partes: Start code, Main code e End code. Todo o código escrito dentro de Start code é executado uma única vez em um fluxo de dados: no início. Já o código escrito em Main code será executado linha a linha, permitindo que realizemos transformações ou meramente propaguemos dados obtidos. E por fim o código escrito em End code será executado uma única vez ao finalizar o fluxo de dados.

Esta abordagem nos permite definir no Start code o cabeçalho de um loop enquanto no Main code teremos basicamente o “corpo” do loop, onde estamos propagando o conteúdo das colunas obtidas para o fluxo “row3” que é aquele “levando” dados para o componente tMysqlOutput. Observe como no campo End code meramente fechamos o corpo do loop for com uma chave.

Além disso, no campo Start code criamos um objeto do tipo Table que recebe o resultado do método getTable, que por sua vez foi executado em um objeto do tipo Database obtido através do método Database.open(). Este objeto do tipo Table é o que nos permite executar um loop e obter os campos desejados de cada registro da tabela especificada, conforme você pode notar na declaração do loop for e no campo Main code.

Esta foi uma breve solução, você pode obter muito mais com a biblioteca Jackcess, existe uma boa documentação da API aqui.

Até a próxima.